commit 0f95bbcdc92f510e92b994d21efe9b3c75146d34
parent 46e78fb0f169b7415c334efa3a935bdf1cac0f49
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:
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`,