commit 05d32fdf7db5cc1996251545a46dc1e71aad71c4
parent 35d043c59c5467b5117cf5df8ae5964b3186a525
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Tue, 29 Apr 2025 04:58:57 +0000
Add lib context to root layout. Add `/farms/products/add`, edit farms routes. Refactor callback utils. Add/edit styles, utils.
Diffstat:
14 files changed, 202 insertions(+), 136 deletions(-)
diff --git a/app/.env.example b/app/.env.example
@@ -1,5 +1,6 @@
PUBLIC_NOSTR_RELAY_DEFAULTS=
PUBLIC_RADROOTS_RELAY_URL=
+PUBLIC_RADROOTS_UPLOAD_IMAGES_URL=
PUBLIC_RADROOTS_URL=
VITE_PUBLIC_IDB_NAME=
VITE_PUBLIC_NDK_CACHE_NAME=
diff --git a/app/src/lib/locale/i18n.ts b/app/src/lib/locale/i18n.ts
@@ -10,7 +10,7 @@ const i18n = i18n_conf<Locale>({
default_locale: `en`,
translations,
loaders: [
- ...locale_keys.map((locale) => [`common`, `countries`, `error`, `eula`, `icu`, `notification`, `units`].map(key => ({
+ ...locale_keys.map((locale) => [`common`, `countries`, `error`, `eula`, `icu`, `notification`, `products`, `units`].map(key => ({
locale,
key,
loader: async () => (await import(`../../../../packages/locales/src/messages/${locale}/${key}.json`)).default
diff --git a/app/src/lib/util/callback.ts b/app/src/lib/util/callback.ts
@@ -1,55 +1,65 @@
-import { ls } from "$lib/locale/i18n";
-import { get_store, handle_err } from "@radroots/lib-app";
-import type { GeocoderReverseResult, GeolocationPoint, IClientGeolocationPosition } from "@radroots/util";
-import { geoc, geol, gui } from ".";
-
-export const lc_gui_alert = async (message: string): Promise<boolean> => {
- try {
- return await gui.alert(message);
- } catch (e) {
- await handle_err(e, `lc_gui_alert`);
- return false;
- }
+import { app_thc, type LocalCallbackColorMode, type LocalCallbackGeocode, type LocalCallbackGeocodeCurrent, type LocalCallbackGuiAlert, type LocalCallbackGuiConfirm, type LocalCallbackImgBin, type LocalCallbackPhotosAddMultiple, type LocalCallbackPhotosUpload } from "@radroots/lib-app";
+import { parse_color_mode } from "@radroots/theme";
+import { throw_err } from "@radroots/util";
+import { fs, geoc, geol, gui, http } from ".";
+
+export const lc_gui_alert: LocalCallbackGuiAlert = async (message) => {
+ return await gui.alert(message);
};
-export const lc_gui_confirm = async (opts: string | { message: string; ok?: string; cancel?: string }): Promise<boolean> => {
- try {
- return await gui.confirm({
- message: typeof opts === `string` ? opts : opts.message,
- ok: typeof opts === `string` ? undefined : opts.ok,
- cancel: typeof opts === `string` ? undefined : opts.cancel,
- });
- } catch (e) {
- await handle_err(e, `lc_gui_alert`);
- return false;
- }
+export const lc_gui_confirm: LocalCallbackGuiConfirm = async (opts) => {
+ return await gui.confirm({
+ message: typeof opts === `string` ? opts : opts.message,
+ ok: typeof opts === `string` ? undefined : opts.ok,
+ cancel: typeof opts === `string` ? undefined : opts.cancel,
+ });
};
-export const lc_geocode = async (geoc_p: GeolocationPoint): Promise<GeocoderReverseResult | undefined> => {
- try {
- await geoc.connect();
- const geoc_res = await geoc.reverse(geoc_p);
- if (
- `results` in geoc_res &&
- geoc_res.results.length > 0
- )
- return geoc_res.results[0];
- } catch (e) {
- await handle_err(e, `lc_geocode`);
- }
+export const lc_geocode: LocalCallbackGeocode = async (geoc_p) => {
+ await geoc.connect();
+ const geoc_res = await geoc.reverse(geoc_p);
+ if (`err` in geoc_res) throw_err(geoc_res);
+ return geoc_res.results[0] || undefined;
};
-export const lc_geop_current = async (show_alert: boolean | string = false): Promise<IClientGeolocationPosition | undefined> => {
- const $ls = get_store(ls);
+export const lc_geop_current: LocalCallbackGeocodeCurrent = async () => {
const geop = await geol.current();
- if (`err` in geop) {
- if (show_alert) {
- await gui.alert(
- typeof show_alert === `string` ? show_alert :
- `${$ls(`icu.failure_*`, { value: `${$ls(`icu.reading_*`, { value: `${$ls(`common.geocode`)}`.toLowerCase() })}` })}`,
- )
+ if (`err` in geop) throw_err(geop);
+ return geop;
+};
+
+export const lc_photos_add: LocalCallbackPhotosAddMultiple = async () => {
+ const photo_paths_open = await gui.open_photos();
+ if (!photo_paths_open) return;
+ if (photo_paths_open.results) return photo_paths_open.results;
+};
+
+export const lc_img_bin: LocalCallbackImgBin = async (file_path) => {
+ const data = await fs.read_bin(file_path);
+ return data;
+};
+
+export const lc_color_mode: LocalCallbackColorMode = async ({ value }) => {
+ if (value) app_thc.set(parse_color_mode(value));
+};
+
+export const lc_photos_upload: LocalCallbackPhotosUpload = async ({ url, path }) => {
+ const data_bin = await lc_img_bin(path);
+ if (!data_bin) return;
+ const res = await http.fetch({
+ url,
+ method: `put`,
+ headers: {
+ "Content-Type": `image/jpeg`,
+ },
+ data_bin,
+ });
+ if (`err` in res) throw_err(res);
+ else if (res.data && res.data.res_base && res.data.res_path && res.data.file_ext) {
+ return {
+ base_url: res.data.res_base,
+ file_hash: res.data.res_path,
+ file_ext: res.data.file_ext
}
- return undefined
}
- return geop;
};
\ No newline at end of file
diff --git a/app/src/lib/util/routes.ts b/app/src/lib/util/routes.ts
@@ -3,6 +3,7 @@ export type NavigationRoute =
| "/farms"
| "/farms/add"
| "/farms/details"
+ | "/farms/products/add"
| "/profile"
| "/profile/edit"
| "/init";
@@ -13,6 +14,7 @@ export function parse_route(route: string): NavigationRoute {
case "/farms":
case "/farms/add":
case "/farms/details":
+ case "/farms/products/add":
case "/profile":
case "/profile/edit":
case "/init":
diff --git a/app/src/routes/(app)/+page.svelte b/app/src/routes/(app)/+page.svelte
@@ -1,5 +1,4 @@
<script lang="ts">
- import { ls } from "$lib/locale/i18n";
import { route } from "$lib/util";
import { handle_err, Home, type IViewHomeData } from "@radroots/lib-app";
@@ -7,20 +6,19 @@
</script>
<Home
- {ls}
basis={{
data,
- lc_handle_farms: async () => {
+ on_handle_farms: async () => {
try {
await route(`/farms`);
} catch (e) {
- await handle_err(e, `lc_handle_farms`);
+ await handle_err(e, `on_handle_farms`);
}
},
- lc_handle_products: async () => {
+ on_handle_products: async () => {
try {
} catch (e) {
- await handle_err(e, `lc_handle_products`);
+ await handle_err(e, `on_handle_products`);
}
},
}}
diff --git a/app/src/routes/(app)/farms/+page.svelte b/app/src/routes/(app)/farms/+page.svelte
@@ -1,14 +1,10 @@
<script lang="ts">
- import { locale, ls } from "$lib/locale/i18n";
import { db, route } from "$lib/util";
- import { lc_geocode } from "$lib/util/callback";
+ import { Farms, handle_err, type IViewFarmsData } from "@radroots/lib-app";
import {
- Farms,
- handle_err,
- type FarmBasis,
- type IViewFarmsData,
- } from "@radroots/lib-app";
- import { location_gcs_to_location_basis } from "@radroots/util";
+ location_gcs_to_location_basis,
+ type FarmExtended,
+ } from "@radroots/util";
import { onMount } from "svelte";
type LoadData = IViewFarmsData | undefined;
@@ -44,7 +40,7 @@
tb_loc_gcs.results[0],
)
: undefined,
- } satisfies FarmBasis;
+ } satisfies FarmExtended;
}),
)) || []
: [],
@@ -56,24 +52,21 @@
</script>
<Farms
- {ls}
- {locale}
basis={{
data,
callback_route: { route: `/` },
- lc_geocode,
- lc_handle_farm_add: async () => {
+ on_handle_farm_add: async () => {
try {
await route(`/farms/add`);
} catch (e) {
- await handle_err(e, `lc_handle_farm_add`);
+ await handle_err(e, `on_handle_farm_add`);
}
},
- lc_handle_farm_view: async (farm_id) => {
+ on_handle_farm_view: async (farm_id) => {
try {
await route(`/farms/details`, [[`id`, farm_id]]);
} catch (e) {
- await handle_err(e, `lc_handle_farm_view`);
+ await handle_err(e, `on_handle_farm_view`);
}
},
}}
diff --git a/app/src/routes/(app)/farms/add/+page.svelte b/app/src/routes/(app)/farms/add/+page.svelte
@@ -1,25 +1,14 @@
<script>
- import { locale, ls } from "$lib/locale/i18n";
import { db, route } from "$lib/util";
- import {
- lc_geocode,
- lc_geop_current,
- lc_gui_alert,
- } from "$lib/util/callback";
import { model_location_gcs_create } from "$lib/util/model/location-gcs";
import { FarmsAdd, handle_err } from "@radroots/lib-app";
import { throw_err } from "@radroots/util";
</script>
<FarmsAdd
- {ls}
- {locale}
basis={{
callback_route: { route: `/farms` },
- lc_gui_alert,
- lc_geocode,
- lc_geop_current,
- lc_submit: async ({ data_s }) => {
+ on_submit: async ({ data_s }) => {
try {
console.log(JSON.stringify(data_s, null, 4), `data_s`);
@@ -53,7 +42,7 @@
if (`err` in farm_location_set) throw_err(farm_location_set);
await route(`/farms`);
} catch (e) {
- await handle_err(e, `lc_submit`);
+ await handle_err(e, `on_submit`);
}
},
}}
diff --git a/app/src/routes/(app)/farms/details/+page.svelte b/app/src/routes/(app)/farms/details/+page.svelte
@@ -1,7 +1,5 @@
<script lang="ts">
- import { locale, ls } from "$lib/locale/i18n";
import { db, route } from "$lib/util";
- import { lc_geocode } from "$lib/util/callback";
import {
FarmsDetails,
handle_err,
@@ -44,34 +42,28 @@
{#if data}
<FarmsDetails
- {ls}
- {locale}
basis={{
data,
callback_route: { route: `/farms` },
- lc_geocode,
- lc_handle_farm_lot_add: async (farm_id) => {
+ on_handle_farm_lot_add: async (farm_id) => {
try {
- // await route(`/farms/lots/add`, { farm_id });
+ // await route(`/farms/lots/add`, [[`id`, farm_id]]);
} catch (e) {
- await handle_err(e, `lc_handle_farm_lot_add`);
+ await handle_err(e, `on_handle_farm_lot_add`);
}
},
- lc_handle_farm_products_view: async (farm_id) => {
+ on_handle_farm_products_view: async (farm_id) => {
try {
- /*
- if (data?.farm_lots?.every((i) => !i.farm_lot_products?.length))
- await route(`/farms/products/add`, { farm_id });
- else
- */
+ // @todo
+ await route(`/farms/products/add`, [[`id`, farm_id]]);
} catch (e) {
- await handle_err(e, `lc_handle_farm_products_view`);
+ await handle_err(e, `on_handle_farm_products_view`);
}
},
- lc_handle_farm_orders_view: async (farm_id) => {
+ on_handle_farm_orders_view: async (farm_id) => {
try {
} catch (e) {
- await handle_err(e, `lc_handle_farm_orders_view`);
+ await handle_err(e, `on_handle_farm_orders_view`);
}
},
}}
diff --git a/app/src/routes/(app)/farms/products/add/+page.svelte b/app/src/routes/(app)/farms/products/add/+page.svelte
@@ -0,0 +1,77 @@
+<script lang="ts">
+ import { db, route } from "$lib/util";
+ import {
+ FarmsProductsAdd,
+ handle_err,
+ qp_id,
+ type IViewFarmsProductsAddData,
+ } from "@radroots/lib-app";
+ import { location_gcs_to_location_basis } from "@radroots/util";
+ import { onMount } from "svelte";
+
+ type LoadData = IViewFarmsProductsAddData | undefined;
+ let data: LoadData = $state(undefined);
+
+ onMount(async () => {
+ data = await load_data();
+ });
+
+ const load_data = async (): Promise<LoadData> => {
+ try {
+ const tb_farm = await db.farm_read({ id: $qp_id || `` });
+ if (`err` in tb_farm) return void route(`/farms`);
+ console.log(JSON.stringify(tb_farm, null, 4), `tb_farm`);
+ const tb_farm_location = await db.location_gcs_read_list({
+ table: [`on_farm`, { id: tb_farm.result.id }],
+ });
+ return {
+ farm: {
+ ...tb_farm.result,
+ },
+ location:
+ `results` in tb_farm_location && tb_farm_location.results[0]
+ ? location_gcs_to_location_basis(
+ tb_farm_location.results[0],
+ )
+ : undefined,
+ } satisfies LoadData;
+ } catch (e) {
+ await handle_err(e, `load_data`);
+ }
+ };
+</script>
+
+{#if data}
+ <FarmsProductsAdd
+ basis={{
+ data,
+ on_handle_farm_lot_add: async () => {
+ try {
+ } catch (e) {
+ await handle_err(e, `on_handle_farm_lot_add`);
+ }
+ },
+ on_handle_photo_envelope_edit: async () => {
+ try {
+ } catch (e) {
+ await handle_err(e, `on_handle_photo_envelope_edit`);
+ }
+ },
+ on_handle_tradepr_key_toggle: async () => {
+ try {
+ return ``;
+ } catch (e) {
+ await handle_err(e, `on_handle_tradepr_key_toggle`);
+ return ``;
+ }
+ },
+ on_submit: async ({ payload, farm_id, geolocation_id }) => {
+ try {
+ console.log(JSON.stringify(payload, null, 4), `payload`);
+ } catch (e) {
+ await handle_err(e, `on_submit`);
+ }
+ },
+ }}
+ />
+{/if}
diff --git a/app/src/routes/(app)/profile/+page.svelte b/app/src/routes/(app)/profile/+page.svelte
@@ -29,7 +29,7 @@
data = { ...tb_nostr_profile.result };
await nostr_sync.metadata({
metadata: tb_nostr_profile.result,
- }); // leave off await
+ }); // no await
return;
}
return void (await route(`/`));
@@ -41,12 +41,11 @@
<Profile
bind:photo_path
- {ls}
basis={{
data,
loading_photo_upload,
loading_photo_upload_open,
- lc_on_destroy: async () => {
+ on_destroy: async () => {
try {
const tb_nostrprofile = await db.nostr_profile_read({
public_key: $ndk_user?.pubkey,
@@ -54,12 +53,12 @@
if (`err` in tb_nostrprofile) throw_err(tb_nostrprofile); //@todo
await nostr_sync.metadata({
metadata: tb_nostrprofile.result,
- }); // leave off await
+ }); // no await
} catch (e) {
- await handle_err(e, `lc_on_destroy`);
+ await handle_err(e, `on_destroy`);
}
},
- lc_handle_back: async ({ is_photo_existing }) => {
+ on_handle_back: async ({ is_photo_existing }) => {
try {
const public_key = $ndk_user?.pubkey;
if (!photo_path || !public_key) return void (await route(`/`));
@@ -118,12 +117,12 @@
throw_err(tb_nostr_profile_update);
await route(`/`);
} catch (e) {
- await handle_err(e, `lc_handle_back`);
+ await handle_err(e, `on_handle_back`);
} finally {
loading_photo_upload = false;
}
},
- lc_handle_edit_profile_field: async ({ field }) => {
+ on_handle_edit_profile_field: async ({ field }) => {
try {
if (field === `name`) {
const confirm = await gui.confirm({
@@ -138,33 +137,13 @@
[`field`, field],
]);
} catch (e) {
- await handle_err(e, `lc_handle_edit_profile_field`);
+ await handle_err(e, `on_handle_edit_profile_field`);
}
},
- lc_handle_photo_add: async () => {
+ on_handle_photo_options: async () => {
try {
- loading_photo_upload_open = true;
- const photo_paths_open = await gui.open_photos();
- if (!photo_paths_open) return;
- const photo_path_add = photo_paths_open.results[0];
- if (photo_path_add) return photo_path_add;
} catch (e) {
- await handle_err(e, `lc_handle_photo_add`);
- } finally {
- loading_photo_upload_open = false;
- }
- },
- lc_handle_photo_options: async () => {
- try {
- } catch (e) {
- await handle_err(e, `lc_handle_photo_options`);
- }
- },
- lc_fs_read_bin: async (file_path) => {
- try {
- return await fs.read_bin(file_path);
- } catch (e) {
- await handle_err(e, `lc_fs_read_bin`);
+ await handle_err(e, `on_handle_photo_options`);
}
},
}}
diff --git a/app/src/routes/(app)/profile/edit/+page.svelte b/app/src/routes/(app)/profile/edit/+page.svelte
@@ -55,10 +55,9 @@
<ProfileEdit
bind:val_field
- {ls}
basis={{
data,
- lc_handle_back: async ({ field, public_key }) => {
+ on_handle_back: async ({ field, public_key }) => {
try {
if (val_field_init === val_field)
return void (await route(`/profile`));
@@ -86,16 +85,16 @@
if (`err` in tb_nostr_profile) throw_err(tb_nostr_profile);
nostr_sync.metadata({
metadata: tb_nostr_profile.result,
- }); // leave off await
+ }); // no await
await route(`/profile`);
} catch (e) {
- await handle_err(e, `lc_handle_back`);
+ await handle_err(e, `on_handle_back`);
}
},
- lc_handle_input: async () => {
+ on_handle_input: async () => {
try {
} catch (e) {
- await handle_err(e, `lc_handle_input`);
+ await handle_err(e, `on_handle_input`);
}
},
}}
diff --git a/app/src/routes/+layout.svelte b/app/src/routes/+layout.svelte
@@ -1,9 +1,21 @@
<script lang="ts">
+ import { locale, ls } from "$lib/locale/i18n";
+ import {
+ lc_color_mode,
+ lc_geocode,
+ lc_geop_current,
+ lc_gui_alert,
+ lc_gui_confirm,
+ lc_img_bin,
+ lc_photos_add,
+ lc_photos_upload,
+ } from "$lib/util/callback";
import {
app_lo,
app_th,
app_thc,
LayoutWindow,
+ set_context,
theme_set,
win_h,
} from "@radroots/lib-app";
@@ -15,6 +27,19 @@
let { children }: LayoutProps = $props();
+ set_context(`lib`, {
+ ls,
+ locale,
+ lc_color_mode,
+ lc_gui_alert,
+ lc_gui_confirm,
+ lc_geocode,
+ lc_geop_current,
+ lc_img_bin,
+ lc_photos_add,
+ lc_photos_upload,
+ });
+
app_thc.subscribe((_app_thc) =>
theme_set(parse_theme_key($app_th), parse_color_mode(_app_thc)),
);
diff --git a/app/tailwind.config.ts b/app/tailwind.config.ts
@@ -32,11 +32,12 @@ const widths_responsive: Record<AppWidthsResponsiveIOS, string> = {
lo_ios1: `345px`,
lo_textdesc_ios0: `312px`,
lo_textdesc_ios1: `312px`,
+ lo_line_entry_ios0: `349px`,
+ lo_line_entry_ios1: `378px`,
};
const widths: Record<string, string> = {
...widths_responsive,
- trellis_line: `349px`,
trellis_value: `180px`,
trellis_display: `286px`,
};
diff --git a/crates/tangle/icons/icon.icns b/crates/tangle/icons/icon.icns
Binary files differ.