commit 389a566cf18d426a4bb80c86ac96a95ec966c559
parent 94fe0c8a8d8836c1e2a01f537857b65765e108fc
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Fri, 7 Mar 2025 14:46:52 +0000
apps-lib: add profile edit view. edit profile view. add/edit types, utils
Diffstat:
7 files changed, 144 insertions(+), 24 deletions(-)
diff --git a/apps-lib/src/lib/index.ts b/apps-lib/src/lib/index.ts
@@ -101,6 +101,7 @@ export * from "./util/casl.js"
export * from "./util/idb.js"
export * from "./util/lib.js"
export * from "./util/service/nostr-sync.js"
+export * from "./util/view.js"
export { default as FarmsAdd } from "./view/farms-add.svelte"
export { default as FarmsProductsAdd } from "./view/farms-products-add.svelte"
export { default as FarmsProductsView } from "./view/farms-products-view.svelte"
@@ -108,6 +109,7 @@ export { default as FarmsView } from "./view/farms-view.svelte"
export { default as Farms } from "./view/farms.svelte"
export { default as Home } from "./view/home.svelte"
export { default as Notifications } from "./view/notifications.svelte"
+export { default as ProfileEdit } from "./view/profile-edit.svelte"
export { default as Profile } from "./view/profile.svelte"
export { default as Search } from "./view/search.svelte"
export { default as Settings } from "./view/settings.svelte"
diff --git a/apps-lib/src/lib/types/view.ts b/apps-lib/src/lib/types/view.ts
@@ -9,4 +9,9 @@ export type IViewProfileData = {
}[];
};
-export type ViewProfileEditFieldKey = `name` | `display_name` | `about`;
-\ No newline at end of file
+export type ViewProfileEditFieldKey = `name` | `display_name` | `about`;
+
+export type IViewProfileEditData = {
+ public_key: string;
+ field: ViewProfileEditFieldKey;
+};
+\ No newline at end of file
diff --git a/apps-lib/src/lib/util/service/nostr-sync.ts b/apps-lib/src/lib/util/service/nostr-sync.ts
@@ -31,10 +31,10 @@ export class NostrSyncService implements INostrSyncService {
metadata,
});
if (ev) return ev;
- return err_msg(`*-ev`);
+ return err_msg(`error.nostr.sync.metadata.missing_event`);
} catch (e) {
await handle_err(e, `metadata`);
- return err_msg(`*`);
+ return err_msg(`error.nostr.sync.failure`); //@todo
}
}
}
\ No newline at end of file
diff --git a/apps-lib/src/lib/util/view.ts b/apps-lib/src/lib/util/view.ts
@@ -0,0 +1,12 @@
+import type { ViewProfileEditFieldKey } from "$root";
+
+export const parse_view_profile_field_key = (val?: string): ViewProfileEditFieldKey | undefined => {
+ switch (val) {
+ case `name`:
+ case `display_name`:
+ case `about`:
+ return val;
+ default:
+ return undefined;
+ }
+};
+\ No newline at end of file
diff --git a/apps-lib/src/lib/view/profile-edit.svelte b/apps-lib/src/lib/view/profile-edit.svelte
@@ -0,0 +1,103 @@
+<script lang="ts">
+ import Empty from "$lib/components/lib/empty.svelte";
+ import {
+ FloatPageButton,
+ fmt_id,
+ handle_err,
+ idb_init_page,
+ Input,
+ LayoutPage,
+ LayoutView,
+ NavigationTabs,
+ type IViewProfileEditData,
+ type ViewProfileEditFieldKey,
+ } from "$root";
+ import {
+ type CallbackPromiseGeneric,
+ type ElementCallbackValue,
+ type I18nTranslateFunction,
+ type IViewBasis,
+ type IViewOnMount,
+ } from "@radroots/util";
+ import { onMount } from "svelte";
+
+ let {
+ basis,
+ ls,
+ val_field = $bindable(``),
+ }: {
+ basis: IViewBasis<{
+ data: IViewProfileEditData;
+ lc_handle_back: CallbackPromiseGeneric<{
+ field: ViewProfileEditFieldKey;
+ public_key: string;
+ }>;
+ lc_handle_input: ElementCallbackValue;
+ }> &
+ IViewOnMount<{ field: ViewProfileEditFieldKey }>;
+ ls: I18nTranslateFunction;
+ val_field: string;
+ } = $props();
+
+ const param: Record<ViewProfileEditFieldKey, { placeholder: string }> = {
+ name: {
+ placeholder: `${$ls(`icu.enter_*`, { value: `profile username` })}`, //@todo
+ },
+ display_name: {
+ placeholder: `${$ls(`icu.enter_*`, { value: `profile display name` })}`, //@todo
+ },
+ about: {
+ placeholder: `${$ls(`icu.enter_*`, { value: `profile bio` })}`, //@todo
+ },
+ };
+
+ onMount(async () => {
+ try {
+ if (!basis.kv_init_prevent) await idb_init_page();
+ await basis.lc_on_mount({ field: basis.data.field });
+ } catch (e) {
+ handle_err(e, `on_mount`);
+ }
+ });
+
+ const input_placeholder = $derived(
+ basis.data?.field ? param[basis.data.field]?.placeholder : ``,
+ );
+
+ $effect(() => {
+ console.log(`input_placeholder `, input_placeholder);
+ });
+</script>
+
+<LayoutView>
+ <LayoutPage>
+ <div class={`flex flex-row h-20 w-full justify-start items-center`}>
+ <Empty />
+ </div>
+ {#if basis.data.field}
+ <Input
+ bind:value={val_field}
+ basis={{
+ id: fmt_id(`field`),
+ sync: true,
+ classes: `pl-6 h-entry_line text-layer-1-glyph bg-layer-1-surface rounded-2xl`,
+ placeholder: input_placeholder,
+ callback: basis.lc_handle_input,
+ }}
+ />
+ {/if}
+ </LayoutPage>
+</LayoutView>
+<FloatPageButton
+ basis={{
+ posx: `left`,
+ glyph: `arrow-left`,
+ callback: async () => {
+ await basis.lc_handle_back({
+ field: basis.data.field,
+ public_key: basis.data.public_key,
+ });
+ },
+ }}
+/>
+<NavigationTabs />
diff --git a/apps-lib/src/lib/view/profile.svelte b/apps-lib/src/lib/view/profile.svelte
@@ -18,9 +18,10 @@
type CallbackPromiseGeneric,
type I18nTranslateFunction,
type IViewBasis,
+ type IViewOnDestroy,
type LcPhotoAddCallback,
} from "@radroots/util";
- import { onMount } from "svelte";
+ import { onDestroy, onMount } from "svelte";
let {
basis,
@@ -28,7 +29,7 @@
photo_path_opt = $bindable(``),
}: {
basis: IViewBasis<{
- data?: IViewProfileData;
+ data: IViewProfileData;
loading_photo_upload: boolean;
lc_handle_back: CallbackPromise;
lc_handle_photo_add: LcPhotoAddCallback;
@@ -37,10 +38,8 @@
lc_handle_edit_profile_field: CallbackPromiseGeneric<{
field: ViewProfileEditFieldKey;
}>;
- //lc_handle_edit_profile_name_confirm: CallbackPromiseReturn<boolean>;
- //lc_handle_edit_profile_display_name: CallbackPromise;
- //lc_handle_edit_profile_about: CallbackPromise;
- }>;
+ }> &
+ IViewOnDestroy<{ public_key: string }>;
ls: I18nTranslateFunction;
photo_path_opt: string;
} = $props();
@@ -51,12 +50,19 @@
onMount(async () => {
try {
if (!basis.kv_init_prevent) await idb_init_page();
- if (basis.lc_on_mount) await basis.lc_on_mount();
} catch (e) {
handle_err(e, `on_mount`);
}
});
+ onDestroy(async () => {
+ try {
+ await basis.lc_on_destroy({ public_key: basis.data.public_key });
+ } catch (e) {
+ handle_err(e, `on_destroy`);
+ }
+ });
+
const profile_photo = $derived(basis.data?.photos?.find((i) => i.primary));
const photo_overlay_visible = $derived(!!(profile_photo || photo_path_opt));
@@ -136,9 +142,9 @@
class={`font-sansd font-[600] text-[2rem] ${classes_photo_overlay_glyph} ${basis.data?.name ? `` : `capitalize opacity-active`} el-re`}
>
{#if basis.data?.display_name}
- {`@${basis.data?.display_name}`}
+ {`${basis.data?.display_name}`}
{:else if basis.data?.name}
- {`@${basis.data?.display_name || basis.data?.name || ``}`}
+ {`${basis.data?.display_name || basis.data?.name || ``}`}
{:else}
{`+ ${`${$ls(`icu.add_*`, { value: `${$ls(`common.profile_name`)}` })}`}`}
{/if}
@@ -200,7 +206,7 @@
class={`font-sansd font-[400] text-[1.1rem] ${classes_photo_overlay_glyph} ${basis.data?.about ? `` : `capitalize opacity-active`}`}
>
{#if basis.data?.about}
- {`@${basis.data.about}`}
+ {`${basis.data.about}`}
{:else}
{`+ ${`${$ls(`icu.add_*`, { value: `${$ls(`common.bio`)}` })}`}`}
{/if}
diff --git a/apps-lib/src/lib/view/search.svelte b/apps-lib/src/lib/view/search.svelte
@@ -24,7 +24,7 @@
type ResolveProfileInfo,
type SearchServiceResult,
} from "@radroots/util";
- import { onDestroy, onMount } from "svelte";
+ import { onMount } from "svelte";
let {
basis,
@@ -54,7 +54,6 @@
try {
search_val = ``;
if (!basis.kv_init_prevent) await idb_init_page();
- if (basis.lc_on_mount) await basis.lc_on_mount();
search_service = new SearchService(basis.data);
} catch (e) {
handle_err(e, `on_mount`);
@@ -65,14 +64,6 @@
console.log(`val `, val);
if (search_service) search_results = search_service.search(val);
}, cfg_app.debounce.search);
-
- onDestroy(async () => {
- try {
- if (basis.lc_on_destroy) await basis.lc_on_destroy();
- } catch (e) {
- handle_err(e, `on_destroy`);
- }
- });
</script>
<LayoutView>