From 954b729dc9da54acaf6779d7f5b5c160a819007a Mon Sep 17 00:00:00 2001 From: reya Date: Thu, 16 Nov 2023 17:48:29 +0700 Subject: [PATCH] wip: settings screen --- package.json | 1 + pnpm-lock.yaml | 44 +++++++ src-tauri/Cargo.lock | 2 +- src/app/settings/about.tsx | 26 +++- src/app/settings/advanced.tsx | 25 +++- src/app/settings/backup.tsx | 36 +++++- src/app/settings/general.tsx | 171 +++++++++++++++++++++++++- src/libs/storage/instance.ts | 8 ++ src/shared/icons/advancedSettings.tsx | 24 ++++ src/shared/icons/dark.tsx | 22 ++++ src/shared/icons/index.ts | 6 + src/shared/icons/info.tsx | 32 +++++ src/shared/icons/light.tsx | 22 ++++ src/shared/icons/system.tsx | 22 ++++ src/shared/icons/user.tsx | 21 ++++ src/shared/layouts/settings.tsx | 164 +++++++++++++----------- 16 files changed, 548 insertions(+), 78 deletions(-) create mode 100644 src/shared/icons/advancedSettings.tsx create mode 100644 src/shared/icons/dark.tsx create mode 100644 src/shared/icons/info.tsx create mode 100644 src/shared/icons/light.tsx create mode 100644 src/shared/icons/system.tsx create mode 100644 src/shared/icons/user.tsx diff --git a/package.json b/package.json index e1145ae2..e9221f5c 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-hover-card": "^1.0.7", "@radix-ui/react-popover": "^1.0.7", + "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-toolbar": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", "@tanstack/react-query": "^5.8.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad849d0a..64394c64 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,9 @@ dependencies: '@radix-ui/react-popover': specifier: ^1.0.7 version: 1.0.7(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-switch': + specifier: ^1.0.3 + version: 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-toolbar': specifier: ^1.0.4 version: 1.0.4(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) @@ -1438,6 +1441,33 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-switch@1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.2 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@types/react': 18.2.37 + '@types/react-dom': 18.2.15 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-toggle-group@1.0.4(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==} peerDependencies: @@ -1605,6 +1635,20 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.37)(react@18.2.0): + resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.2 + '@types/react': 18.2.37 + react: 18.2.0 + dev: false + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.37)(react@18.2.0): resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} peerDependencies: diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index f6604e5d..ca452531 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2612,7 +2612,7 @@ dependencies = [ [[package]] name = "lume" -version = "2.0.1" +version = "2.1.0" dependencies = [ "keyring", "serde", diff --git a/src/app/settings/about.tsx b/src/app/settings/about.tsx index 166794bc..8bbbe597 100644 --- a/src/app/settings/about.tsx +++ b/src/app/settings/about.tsx @@ -1,3 +1,27 @@ +import { getVersion } from '@tauri-apps/api/app'; +import { useEffect, useState } from 'react'; + export function AboutScreen() { - return
; + const [version, setVersion] = useState(''); + + useEffect(() => { + async function loadVersion() { + const appVersion = await getVersion(); + setVersion(appVersion); + } + + loadVersion(); + }, []); + + return ( +
+
+ Lume's logo +
+

Lume

+

Version {version}

+
+
+
+ ); } diff --git a/src/app/settings/advanced.tsx b/src/app/settings/advanced.tsx index fb2d693d..8a5f8660 100644 --- a/src/app/settings/advanced.tsx +++ b/src/app/settings/advanced.tsx @@ -1,3 +1,26 @@ export function AdvancedSettingScreen() { - return
; + return ( +
+
+
+
Event Caches
+ +
+
+
User Caches
+ +
+
+
+ ); } diff --git a/src/app/settings/backup.tsx b/src/app/settings/backup.tsx index b1c1c94b..c0748879 100644 --- a/src/app/settings/backup.tsx +++ b/src/app/settings/backup.tsx @@ -1,3 +1,37 @@ +import { useEffect, useState } from 'react'; + +import { useStorage } from '@libs/storage/provider'; + export function BackupSettingScreen() { - return
; + const { db } = useStorage(); + const [privkey, setPrivkey] = useState(null); + + useEffect(() => { + async function loadPrivkey() { + const key = await db.secureLoad(db.account.pubkey); + if (key) setPrivkey(key); + } + + loadPrivkey(); + }, []); + + return ( +
+
Private key
+
+ {!privkey ? ( +
+ You've stored private key on Lume +
+ ) : ( + + )} +
+
+ ); } diff --git a/src/app/settings/general.tsx b/src/app/settings/general.tsx index b6f089a9..0decafaf 100644 --- a/src/app/settings/general.tsx +++ b/src/app/settings/general.tsx @@ -1,3 +1,172 @@ +import * as Switch from '@radix-ui/react-switch'; +import { useEffect, useState } from 'react'; + +import { useStorage } from '@libs/storage/provider'; + +import { DarkIcon, LightIcon, SystemModeIcon } from '@shared/icons'; + export function GeneralSettingScreen() { - return
; + const { db } = useStorage(); + const [settings, setSettings] = useState({ + autolaunch: false, + outbox: false, + media: true, + hashtag: true, + notification: true, + appearance: 'system', + }); + + useEffect(() => { + async function loadSettings() { + const data = await db.getAllSettings(); + if (!data) return; + + data.forEach((item) => { + if (item.key === 'autolaunch') + setSettings((prev) => ({ + ...prev, + autolaunch: item.value === '1' ? true : false, + })); + + if (item.key === 'outbox') + setSettings((prev) => ({ + ...prev, + outbox: item.value === '1' ? true : false, + })); + + if (item.key === 'media') + setSettings((prev) => ({ + ...prev, + media: item.value === '1' ? true : false, + })); + + if (item.key === 'hashtag') + setSettings((prev) => ({ + ...prev, + hashtag: item.value === '1' ? true : false, + })); + + if (item.key === 'notification') + setSettings((prev) => ({ + ...prev, + notification: item.value === '1' ? true : false, + })); + + if (item.key === 'appearance') + setSettings((prev) => ({ + ...prev, + appearance: item.value, + })); + }); + } + + loadSettings(); + }, []); + + return ( +
+
+
+
+
Startup
+
Launch Lume at Login
+
+ + + +
+
+
+
Gossip
+
Use Outbox model
+
+ + + +
+
+
+
Media
+
Automatically load media
+
+ + + +
+
+
+
Hashtag
+
Hide all hashtags in content
+
+ + + +
+
+
+
+ Notification +
+
Automatically send notification
+
+ + + +
+
+
Appearance
+
+ + + +
+
+
+
+ ); } diff --git a/src/libs/storage/instance.ts b/src/libs/storage/instance.ts index 071e2555..58cef831 100644 --- a/src/libs/storage/instance.ts +++ b/src/libs/storage/instance.ts @@ -435,6 +435,14 @@ export class LumeStorage { ); } + public async getAllSettings() { + const results: { key: string; value: string }[] = await this.db.select( + 'SELECT * FROM settings ORDER BY id DESC;' + ); + if (results.length < 1) return null; + return results; + } + public async getSettingValue(key: string) { const results: { key: string; value: string }[] = await this.db.select( 'SELECT * FROM settings WHERE key = $1 ORDER BY id DESC LIMIT 1;', diff --git a/src/shared/icons/advancedSettings.tsx b/src/shared/icons/advancedSettings.tsx new file mode 100644 index 00000000..cd804893 --- /dev/null +++ b/src/shared/icons/advancedSettings.tsx @@ -0,0 +1,24 @@ +import { SVGProps } from 'react'; + +export function AdvancedSettingsIcon( + props: JSX.IntrinsicAttributes & SVGProps +) { + return ( + + + + ); +} diff --git a/src/shared/icons/dark.tsx b/src/shared/icons/dark.tsx new file mode 100644 index 00000000..4bdaf2d3 --- /dev/null +++ b/src/shared/icons/dark.tsx @@ -0,0 +1,22 @@ +import { SVGProps } from 'react'; + +export function DarkIcon(props: JSX.IntrinsicAttributes & SVGProps) { + return ( + + + + ); +} diff --git a/src/shared/icons/index.ts b/src/shared/icons/index.ts index fc76dda2..2fd28a33 100644 --- a/src/shared/icons/index.ts +++ b/src/shared/icons/index.ts @@ -78,3 +78,9 @@ export * from './heading2'; export * from './heading3'; export * from './bold'; export * from './italic'; +export * from './user'; +export * from './advancedSettings'; +export * from './info'; +export * from './light'; +export * from './dark'; +export * from './system'; diff --git a/src/shared/icons/info.tsx b/src/shared/icons/info.tsx new file mode 100644 index 00000000..b6a60a99 --- /dev/null +++ b/src/shared/icons/info.tsx @@ -0,0 +1,32 @@ +import { SVGProps } from 'react'; + +export function InfoIcon(props: JSX.IntrinsicAttributes & SVGProps) { + return ( + + + + + ); +} diff --git a/src/shared/icons/light.tsx b/src/shared/icons/light.tsx new file mode 100644 index 00000000..119bde0f --- /dev/null +++ b/src/shared/icons/light.tsx @@ -0,0 +1,22 @@ +import { SVGProps } from 'react'; + +export function LightIcon(props: JSX.IntrinsicAttributes & SVGProps) { + return ( + + + + ); +} diff --git a/src/shared/icons/system.tsx b/src/shared/icons/system.tsx new file mode 100644 index 00000000..3129eb8b --- /dev/null +++ b/src/shared/icons/system.tsx @@ -0,0 +1,22 @@ +import { SVGProps } from 'react'; + +export function SystemModeIcon(props: JSX.IntrinsicAttributes & SVGProps) { + return ( + + + + ); +} diff --git a/src/shared/icons/user.tsx b/src/shared/icons/user.tsx new file mode 100644 index 00000000..7bb9eb67 --- /dev/null +++ b/src/shared/icons/user.tsx @@ -0,0 +1,21 @@ +import { SVGProps } from 'react'; + +export function UserIcon(props: JSX.IntrinsicAttributes & SVGProps) { + return ( + + + + ); +} diff --git a/src/shared/layouts/settings.tsx b/src/shared/layouts/settings.tsx index 7280d4bb..f64972bb 100644 --- a/src/shared/layouts/settings.tsx +++ b/src/shared/layouts/settings.tsx @@ -1,10 +1,17 @@ -import { NavLink, Outlet, ScrollRestoration } from 'react-router-dom'; +import { Link, NavLink, Outlet, ScrollRestoration } from 'react-router-dom'; import { twMerge } from 'tailwind-merge'; import { WindowTitlebar } from 'tauri-controls'; import { useStorage } from '@libs/storage/provider'; -import { SecureIcon, SettingsIcon } from '@shared/icons'; +import { + AdvancedSettingsIcon, + ArrowLeftIcon, + InfoIcon, + SecureIcon, + SettingsIcon, + UserIcon, +} from '@shared/icons'; export function SettingsLayout() { const { db } = useStorage(); @@ -17,77 +24,88 @@ export function SettingsLayout() {
)}
-
- - twMerge( - 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 hover:bg-neutral-100 dark:hover:bg-neutral-900', - isActive - ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' - : '' - ) - } - > - -

User

-
- - twMerge( - 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900', - isActive - ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' - : '' - ) - } - > - -

General

-
- - twMerge( - 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900', - isActive - ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' - : '' - ) - } - > - -

Backup

-
- - twMerge( - 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900', - isActive - ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' - : '' - ) - } - > - -

Advanced

-
- - twMerge( - 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900', - isActive - ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' - : '' - ) - } - > - -

About

-
+
+
+ + + +
+
+ + twMerge( + 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900', + isActive + ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' + : '' + ) + } + > + +

User

+
+ + twMerge( + 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900', + isActive + ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' + : '' + ) + } + > + +

General

+
+ + twMerge( + 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900', + isActive + ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' + : '' + ) + } + > + +

Backup

+
+ + twMerge( + 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900', + isActive + ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' + : '' + ) + } + > + +

Advanced

+
+ + twMerge( + 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900', + isActive + ? 'bg-neutral-100 text-blue-500 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800' + : '' + ) + } + > + +

About

+
+
+