mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-19 11:43:30 +00:00
update settings page
This commit is contained in:
parent
d35c64e28d
commit
6f29df112b
@ -41,6 +41,7 @@
|
||||
"slate-history": "^0.93.0",
|
||||
"slate-react": "^0.94.2",
|
||||
"tailwind-merge": "^1.13.2",
|
||||
"tauri-plugin-autostart-api": "github:tauri-apps/tauri-plugin-autostart#v1",
|
||||
"tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql",
|
||||
"zustand": "^4.3.8"
|
||||
},
|
||||
|
@ -85,6 +85,9 @@ dependencies:
|
||||
tailwind-merge:
|
||||
specifier: ^1.13.2
|
||||
version: 1.13.2
|
||||
tauri-plugin-autostart-api:
|
||||
specifier: github:tauri-apps/tauri-plugin-autostart#v1
|
||||
version: github.com/tauri-apps/tauri-plugin-autostart/b331e5700ca2a5d340563efab7398c61812c69f7
|
||||
tauri-plugin-sql-api:
|
||||
specifier: github:tauri-apps/tauri-plugin-sql
|
||||
version: github.com/tauri-apps/tauri-plugin-sql/45b46ee428f6c13a831d237d8b602349ad6b17a6
|
||||
@ -5530,6 +5533,14 @@ packages:
|
||||
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
github.com/tauri-apps/tauri-plugin-autostart/b331e5700ca2a5d340563efab7398c61812c69f7:
|
||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-autostart/tar.gz/b331e5700ca2a5d340563efab7398c61812c69f7}
|
||||
name: tauri-plugin-autostart-api
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
'@tauri-apps/api': 1.4.0
|
||||
dev: false
|
||||
|
||||
github.com/tauri-apps/tauri-plugin-sql/45b46ee428f6c13a831d237d8b602349ad6b17a6:
|
||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-sql/tar.gz/45b46ee428f6c13a831d237d8b602349ad6b17a6}
|
||||
name: tauri-plugin-sql-api
|
||||
|
51
src-tauri/Cargo.lock
generated
51
src-tauri/Cargo.lock
generated
@ -244,6 +244,17 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "auto-launch"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5904a4d734f0235edf29aab320a14899f3e090446e594ff96508a6215f76f89c"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"thiserror",
|
||||
"winreg 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
@ -864,6 +875,15 @@ dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-next"
|
||||
version = "2.0.0"
|
||||
@ -874,6 +894,17 @@ dependencies = [
|
||||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys-next"
|
||||
version = "0.1.2"
|
||||
@ -2072,6 +2103,7 @@ dependencies = [
|
||||
"sqlx-cli",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-autostart",
|
||||
"tauri-plugin-single-instance",
|
||||
"tauri-plugin-sql",
|
||||
"tauri-plugin-store",
|
||||
@ -4063,10 +4095,23 @@ dependencies = [
|
||||
"tauri-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-autostart"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#36b7296746bf8d41f0790d8ecd9b097430750a47"
|
||||
dependencies = [
|
||||
"auto-launch",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-single-instance"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=dev#dce0f02bc571128308c30278cde3233f341e6a50"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#36b7296746bf8d41f0790d8ecd9b097430750a47"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@ -4080,7 +4125,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tauri-plugin-sql"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=dev#dce0f02bc571128308c30278cde3233f341e6a50"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#36b7296746bf8d41f0790d8ecd9b097430750a47"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"log",
|
||||
@ -4096,7 +4141,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tauri-plugin-store"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=dev#dce0f02bc571128308c30278cde3233f341e6a50"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#36b7296746bf8d41f0790d8ecd9b097430750a47"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
|
@ -17,13 +17,14 @@ tauri-build = { version = "1.2", features = [] }
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tauri = { version = "1.2", features = [ "clipboard-read-text", "clipboard-write-text", "dialog-open", "fs-read-dir", "fs-read-file", "http-all", "http-multipart", "notification-all", "os-all", "process-relaunch", "shell-open", "system-tray", "updater", "window-close", "window-start-dragging"] }
|
||||
tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" }
|
||||
tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" }
|
||||
tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
||||
tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
||||
tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
||||
sqlx-cli = {version = "0.6.3", default-features = false, features = ["sqlite"] }
|
||||
|
||||
[dependencies.tauri-plugin-sql]
|
||||
git = "https://github.com/tauri-apps/plugins-workspace"
|
||||
branch = "dev"
|
||||
branch = "v1"
|
||||
features = ["sqlite"]
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
|
@ -2,4 +2,13 @@
|
||||
INSERT INTO
|
||||
settings (key, value)
|
||||
VALUES
|
||||
("last_login", "0");
|
||||
("last_login", "0"),
|
||||
(
|
||||
"relays",
|
||||
'["wss://relayable.org","wss://relay.damus.io","wss://relay.nostr.band/all","wss://relay.nostrgraph.net","wss://nostr.mutinywallet.com"]'
|
||||
),
|
||||
("auto_start", "0"),
|
||||
("cache_time", "86400"),
|
||||
("compose_shortcut", "meta+n"),
|
||||
("add_imageblock_shortcut", "meta+i"),
|
||||
("add_feedblock_shortcut", "meta+f")
|
@ -9,6 +9,7 @@ extern crate objc;
|
||||
|
||||
use tauri::{Manager, WindowEvent};
|
||||
use tauri_plugin_sql::{Migration, MigrationKind};
|
||||
use tauri_plugin_autostart::MacosLauncher;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use window_ext::WindowExt;
|
||||
@ -109,6 +110,7 @@ fn main() {
|
||||
)
|
||||
.build(),
|
||||
)
|
||||
.plugin(tauri_plugin_autostart::init(MacosLauncher::LaunchAgent, Some(vec!["--flag1", "--flag2"])))
|
||||
.plugin(tauri_plugin_single_instance::init(|app, argv, cwd| {
|
||||
println!("{}, {argv:?}, {cwd}", app.package_info().name);
|
||||
app
|
||||
|
@ -16,7 +16,6 @@ import { Root } from "@app/root";
|
||||
import { AccountSettingsScreen } from "@app/settings/account";
|
||||
import { GeneralSettingsScreen } from "@app/settings/general";
|
||||
import { ShortcutsSettingsScreen } from "@app/settings/shortcuts";
|
||||
import { UpdateSettingsScreen } from "@app/settings/update";
|
||||
import { SpaceScreen } from "@app/space";
|
||||
import { TrendingScreen } from "@app/trending";
|
||||
import { UserScreen } from "@app/user";
|
||||
@ -88,7 +87,6 @@ const router = createBrowserRouter([
|
||||
{ path: "general", element: <GeneralSettingsScreen /> },
|
||||
{ path: "shortcuts", element: <ShortcutsSettingsScreen /> },
|
||||
{ path: "account", element: <AccountSettingsScreen /> },
|
||||
{ path: "update", element: <UpdateSettingsScreen /> },
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
@ -143,7 +143,8 @@ export function Root() {
|
||||
const chats = await fetchChats();
|
||||
// const channels = await fetchChannelMessages();
|
||||
if (chats) {
|
||||
await updateLastLogin(dateToUnix());
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
await updateLastLogin(now);
|
||||
navigate("/app/space", { replace: true });
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,84 @@
|
||||
import { EyeOffIcon, EyeOnIcon } from "@shared/icons";
|
||||
import { useAccount } from "@utils/hooks/useAccount";
|
||||
import { useState } from "react";
|
||||
|
||||
export function AccountSettingsScreen() {
|
||||
const { status, account } = useAccount();
|
||||
const [type, setType] = useState("password");
|
||||
|
||||
const showPrivateKey = () => {
|
||||
if (type === "password") {
|
||||
setType("text");
|
||||
} else {
|
||||
setType("password");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<h1>Account</h1>
|
||||
<div className="w-full h-full px-3 pt-12">
|
||||
<div className="flex flex-col gap-2">
|
||||
<h1 className="text-lg font-semibold text-zinc-100">Account</h1>
|
||||
<div className="">
|
||||
{status === "loading" ? (
|
||||
<p>Loading...</p>
|
||||
) : (
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-base font-semibold text-zinc-400">
|
||||
Public Key
|
||||
</label>
|
||||
<input
|
||||
readOnly
|
||||
value={account.pubkey}
|
||||
className="relative w-2/3 rounded-lg py-3 pl-3.5 pr-11 !outline-none placeholder:text-zinc-400 bg-zinc-800 text-zinc-100"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-base font-semibold text-zinc-400">
|
||||
Npub
|
||||
</label>
|
||||
<input
|
||||
readOnly
|
||||
value={account.npub}
|
||||
className="relative w-2/3 rounded-lg py-3 pl-3.5 pr-11 !outline-none placeholder:text-zinc-400 bg-zinc-800 text-zinc-100"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-base font-semibold text-zinc-400">
|
||||
Private Key
|
||||
</label>
|
||||
<div className="relative w-2/3">
|
||||
<input
|
||||
readOnly
|
||||
type={type}
|
||||
value={account.privkey}
|
||||
className="relative w-full rounded-lg py-3 pl-3.5 pr-11 !outline-none placeholder:text-zinc-400 bg-zinc-800 text-zinc-100"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => showPrivateKey()}
|
||||
className="group absolute right-2 top-1/2 -translate-y-1/2 transform rounded p-1 hover:bg-zinc-700"
|
||||
>
|
||||
{type === "password" ? (
|
||||
<EyeOffIcon
|
||||
width={20}
|
||||
height={20}
|
||||
className="text-zinc-500 group-hover:text-zinc-100"
|
||||
/>
|
||||
) : (
|
||||
<EyeOnIcon
|
||||
width={20}
|
||||
height={20}
|
||||
className="text-zinc-500 group-hover:text-zinc-100"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
61
src/app/settings/components/autoStart.tsx
Normal file
61
src/app/settings/components/autoStart.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
import { Switch } from "@headlessui/react";
|
||||
import { getSetting, updateSetting } from "@libs/storage";
|
||||
import { useEffect, useState } from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { disable, enable, isEnabled } from "tauri-plugin-autostart-api";
|
||||
|
||||
export function AutoStartSetting() {
|
||||
const [enabled, setEnabled] = useState(false);
|
||||
|
||||
const toggle = async () => {
|
||||
if (!enabled) {
|
||||
await enable();
|
||||
await updateSetting("auto_start", 1);
|
||||
console.log(`registered for autostart? ${await isEnabled()}`);
|
||||
} else {
|
||||
await disable();
|
||||
await updateSetting("auto_start", 0);
|
||||
}
|
||||
setEnabled(!enabled);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
async function getAppSetting() {
|
||||
const setting = await getSetting("auto_start");
|
||||
if (parseInt(setting) === 0) {
|
||||
setEnabled(false);
|
||||
} else {
|
||||
setEnabled(true);
|
||||
}
|
||||
}
|
||||
getAppSetting();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="px-5 py-4 inline-flex items-center justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="leading-none font-medium text-zinc-200">
|
||||
Auto start
|
||||
</span>
|
||||
<span className="leading-none text-sm text-zinc-400">
|
||||
Auto start at login
|
||||
</span>
|
||||
</div>
|
||||
<Switch
|
||||
checked={enabled}
|
||||
onChange={toggle}
|
||||
className={twMerge(
|
||||
"relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-fuchsia-500 focus:ring-offset-2",
|
||||
enabled ? "bg-fuchsia-500" : "bg-zinc-700",
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={twMerge(
|
||||
"pointer-events-none inline-block h-5 w-5 transform rounded-full bg-zinc-900 shadow ring-0 transition duration-200 ease-in-out",
|
||||
enabled ? "translate-x-5" : "translate-x-0",
|
||||
)}
|
||||
/>
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
43
src/app/settings/components/cacheTime.tsx
Normal file
43
src/app/settings/components/cacheTime.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import { getSetting, updateSetting } from "@libs/storage";
|
||||
import { CheckCircleIcon } from "@shared/icons";
|
||||
import { useState } from "react";
|
||||
|
||||
const setting = await getSetting("cache_time");
|
||||
const cacheTime = setting;
|
||||
|
||||
export function CacheTimeSetting() {
|
||||
const [time, setTime] = useState(cacheTime);
|
||||
|
||||
const update = async () => {
|
||||
await updateSetting("cache_time", time);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="px-5 py-4 inline-flex items-center justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="leading-none font-medium text-zinc-200">
|
||||
Cache time
|
||||
</span>
|
||||
<span className="leading-none text-sm text-zinc-400">
|
||||
The length of time before inactive data gets removed from the cache
|
||||
</span>
|
||||
</div>
|
||||
<div className="inline-flex items-center gap-2">
|
||||
<input
|
||||
value={time}
|
||||
onChange={(e) => setTime(e.currentTarget.value)}
|
||||
autoCapitalize="none"
|
||||
autoCorrect="none"
|
||||
className="w-24 h-8 rounded-md px-2 bg-zinc-800 text-zinc-300 text-right font-medium focus:outline-none"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => update()}
|
||||
className="w-8 h-8 inline-flex items-center justify-center font-medium bg-zinc-800 hover:bg-fuchsia-500 rounded-md"
|
||||
>
|
||||
<CheckCircleIcon className="w-4 h-4 text-zinc-100" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
26
src/app/settings/components/version.tsx
Normal file
26
src/app/settings/components/version.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import { RefreshIcon } from "@shared/icons";
|
||||
import { getVersion } from "@tauri-apps/api/app";
|
||||
|
||||
const appVersion = await getVersion();
|
||||
|
||||
export function VersionSetting() {
|
||||
return (
|
||||
<div className="px-5 py-4 inline-flex items-center justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="leading-none font-medium text-zinc-200">Version</span>
|
||||
<span className="leading-none text-sm text-zinc-400">
|
||||
You're using latest version
|
||||
</span>
|
||||
</div>
|
||||
<div className="inline-flex items-center gap-2">
|
||||
<span className="text-zinc-300 font-medium">{appVersion}</span>
|
||||
<button
|
||||
type="button"
|
||||
className="w-8 h-8 inline-flex items-center justify-center font-medium bg-zinc-800 hover:bg-fuchsia-500 rounded-md"
|
||||
>
|
||||
<RefreshIcon className="w-4 h-4 text-zinc-100" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,7 +1,20 @@
|
||||
import { AutoStartSetting } from "@app/settings/components/autoStart";
|
||||
import { CacheTimeSetting } from "@app/settings/components/cacheTime";
|
||||
import { VersionSetting } from "@app/settings/components/version";
|
||||
|
||||
export function GeneralSettingsScreen() {
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<h1>General</h1>
|
||||
<div className="w-full h-full px-3 pt-12">
|
||||
<div className="flex flex-col gap-2">
|
||||
<h1 className="text-lg font-semibold text-zinc-100">General</h1>
|
||||
<div className="w-full bg-zinc-900 border-t border-zinc-800/50 rounded-xl">
|
||||
<div className="w-full h-full flex flex-col divide-y divide-zinc-800">
|
||||
<AutoStartSetting />
|
||||
<CacheTimeSetting />
|
||||
<VersionSetting />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,7 +1,110 @@
|
||||
import { CommandIcon } from "@shared/icons";
|
||||
|
||||
export function ShortcutsSettingsScreen() {
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<h1>Shortcuts</h1>
|
||||
<div className="w-full h-full px-3 pt-12">
|
||||
<div className="flex flex-col gap-2">
|
||||
<h1 className="text-lg font-semibold text-zinc-100">Shortcuts</h1>
|
||||
<div className="w-full bg-zinc-900 border-t border-zinc-800/50 rounded-xl">
|
||||
<div className="w-full h-full flex flex-col divide-y divide-zinc-800">
|
||||
<div className="px-5 py-4 inline-flex items-center justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="leading-none font-medium text-zinc-200">
|
||||
Open composer
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<CommandIcon
|
||||
width={12}
|
||||
height={12}
|
||||
className="text-zinc-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<span className="text-zinc-500 text-sm leading-none">N</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-5 py-4 inline-flex items-center justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="leading-none font-medium text-zinc-200">
|
||||
Add image block
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<CommandIcon
|
||||
width={12}
|
||||
height={12}
|
||||
className="text-zinc-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<span className="text-zinc-500 text-sm leading-none">I</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-5 py-4 inline-flex items-center justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="leading-none font-medium text-zinc-200">
|
||||
Add newsfeed block
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<CommandIcon
|
||||
width={12}
|
||||
height={12}
|
||||
className="text-zinc-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<span className="text-zinc-500 text-sm leading-none">F</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-5 py-4 inline-flex items-center justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="leading-none font-medium text-zinc-200">
|
||||
Open personal page
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<CommandIcon
|
||||
width={12}
|
||||
height={12}
|
||||
className="text-zinc-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<span className="text-zinc-500 text-sm leading-none">P</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-5 py-4 inline-flex items-center justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="leading-none font-medium text-zinc-200">
|
||||
Open notification
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<CommandIcon
|
||||
width={12}
|
||||
height={12}
|
||||
className="text-zinc-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-t border-zinc-700/50 bg-zinc-800">
|
||||
<span className="text-zinc-500 text-sm leading-none">B</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
export function UpdateSettingsScreen() {
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<h1>Update</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -39,7 +39,7 @@ export async function prefetchEvents(
|
||||
});
|
||||
|
||||
relaySetSubscription.on("eose", () => {
|
||||
setTimeout(() => resolve(new Set(events.values())), 1200);
|
||||
setTimeout(() => resolve(new Set(events.values())), 3000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -325,13 +325,34 @@ export async function createChat(
|
||||
return sender_pubkey;
|
||||
}
|
||||
|
||||
// get setting
|
||||
export async function getSetting(key: string) {
|
||||
const db = await connect();
|
||||
const result = await db.select(
|
||||
`SELECT value FROM settings WHERE key = "${key}";`,
|
||||
);
|
||||
return result[0]?.value;
|
||||
}
|
||||
|
||||
// update setting
|
||||
export async function updateSetting(key: string, value: string | number) {
|
||||
const db = await connect();
|
||||
return await db.execute(
|
||||
`UPDATE settings SET value = "${value}" WHERE key = "${key}";`,
|
||||
);
|
||||
}
|
||||
|
||||
// get last login
|
||||
export async function getLastLogin() {
|
||||
const db = await connect();
|
||||
const result = await db.select(
|
||||
`SELECT value FROM settings WHERE key = "last_login";`,
|
||||
);
|
||||
return result[0]?.value;
|
||||
if (result[0]) {
|
||||
return parseInt(result[0].value);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// update last login
|
||||
|
@ -1,12 +1,15 @@
|
||||
import App from "./app";
|
||||
import { getSetting } from "@libs/storage";
|
||||
import { RelayProvider } from "@shared/relayProvider";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { createRoot } from "react-dom/client";
|
||||
|
||||
const cacheTime = await getSetting("cache_time");
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
cacheTime: 1000 * 60 * 60 * 24,
|
||||
cacheTime: parseInt(cacheTime),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -8,7 +8,8 @@ export function VideoPreview({ urls }: { urls: string[] }) {
|
||||
key={url}
|
||||
url={url}
|
||||
width="100%"
|
||||
className="w-full h-auto border border-zinc-800/50 rounded-lg"
|
||||
height="auto"
|
||||
className="!h-auto object-fill rounded-lg overflow-hidden"
|
||||
controls={true}
|
||||
pip={true}
|
||||
/>
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { initNDK } from "@libs/ndk";
|
||||
import { getSetting } from "@libs/storage";
|
||||
import NDK from "@nostr-dev-kit/ndk";
|
||||
import { FULL_RELAYS } from "@stores/constants";
|
||||
import { createContext } from "react";
|
||||
|
||||
export const RelayContext = createContext<NDK>(null);
|
||||
|
||||
const ndk = await initNDK(FULL_RELAYS);
|
||||
const relays = await getSetting("relays");
|
||||
const relaysArray = JSON.parse(relays);
|
||||
const ndk = await initNDK(relaysArray);
|
||||
|
||||
export function RelayProvider({ children }: { children: React.ReactNode }) {
|
||||
return <RelayContext.Provider value={ndk}>{children}</RelayContext.Provider>;
|
||||
|
@ -49,17 +49,6 @@ export function SettingsLayout() {
|
||||
>
|
||||
<span className="font-medium">Account</span>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to="/settings/update"
|
||||
className={({ isActive }) =>
|
||||
twMerge(
|
||||
"flex h-9 items-center gap-2.5 rounded-md px-2.5 text-zinc-200",
|
||||
isActive ? "bg-zinc-900/50" : "",
|
||||
)
|
||||
}
|
||||
>
|
||||
<span className="font-medium">Update</span>
|
||||
</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user