app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit e5f5a513a721f9a6c785ea4cb04298d2bc2b8e67
parent 3bf29f8204956cdb211bd7449affd15256f3119d
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Thu, 24 Oct 2024 21:23:10 +0000

Edit `/cfg/init` add default nostr relay configuration to submit handler. Add reset device util.

Diffstat:
Msrc/lib/utils/client.ts | 18++++++++++++++++--
Msrc/routes/(app)/settings/+page.svelte | 606++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msrc/routes/(cfg)/cfg/init/+page.svelte | 56++++++++++++++++++++++++++++++++++++++++----------------
3 files changed, 351 insertions(+), 329 deletions(-)

diff --git a/src/lib/utils/client.ts b/src/lib/utils/client.ts @@ -1,10 +1,11 @@ import { keystore } from "$lib/client"; import { app_notify, route, type NavigationRoute } from "@radroots/svelte-lib"; +import type { ErrorMessage } from "@radroots/utils"; -export const keystore_reset = async (): Promise<void> => { +export const keystore_reset = async (): Promise<ErrorMessage<string> | undefined> => { try { const ks_keys = await keystore.keys(); - if (`err` in ks_keys) return; //@todo + if (`err` in ks_keys) return ks_keys; for (const ks_key of ks_keys.results) await keystore.remove(ks_key); } catch (e) { console.log(`(error) keystore_reset `, e); @@ -23,3 +24,16 @@ export const restart = async (opts?: { console.log(`(error) restart `, e); } }; + +export const reset_device = async (): Promise<ErrorMessage<string> | undefined> => { + try { + const ks_keys = await keystore.keys(); + console.log(JSON.stringify(ks_keys, null, 4), `ks_keys`) + if (`err` in ks_keys) return ks_keys; + for (const ks_key of ks_keys.results) await keystore.remove(ks_key); + // @todo add database reset + await route(`/`); + } catch (e) { + console.log(`(error) reset_device `, e); + } +}; diff --git a/src/routes/(app)/settings/+page.svelte b/src/routes/(app)/settings/+page.svelte @@ -1,9 +1,10 @@ <script lang="ts"> import { dialog, geol, haptics, keystore } from "$lib/client"; import { ks } from "$lib/conf"; + import { reset_device } from "$lib/utils/client"; import { - app_notify, app_thc, + LayoutTrellis, LayoutView, Nav, t, @@ -13,366 +14,349 @@ </script> <LayoutView> - <Trellis - basis={{ - args: { - layer: 1, - title: { - value: `Appearance`, - }, - list: [ - { - hide_active: true, - touch: { - label: { - left: [ - { - value: `Toggle Color Mode (${toggle_color_mode($app_thc)})`, - classes: `capitalize`, - }, - ], - }, - callback: async () => { - await haptics.impact(); - app_thc.set(toggle_color_mode($app_thc)); - }, - }, + <LayoutTrellis> + <Trellis + basis={{ + args: { + layer: 1, + title: { + value: `Appearance`, }, - ], - }, - }} - /> - <Trellis - basis={{ - args: { - layer: 1, - title: { - value: `Nostr Keys`, - }, - list: [ - { - touch: { - label: { - left: [ - { - value: `Nostr Key (public)`, - classes: `capitalize`, - }, - ], - }, - end: { - icon: { - key: `caret-right`, + list: [ + { + hide_active: true, + touch: { + label: { + left: [ + { + value: `Toggle Color Mode (${toggle_color_mode($app_thc)})`, + classes: `capitalize`, + }, + ], + }, + callback: async () => { + await haptics.impact(); + app_thc.set(toggle_color_mode($app_thc)); }, - }, - callback: async () => { - const public_key = await keystore.get( - ks.keys.nostr_publickey, - ); - if (`err` in public_key) return; - await dialog.alert( - `Hi! This is your nostr public key ${public_key.result}`, - ); }, }, + ], + }, + }} + /> + <Trellis + basis={{ + args: { + layer: 1, + title: { + value: `Nostr Keys`, }, - { - touch: { - label: { - left: [ - { - value: `Nostr Key (secret)`, - classes: `capitalize`, + list: [ + { + touch: { + label: { + left: [ + { + value: `Nostr Key (public)`, + classes: `capitalize`, + }, + ], + }, + end: { + icon: { + key: `caret-right`, }, - ], - }, - end: { - icon: { - key: `caret-right`, }, - }, - callback: async () => { - const public_key = await keystore.get( - ks.keys.nostr_publickey, - ); - if (`err` in public_key) return; - const secret_key = await keystore.get( - ks.keys.nostr_secretkey(public_key.result), - ); - if (`err` in secret_key) return; - await dialog.alert( - `Hi! This is your nostr secret key ${secret_key.result}`, - ); + callback: async () => { + const public_key = await keystore.get( + ks.keys.nostr_publickey, + ); + if (`err` in public_key) return; + await dialog.alert( + `Hi! This is your nostr public key ${public_key.result}`, + ); + }, }, }, - }, - ], - }, - }} - /> - <Trellis - basis={{ - args: { - layer: 1, - title: { - value: `Configuration`, - }, - list: [ - { - touch: { - label: { - left: [ - { - value: `Reset Device`, - classes: `capitalize`, + { + touch: { + label: { + left: [ + { + value: `Nostr Key (secret)`, + classes: `capitalize`, + }, + ], + }, + end: { + icon: { + key: `caret-right`, }, - ], - }, - end: { - icon: { - key: `caret-right`, }, - }, - callback: async () => { - const confirm = await dialog.confirm( - `Hi! This will delete your saved keys.`, - ); - if (confirm) { - const ks_nostr_pk = await keystore.get( + callback: async () => { + const public_key = await keystore.get( ks.keys.nostr_publickey, ); - if (`err` in ks_nostr_pk) { - await dialog.alert( - `There was an error.`, - ); - return; - } - await keystore.remove( + if (`err` in public_key) return; + const secret_key = await keystore.get( ks.keys.nostr_secretkey( - ks_nostr_pk.result, + public_key.result, ), ); - await keystore.remove( - ks.keys.nostr_publickey, - ); - app_notify.set( - `Your device has been reset.`, + if (`err` in secret_key) return; + await dialog.alert( + `Hi! This is your nostr secret key ${secret_key.result}`, ); - } + }, }, }, - }, - ], - }, - }} - /> - <Trellis - basis={{ - args: { - layer: 1, - title: { - value: `Location`, + ], }, - list: [ - { - touch: { - label: { - left: [ - { - value: `Geolocation Current`, - classes: `capitalize`, - }, - ], - }, - callback: async () => { - const pos = await geol.current(); - await dialog.alert(JSON.stringify(pos)); - }, - }, + }} + /> + <Trellis + basis={{ + args: { + layer: 1, + title: { + value: `Configuration`, }, - ], - }, - }} - /> - <Trellis - basis={{ - args: { - layer: 1, - title: { - value: `Web`, - }, - list: [ - { - touch: { - label: { - left: [ - { - value: `Radroots.Org (Open Homepage)`, + list: [ + { + touch: { + label: { + left: [ + { + value: `Reset Device`, + classes: `capitalize`, + }, + ], + }, + end: { + icon: { + key: `caret-right`, }, - ], - }, - callback: async () => { - //const url = `https://radroots.org`; - //await browser.open(url); + }, + callback: async () => { + const confirm = await dialog.confirm( + `Hi! This will delete your saved keys.`, + ); + if (confirm === true) await reset_device(); + }, }, }, + ], + }, + }} + /> + <Trellis + basis={{ + args: { + layer: 1, + title: { + value: `Location`, }, - { - touch: { - label: { - left: [ - { - value: `Radroots.Org (Share Homepage)`, - }, - ], - }, - callback: async () => { - //await share.open({ - // title: `Radroots Home Page`, - // text: `Find farmers around the world.`, - // url: `https://radroots.org`, - // dialog_title: `This is the dialog title`, - //}); + list: [ + { + touch: { + label: { + left: [ + { + value: `Geolocation Current`, + classes: `capitalize`, + }, + ], + }, + callback: async () => { + const pos = await geol.current(); + await dialog.alert(JSON.stringify(pos)); + }, }, }, + ], + }, + }} + /> + <Trellis + basis={{ + args: { + layer: 1, + title: { + value: `Web`, }, - { - touch: { - label: { - left: [ - { - value: `Primal.Net (Open Profile)`, - }, - ], - }, - callback: async () => { - //const public_key = await keystore.get( - // ks.keys.nostr_publickey, - //); - //const npub = nostr.lib.npub(public_key); - //const url = `https://primal.net/p/${npub}`; - //await browser.open(url); + list: [ + { + touch: { + label: { + left: [ + { + value: `Radroots.Org (Open Homepage)`, + }, + ], + }, + callback: async () => { + //const url = `https://radroots.org`; + //await browser.open(url); + }, }, }, - }, - ], - }, - }} - /> - <Trellis - basis={{ - args: { - layer: 1, - title: { - value: `Device`, - }, - list: [ - { - touch: { - label: { - left: [ - { - value: `Device (Info)`, - }, - ], + { + touch: { + label: { + left: [ + { + value: `Radroots.Org (Share Homepage)`, + }, + ], + }, + callback: async () => { + //await share.open({ + // title: `Radroots Home Page`, + // text: `Find farmers around the world.`, + // url: `https://radroots.org`, + // dialog_title: `This is the dialog title`, + //}); + }, }, - callback: async () => { - //const data = await device.info(); - //await dialog.alert(JSON.stringify(data)); + }, + { + touch: { + label: { + left: [ + { + value: `Primal.Net (Open Profile)`, + }, + ], + }, + callback: async () => { + //const public_key = await keystore.get( + // ks.keys.nostr_publickey, + //); + //const npub = nostr.lib.npub(public_key); + //const url = `https://primal.net/p/${npub}`; + //await browser.open(url); + }, }, }, + ], + }, + }} + /> + <Trellis + basis={{ + args: { + layer: 1, + title: { + value: `Device`, }, - { - touch: { - label: { - left: [ - { - value: `Device (Battery)`, - }, - ], + list: [ + { + touch: { + label: { + left: [ + { + value: `Device (Info)`, + }, + ], + }, + callback: async () => { + //const data = await device.info(); + //await dialog.alert(JSON.stringify(data)); + }, }, - callback: async () => { - //const data = await device.battery(); - //await dialog.alert(JSON.stringify(data)); + }, + { + touch: { + label: { + left: [ + { + value: `Device (Battery)`, + }, + ], + }, + callback: async () => { + //const data = await device.battery(); + //await dialog.alert(JSON.stringify(data)); + }, }, }, - }, - ], - }, - }} - /> - <Trellis - basis={{ - args: { - layer: 1, - title: { - value: `Tests`, + ], }, - list: [ - { - touch: { - label: { - left: [ - { - value: `Haptics Touch (less)`, - classes: `capitalize`, + }} + /> + <Trellis + basis={{ + args: { + layer: 1, + title: { + value: `Tests`, + }, + list: [ + { + touch: { + label: { + left: [ + { + value: `Haptics Touch (less)`, + classes: `capitalize`, + }, + ], + }, + end: { + icon: { + key: `caret-right`, }, - ], - }, - end: { - icon: { - key: `caret-right`, }, - }, - callback: async () => { - await haptics.impact(`light`); + callback: async () => { + await haptics.impact(`light`); + }, }, }, - }, - { - touch: { - label: { - left: [ - { - value: `Haptics Touch (more)`, - classes: `capitalize`, + { + touch: { + label: { + left: [ + { + value: `Haptics Touch (more)`, + classes: `capitalize`, + }, + ], + }, + end: { + icon: { + key: `caret-right`, }, - ], - }, - end: { - icon: { - key: `caret-right`, }, - }, - callback: async () => { - await haptics.impact(`heavy`); + callback: async () => { + await haptics.impact(`heavy`); + }, }, }, - }, - { - touch: { - label: { - left: [ - { - value: `Haptics Vibrate (500ms)`, - classes: `capitalize`, + { + touch: { + label: { + left: [ + { + value: `Haptics Vibrate (500ms)`, + classes: `capitalize`, + }, + ], + }, + end: { + icon: { + key: `caret-right`, }, - ], - }, - end: { - icon: { - key: `caret-right`, }, - }, - callback: async () => { - await haptics.vibrate(500); + callback: async () => { + await haptics.vibrate(500); + }, }, }, - }, - ], - }, - }} - /> + ], + }, + }} + /> + </LayoutTrellis> </LayoutView> <Nav basis={{ diff --git a/src/routes/(cfg)/cfg/init/+page.svelte b/src/routes/(cfg)/cfg/init/+page.svelte @@ -1,5 +1,8 @@ <script lang="ts"> - import { PUBLIC_RADROOTS_URL } from "$env/static/public"; + import { + PUBLIC_NOSTR_RELAY_DEFAULTS, + PUBLIC_RADROOTS_URL, + } from "$env/static/public"; import { db, dialog, http, keystore, nostr } from "$lib/client"; import { cfg, ks } from "$lib/conf"; import { restart } from "$lib/utils/client"; @@ -617,24 +620,45 @@ ? ks_nostr_profilename.result : undefined, }); - console.log( - JSON.stringify(nostr_profile_add, null, 4), - `nostr_profile_add`, - ); - if (`id` in nostr_profile_add) { - await keystore.set(ks.keys.nostr_publickey, nostr_publickey); - await keystore.set( - ks.keys.nostr_secretkey(nostr_publickey), - ks_nostr_secretkey.result, + + if (`err` in nostr_profile_add || `err_s` in nostr_profile_add) { + await dialog.alert( + `${$t(`icu.failure_saving_*_to_the_database`, { value: `${$t(`common.profile`)}`.toLowerCase() })}`, ); - await reset_ks(); - await restart({ - route: `/`, - notify_message: `${$t(`app.page.cfg.init.notification.welcome`)}`, + return; //@todo + } + await keystore.set(ks.keys.nostr_publickey, nostr_publickey); + await keystore.set( + ks.keys.nostr_secretkey(nostr_publickey), + ks_nostr_secretkey.result, + ); + for (const url of Array.from( + new Set([ + cfg.nostr.relay_url, + ...PUBLIC_NOSTR_RELAY_DEFAULTS.split(","), + ]), + )) { + const nostr_relay_add = await db.nostr_relay_add({ url }); + if (`err` in nostr_relay_add || `err_s` in nostr_relay_add) { + await dialog.alert( + `${$t(`icu.failure_saving_*_to_the_database`, { value: `${$t(`icu.default_*`, { value: `${$t(`common.relays`)}` })}`.toLowerCase() })}`, + ); + return; // @todo + } + await db.set_nostr_profile_relay({ + nostr_profile: { + id: nostr_profile_add.id, + }, + nostr_relay: { + id: nostr_relay_add.id, + }, }); - return; } - await dialog.alert(`There was an error saving to the database.`); //@todo + await reset_ks(); + await restart({ + route: `/`, + notify_message: `${$t(`app.page.cfg.init.notification.welcome`)}`, + }); } catch (e) { console.log(`(error) submit `, e); }