web


git clone https://radroots.dev/git/web.git
Log | Files | Refs | Submodules | README | LICENSE

commit 9e31e4c0132c65b35eb084d115f4461e6b5ad972
parent 66290f81bbc507ad916d9c3549a608db74537a52
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Sat, 21 Sep 2024 12:37:32 +0000

 Edit (conf) `/init` route. Edit scope layout functions. Edit conf, styles, utils. Add root layout alert dialog command.

Diffstat:
Msrc/lib/conf.ts | 4++++
Msrc/lib/utils/index.ts | 11++++++++++-
Msrc/routes/(app)/+layout.svelte | 3---
Asrc/routes/(app)/+layout.ts | 21+++++++++++++++++++++
Msrc/routes/(app)/settings/+page.svelte | 2+-
Asrc/routes/(conf)/+layout.svelte | 4++++
Dsrc/routes/(conf)/conf/nostr/+page.svelte | 33---------------------------------
Asrc/routes/(conf)/init/+page.svelte | 431+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/routes/+layout.svelte | 2+-
Mtailwind.config.ts | 3++-
10 files changed, 474 insertions(+), 40 deletions(-)

diff --git a/src/lib/conf.ts b/src/lib/conf.ts @@ -4,6 +4,7 @@ import { type NumberTuple } from "@radroots/utils"; type Conf = { app: Record<string, string>; pref: Record<string, string>; + cmd: Record<string, string>; map: { styles: { base: Record<ColorMode, string>; @@ -25,6 +26,9 @@ export const _cf: Conf = { pref: { key_active: `nostr:key:active` }, + cmd: { + root_alert: `*-alert` + }, map: { styles: { base: { diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts @@ -1,13 +1,22 @@ import { goto } from "$app/navigation"; +import { _cf } from "$lib/conf"; +import { kv } from "@radroots/svelte-lib"; import { lc } from "../client"; -export const restart = async (route_to?: true | string): Promise<void> => { +export const restart = async (route_to: true | string, alert_message?: string): Promise<void> => { try { await lc.window.splash_show(); + if (alert_message) { + await kv.set( + _cf.cmd.root_alert, + alert_message + ); + } if (route_to) { if (route_to === true) await goto(`/`); else await goto(route_to) } + location.reload(); } catch (e) { console.log(`(error) restart `, e); diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte @@ -3,7 +3,6 @@ import { LayoutWindow, Tabs, - app_layout, app_tab_active, app_tabs_visible, } from "@radroots/svelte-lib"; @@ -15,8 +14,6 @@ {#if $app_tabs_visible} <Tabs basis={{ - tab_active: $app_tab_active, - app_layout: $app_layout, list: [ { icon: `house-line`, diff --git a/src/routes/(app)/+layout.ts b/src/routes/(app)/+layout.ts @@ -0,0 +1,21 @@ +import { lc } from '$lib/client'; +import { _cf } from '$lib/conf'; +import { kv } from '@radroots/svelte-lib'; +import type { LayoutLoad, LayoutLoadEvent } from '../$types'; + +export const load: LayoutLoad = async ({ url }: LayoutLoadEvent) => { + try { + console.log(`layout (app) `, url.pathname); + if (url.pathname === `/`) { + const root_alert = await kv.get(_cf.cmd.root_alert); + if (root_alert) { + await kv.delete(_cf.cmd.root_alert); + lc.dialog.alert(root_alert); + } + } + } catch (e) { + console.log(`layout (app) error: `, e); + } finally { + return {} + } +}; diff --git a/src/routes/(app)/settings/+page.svelte b/src/routes/(app)/settings/+page.svelte @@ -158,7 +158,7 @@ await lc.preferences.remove( _cf.pref.key_active, ); - await restart(); + await restart(true); } else { await lc.dialog.alert( `There is no public key preference saved.`, diff --git a/src/routes/(conf)/+layout.svelte b/src/routes/(conf)/+layout.svelte @@ -0,0 +1,4 @@ +<script lang="ts"> +</script> + +<slot /> diff --git a/src/routes/(conf)/conf/nostr/+page.svelte b/src/routes/(conf)/conf/nostr/+page.svelte @@ -1,33 +0,0 @@ -<script lang="ts"> - import { lc } from "$lib/client"; - import { _cf } from "$lib/conf"; - import { restart } from "$lib/utils"; - import { sleep } from "@radroots/svelte-lib"; -</script> - -<div class={`flex flex-col w-full pt-16 justify-center items-center`}> - <button - class={`flex flex-row justify-center items-center text-white`} - on:click={async () => { - const sk_hex = lc.nostr.lib.generate_key(); - const pk_hex = lc.nostr.lib.public_key(sk_hex); - const new_key_added = await lc.keystore.set( - `nostr:key:${pk_hex}`, - sk_hex, - ); - if (new_key_added) { - await lc.preferences.set(_cf.pref.key_active, pk_hex); - await sleep(500); - await restart(true); - } - }} - > - <div - class={`flex flex-col h-line w-line justify-center items-center bg-layer-1-surface`} - > - <p class={`font-mono text-sm lowercase text-layer-2-glyph`}> - {`create nostr keys`} - </p> - </div> - </button> -</div> diff --git a/src/routes/(conf)/init/+page.svelte b/src/routes/(conf)/init/+page.svelte @@ -0,0 +1,431 @@ +<script lang="ts"> + import { lc } from "$lib/client"; + import { _cf } from "$lib/conf"; + import { restart } from "$lib/utils"; + import { Glyph, LayoutView, sleep } from "@radroots/svelte-lib"; + + const SLIDE_DURATION = 600; + + const slides_param: Record<View, { max: number }> = { + start: { + max: 4, + }, + configure: { + max: 1, + }, + }; + + type View = `start` | `configure`; + let view: View = `start`; + + $: { + for (const el of document.querySelectorAll(`[data-view]`)) + el.classList.toggle( + `hidden`, + el.getAttribute(`data-view`) !== view, + ); + } + + let slide_active = false; + let slide_index = 0; + + const get_slide_container = (view: View): Element | undefined => { + const el = document.querySelector(`[data-slide-container="${view}"]`); + return el ? el : undefined; + }; + + const get_slide_item = (view: View): Element | undefined => { + const el = document.querySelector(`[data-carousel-li="${view}"]`); + return el ? el : undefined; + }; + + const slide_prev = async (): Promise<void> => { + if (slide_active) return; + slide_active = true; + const slide_item = get_slide_item(view); + const slide_container = get_slide_container(view); + if (slide_container && slide_item) { + const slide_w = slide_item?.clientWidth || 0; + slide_container.scrollLeft -= slide_w; + slide_index = Math.max(slide_index - 1, 0); + } + await sleep(SLIDE_DURATION); + slide_active = false; + }; + + const slide_next = async (): Promise<void> => { + if (slide_active) return; + slide_active = true; + const slide_item = get_slide_item(view); + const slide_container = get_slide_container(view); + if (slide_container && slide_item) { + const slide_w = slide_item?.clientWidth || 0; + slide_container.scrollLeft += slide_w; + slide_index = Math.min(slide_index + 1, slides_param[view].max); + } + await sleep(SLIDE_DURATION); + slide_active = false; + }; + + const create_new_key = async (): Promise<void> => { + try { + const sk_hex = lc.nostr.lib.generate_key(); + const pk_hex = lc.nostr.lib.public_key(sk_hex); + const new_key_added = await lc.keystore.set( + `nostr:key:${pk_hex}`, + sk_hex, + ); + if (new_key_added) { + await lc.preferences.set(_cf.pref.key_active, pk_hex); + await sleep(500); + await restart( + true, + `Welcome! To view your device configuration go to Settings > Keypairs.`, + ); + } + } catch (e) { + console.log(`(error) create_new_key `, e); + } + }; +</script> + +<LayoutView> + <div + data-view={`start`} + class={`flex flex-col h-full w-full py-12 px-6 justify-start items-center`} + > + <div + class={`relative flex flex-col h-full w-full justify-start items-center`} + > + <ul + data-slide-container={`start`} + class={`carousel-container flex flex-grow h-full w-full bg-layer-1-surface rounded-2xl scrollbar-hide`} + > + <li + data-carousel-li={`start`} + class={`carousel-li flex flex-col flex-fill w-full gap-12 justify-center items-center`} + > + <div + class={`flex flex-col w-54 gap-4 justify-start items-center`} + > + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`we`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`hope you`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`find it`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`useful :)`} + </p> + </div> + <button + class={`group flex flex-row gap-4 justify-center items-center active:opacity-80`} + on:click={async () => { + view = `configure`; + }} + > + <p + class={`font-mono font-[500] text-layer-1-glyph-hl text-3xl`} + > + {`*`} + </p> + <div class={`flex flex-col justify-start items-center`}> + <p + class={`font-mono font-[500] text-layer-1-glyph-hl text-2xl`} + > + {`configure`} + </p> + <p + class={`font-mono font-[500] text-layer-1-glyph-hl text-2xl`} + > + {`device`} + </p> + </div> + <p + class={`font-mono font-[500] text-layer-1-glyph-hl text-3xl`} + > + {`*`} + </p> + </button> + </li> + <li + data-carousel-li={`start`} + class={`carousel-li flex flex-col flex-fill w-full py-40 justify-between items-center`} + > + <div + class={`flex flex-col w-40 gap-2 justify-start items-center`} + > + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`welcome`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`to`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`radroots`} + </p> + </div> + <div class={`flex flex-col justify-start items-center`}> + <p + class={`font-mono font-[400] text-layer-0-glyph text-2xl`} + > + {`direct trade with`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-2xl`} + > + {`farmers`} + </p> + </div> + </li> + <li + data-carousel-li={`start`} + class={`carousel-li flex flex-col flex-fill w-full justify-center items-center`} + > + <div + class={`flex flex-col w-40 gap-4 justify-start items-center`} + > + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`radroots`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`is an`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`open`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`source`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`app`} + </p> + </div> + </li> + <li + data-carousel-li={`start`} + class={`carousel-li flex flex-col flex-fill w-full justify-center items-center`} + > + <div + class={`flex flex-col w-54 gap-4 justify-start items-center`} + > + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`... it's`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`running on`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`a`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`decentralized`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`network`} + </p> + </div> + </li> + <li + data-carousel-li={`start`} + class={`carousel-li flex flex-col flex-fill w-full justify-center items-center`} + > + <div + class={`flex flex-col w-54 gap-4 justify-start items-center`} + > + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`connecting`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`farmers`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`and buyers`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`around the`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-3xl`} + > + {`world.`} + </p> + </div> + </li> + </ul> + <div + class={`absolute bottom-0 left-0 flex flex-row h-12 w-full justify-center items-center`} + > + <div class={`flex flex-row gap-4 justify-start items-center`}> + <Glyph + basis={{ + key: `caret-left`, + dim: `sm-`, + weight: `bold`, + classes: + slide_index > 0 + ? `h-glyph_btn_sm w-glyph_btn_sm text-layer-2-glyph bg-layer-2-surface rounded-full` + : `h-glyph_btn_sm w-glyph_btn_sm text-layer-2-glyph bg-layer-2-surface rounded-full opacity-60`, + callback: async () => { + if (slide_index > 0) await slide_prev(); + }, + }} + /> + <Glyph + basis={{ + key: `caret-right`, + dim: `sm-`, + weight: `bold`, + classes: + slide_index !== slides_param[view].max + ? `h-glyph_btn_sm w-glyph_btn_sm text-layer-2-glyph bg-layer-2-surface rounded-full` + : `h-glyph_btn_sm w-glyph_btn_sm text-layer-2-glyph bg-layer-2-surface rounded-full opacity-60`, + callback: async () => { + if (slide_index !== slides_param[view].max) + await slide_next(); + }, + }} + /> + </div> + </div> + </div> + </div> + <div + data-view={`configure`} + class={`hidden flex flex-col h-full w-full py-12 px-6 justify-start items-center`} + > + <div + class={`relative flex flex-col h-full w-full justify-start items-center`} + > + <ul + data-slide-container={`configure`} + class={`carousel-container flex flex-grow h-full w-full scrollbar-hide`} + > + <li + data-carousel-li={`configure`} + class={`carousel-li flex flex-col flex-fill w-full gap-12 justify-center items-center`} + > + <div + class={`flex flex-col w-54 gap-4 justify-start items-center`} + > + <p + class={`font-mono font-[700] text-layer-0-glyph text-2xl`} + > + {`to start:`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-2xl`} + > + {`a keypair will be`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-2xl`} + > + {`created`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-2xl`} + > + {`... and saved`} + </p> + <p + class={`font-mono font-[400] text-layer-0-glyph text-2xl`} + > + {`on your device.`} + </p> + </div> + <div + class={`flex flex-col gap-6 justify-start items-center`} + > + <div class={`flex flex-col justify-start items-center`}> + <button + class={`flex flex-row gap-3 justify-center items-center active:opacity-80`} + on:click={async () => { + await create_new_key(); + }} + > + <p + class={`font-mono font-[900] text-layer-0-glyph text-xl`} + > + {`**`} + </p> + <p + class={`font-mono font-[900] text-layer-0-glyph text-xl underline`} + > + {`create keypair`} + </p> + <p + class={`font-mono font-[900] text-layer-0-glyph text-xl`} + > + {`**`} + </p> + </button> + </div> + <button + class={`flex flex-col justify-center items-center active:opacity-80`} + on:click={async () => { + await lc.dialog.alert(`Coming soon!`); + }} + > + <p + class={`font-mono font-[500] text-layer-0-glyph-hl text-xl`} + > + {`i have a keypair`} + </p> + <p + class={`font-mono font-[500] text-layer-0-glyph-hl text-xl`} + > + {`already...`} + </p> + </button> + </div> + </li> + </ul> + </div> + </div> +</LayoutView> diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte @@ -81,7 +81,7 @@ app_nostr_key.set(active_nostr_pk); else { await lc.preferences.remove(_cf.pref.key_active); - await goto(`/conf/nostr`); + await goto(`/init`); } } catch (e) { console.log(`(app_config) error `, e); diff --git a/tailwind.config.ts b/tailwind.config.ts @@ -14,7 +14,7 @@ const heights = { tabs_lg: `86px`, nav_base: `71px`, nav_lg: `100px`, - "envTop": "56px", + envelope_top: "56px", }; const widths = { @@ -22,6 +22,7 @@ const widths = { }; const dimensions = { + glyph_btn_sm: `28px`, map_circle: `16px`, map_circle_inner: `10px`, map_offset_top_base: `32px`,