From 2c414c4a5624397256355b3a507690738849a985 Mon Sep 17 00:00:00 2001 From: Kieran Date: Thu, 23 Nov 2023 13:43:23 +0000 Subject: [PATCH] feat: backup key task --- packages/app/src/Tasks/BackupKey.tsx | 49 +++++++++++++++++++++++ packages/app/src/Tasks/TaskList.tsx | 59 ++++++++++++++++++++-------- packages/app/src/Tasks/index.ts | 9 ++++- packages/app/vite.config.ts | 5 +-- 4 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 packages/app/src/Tasks/BackupKey.tsx diff --git a/packages/app/src/Tasks/BackupKey.tsx b/packages/app/src/Tasks/BackupKey.tsx new file mode 100644 index 00000000..38009ffc --- /dev/null +++ b/packages/app/src/Tasks/BackupKey.tsx @@ -0,0 +1,49 @@ +import { FormattedMessage } from "react-intl"; +import { Link } from "react-router-dom"; +import { BaseUITask } from "@/Tasks"; +import { MetadataCache } from "@snort/system"; +import { LoginSession } from "@/Login"; +import Icon from "@/Icons/Icon"; + +export class BackupKeyTask extends BaseUITask { + id = "backup-key"; + noBaseStyle = true; + + check(_: MetadataCache, session: LoginSession): boolean { + return !this.state.muted && session.type == "private_key"; + } + + render() { + return ( +
+
+
+
+ +
+
+
+
+ +
+ + + +
+ + + + +
+
+
+
+ ); + } +} diff --git a/packages/app/src/Tasks/TaskList.tsx b/packages/app/src/Tasks/TaskList.tsx index 0fe477dc..11cb82b4 100644 --- a/packages/app/src/Tasks/TaskList.tsx +++ b/packages/app/src/Tasks/TaskList.tsx @@ -1,5 +1,5 @@ import "./TaskList.css"; -import { useState } from "react"; +import { useSyncExternalStore } from "react"; import { useUserProfile } from "@snort/system-react"; import useLogin from "@/Hooks/useLogin"; @@ -9,37 +9,62 @@ import { DonateTask } from "./DonateTask"; import { Nip5Task } from "./Nip5Task"; import { RenewSubTask } from "./RenewSubscription"; import { NoticeZapPoolDefault } from "./NoticeZapPool"; +import { BackupKeyTask } from "./BackupKey"; +import { ExternalStore } from "@snort/shared"; -const AllTasks: Array = [new Nip5Task(), new DonateTask(), new NoticeZapPoolDefault()]; -if (CONFIG.features.subscriptions) { - AllTasks.push(new RenewSubTask()); +class TaskStore extends ExternalStore> { + #tasks: Array; + + constructor() { + super(); + const AllTasks: Array = [ + new BackupKeyTask(), + new Nip5Task(), + new DonateTask(), + new NoticeZapPoolDefault() + ]; + if (CONFIG.features.subscriptions) { + AllTasks.push(new RenewSubTask()); + } + AllTasks.forEach(a => a.load(() => { + this.notifyChange() + })); + this.#tasks = AllTasks; + } + + takeSnapshot(): UITask[] { + return [...this.#tasks]; + } } -AllTasks.forEach(a => a.load()); +const AllTasks = new TaskStore(); export const TaskList = () => { const session = useLogin(); const user = useUserProfile(session.publicKey); - const [, setTick] = useState(0); + const tasks = useSyncExternalStore(c => AllTasks.hook(c), () => AllTasks.snapshot()); function muteTask(t: UITask) { t.mute(); - setTick(x => (x += 1)); } return (
- {AllTasks.filter(a => (user ? a.check(user, session) : false)).map(a => { - return ( -
-
- -
muteTask(a)}> - + {tasks.filter(a => (user ? a.check(user, session) : false)).map(a => { + if (a.noBaseStyle) { + return a.render(); + } else { + return ( +
+
+ +
muteTask(a)}> + +
+ {a.render()}
- {a.render()} -
- ); + ); + } })}
); diff --git a/packages/app/src/Tasks/index.ts b/packages/app/src/Tasks/index.ts index 73416e41..a0bba592 100644 --- a/packages/app/src/Tasks/index.ts +++ b/packages/app/src/Tasks/index.ts @@ -3,12 +3,13 @@ import { LoginSession } from "@/Login"; export interface UITask { id: string; + noBaseStyle: boolean; /** * Run checks to determine if this Task should be triggered for this user */ check(user: MetadataCache, session: LoginSession): boolean; mute(): void; - load(): void; + load(cb: () => void): void; render(): JSX.Element; } @@ -19,9 +20,11 @@ export interface UITaskState { } export abstract class BaseUITask implements UITask { + #cb?: () => void; protected state: UITaskState; abstract id: string; + noBaseStyle = false; abstract check(user: MetadataCache, session: LoginSession): boolean; abstract render(): JSX.Element; @@ -34,7 +37,8 @@ export abstract class BaseUITask implements UITask { this.#save(); } - load() { + load(cb: () => void) { + this.#cb = cb; const state = window.localStorage.getItem(`task:${this.id}`); if (state) { this.state = JSON.parse(state); @@ -43,5 +47,6 @@ export abstract class BaseUITask implements UITask { #save() { window.localStorage.setItem(`task:${this.id}`, JSON.stringify(this.state)); + this.#cb?.(); } } diff --git a/packages/app/vite.config.ts b/packages/app/vite.config.ts index ff798ef3..4d62cf83 100644 --- a/packages/app/vite.config.ts +++ b/packages/app/vite.config.ts @@ -3,7 +3,6 @@ import { VitePWA } from "vite-plugin-pwa"; import { visualizer } from "rollup-plugin-visualizer"; import { defineConfig } from "vite"; import { vitePluginVersionMark } from "vite-plugin-version-mark"; - import appConfig from "config"; export default defineConfig({ @@ -27,13 +26,13 @@ export default defineConfig({ name: "snort", ifGitSHA: true, command: "git describe --always --tags", - }), + }) ], assetsInclude: ["**/*.md", "**/*.wasm"], build: { outDir: "build", }, - base: "", + clearScreen: false, publicDir: appConfig.get("publicDir"), resolve: { alias: {