feat: add theme switcher

This commit is contained in:
reya 2024-05-26 16:11:27 +07:00
parent 4dc13385a5
commit 5ca9444358
12 changed files with 564 additions and 619 deletions

View File

@ -2,6 +2,7 @@ import { NostrQuery } from "@lume/system";
import type { Settings } from "@lume/types";
import * as Switch from "@radix-ui/react-switch";
import { createFileRoute } from "@tanstack/react-router";
import { invoke } from "@tauri-apps/api/core";
import { requestPermission } from "@tauri-apps/plugin-notification";
import { useEffect, useState } from "react";
import { useDebouncedCallback } from "use-debounce";
@ -61,6 +62,19 @@ function Screen() {
}));
};
const changeTheme = (theme: string) => {
if (theme === "auto" || theme === "light" || theme === "dark") {
invoke("plugin:theme|set_theme", {
theme: theme,
}).then(() =>
setNewSettings((prev) => ({
...prev,
theme,
})),
);
}
};
const updateSettings = useDebouncedCallback(() => {
NostrQuery.setSettings(newSettings);
}, 200);
@ -173,7 +187,6 @@ function Screen() {
Interface
</h2>
<div className="flex flex-col divide-y divide-black/10 dark:divide-white/10 bg-black/5 dark:bg-white/5 rounded-xl px-3">
<div className="flex flex-col gap-4">
<div className="flex w-full items-start justify-between gap-4 py-3">
<div className="flex-1">
<h3 className="font-semibold">Zap</h3>
@ -192,6 +205,25 @@ function Screen() {
</Switch.Root>
</div>
</div>
<div className="flex w-full items-start justify-between gap-4 py-3">
<div className="flex-1">
<h3 className="font-semibold">Appearance</h3>
<p className="text-sm text-neutral-700 dark:text-neutral-300">
* Require restarting the app to take effect.
</p>
</div>
<div className="w-36 flex justify-end shrink-0">
<select
name="theme"
className="bg-transparent shadow-none outline-none rounded-lg border-1 border-black/10 dark:border-white/10 py-1 w-24"
defaultValue={settings.theme}
onChange={(e) => changeTheme(e.target.value)}
>
<option value="auto">Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
</div>
</div>
</div>

View File

@ -1,568 +1,377 @@
// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually.
// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually.
export const commands = {
async getRelays(): Promise<Result<Relays, null>> {
try {
export const commands = {
async getRelays() : Promise<Result<Relays, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_relays") };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async connectRelay(relay: string): Promise<Result<boolean, null>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("connect_relay", { relay }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async connectRelay(relay: string) : Promise<Result<boolean, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("connect_relay", { relay }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async removeRelay(relay: string): Promise<Result<boolean, null>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("remove_relay", { relay }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async removeRelay(relay: string) : Promise<Result<boolean, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("remove_relay", { relay }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getAccounts(): Promise<Result<string, string>> {
try {
}
},
async getAccounts() : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_accounts") };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async createAccount(): Promise<Result<Account, null>> {
try {
}
},
async createAccount() : Promise<Result<Account, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("create_account") };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async saveAccount(
nsec: string,
password: string,
): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("save_account", { nsec, password }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async saveAccount(nsec: string, password: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("save_account", { nsec, password }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getEncryptedKey(
npub: string,
password: string,
): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("get_encrypted_key", { npub, password }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async getEncryptedKey(npub: string, password: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_encrypted_key", { npub, password }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async nostrConnect(
npub: string,
uri: string,
): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("nostr_connect", { npub, uri }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async nostrConnect(npub: string, uri: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("nostr_connect", { npub, uri }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async loadAccount(npub: string): Promise<Result<boolean, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("load_account", { npub }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async loadAccount(npub: string) : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("load_account", { npub }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async eventToBech32(
id: string,
relays: string[],
): Promise<Result<string, null>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("event_to_bech32", { id, relays }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async eventToBech32(id: string, relays: string[]) : Promise<Result<string, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("event_to_bech32", { id, relays }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async userToBech32(
key: string,
relays: string[],
): Promise<Result<string, null>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("user_to_bech32", { key, relays }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async userToBech32(key: string, relays: string[]) : Promise<Result<string, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("user_to_bech32", { key, relays }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async toNpub(hex: string): Promise<Result<string, null>> {
try {
}
},
async toNpub(hex: string) : Promise<Result<string, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("to_npub", { hex }) };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async verifyNip05(
key: string,
nip05: string,
): Promise<Result<boolean, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("verify_nip05", { key, nip05 }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async verifyNip05(key: string, nip05: string) : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("verify_nip05", { key, nip05 }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async runNotification(accounts: string[]): Promise<Result<null, null>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("run_notification", { accounts }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async runNotification(accounts: string[]) : Promise<Result<null, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("run_notification", { accounts }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getActivities(
account: string,
kind: string,
): Promise<Result<string[], string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("get_activities", { account, kind }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async getActivities(account: string, kind: string) : Promise<Result<string[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_activities", { account, kind }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getCurrentUserProfile(): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("get_current_user_profile"),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async getCurrentUserProfile() : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_current_user_profile") };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getProfile(id: string): Promise<Result<string, string>> {
try {
}
},
async getProfile(id: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_profile", { id }) };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getContactList(): Promise<Result<string[], string>> {
try {
}
},
async getContactList() : Promise<Result<string[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_contact_list") };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async setContactList(pubkeys: string[]): Promise<Result<boolean, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("set_contact_list", { pubkeys }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async setContactList(pubkeys: string[]) : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("set_contact_list", { pubkeys }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async createProfile(
name: string,
displayName: string,
about: string,
picture: string,
banner: string,
nip05: string,
lud16: string,
website: string,
): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("create_profile", {
name,
displayName,
about,
picture,
banner,
nip05,
lud16,
website,
}),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async createProfile(name: string, displayName: string, about: string, picture: string, banner: string, nip05: string, lud16: string, website: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("create_profile", { name, displayName, about, picture, banner, nip05, lud16, website }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async follow(
id: string,
alias: string | null,
): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("follow", { id, alias }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async follow(id: string, alias: string | null) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("follow", { id, alias }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async unfollow(id: string): Promise<Result<string, string>> {
try {
}
},
async unfollow(id: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("unfollow", { id }) };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getNstore(key: string): Promise<Result<string, string>> {
try {
}
},
async getNstore(key: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_nstore", { key }) };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async setNstore(
key: string,
content: string,
): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("set_nstore", { key, content }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async setNstore(key: string, content: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("set_nstore", { key, content }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async setNwc(uri: string): Promise<Result<boolean, string>> {
try {
}
},
async setNwc(uri: string) : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("set_nwc", { uri }) };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async loadNwc(): Promise<Result<boolean, string>> {
try {
}
},
async loadNwc() : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("load_nwc") };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getBalance(): Promise<Result<string, string>> {
try {
}
},
async getBalance() : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_balance") };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async zapProfile(
id: string,
amount: string,
message: string,
): Promise<Result<boolean, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("zap_profile", { id, amount, message }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async zapProfile(id: string, amount: string, message: string) : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("zap_profile", { id, amount, message }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async zapEvent(
id: string,
amount: string,
message: string,
): Promise<Result<boolean, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("zap_event", { id, amount, message }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async zapEvent(id: string, amount: string, message: string) : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("zap_event", { id, amount, message }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async friendToFriend(npub: string): Promise<Result<boolean, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("friend_to_friend", { npub }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async friendToFriend(npub: string) : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("friend_to_friend", { npub }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getEvent(id: string): Promise<Result<string, string>> {
try {
}
},
async getEvent(id: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_event", { id }) };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getReplies(id: string): Promise<Result<string[], string>> {
try {
}
},
async getReplies(id: string) : Promise<Result<string[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_replies", { id }) };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getEventsBy(
publicKey: string,
asOf: string | null,
): Promise<Result<string[], string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("get_events_by", { publicKey, asOf }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async getEventsBy(publicKey: string, asOf: string | null) : Promise<Result<string[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_events_by", { publicKey, asOf }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getLocalEvents(
pubkeys: string[],
until: string | null,
): Promise<Result<string[], string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("get_local_events", { pubkeys, until }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async getLocalEvents(pubkeys: string[], until: string | null) : Promise<Result<string[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_local_events", { pubkeys, until }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getGlobalEvents(
until: string | null,
): Promise<Result<string[], string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("get_global_events", { until }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async getGlobalEvents(until: string | null) : Promise<Result<string[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_global_events", { until }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getHashtagEvents(
hashtags: string[],
until: string | null,
): Promise<Result<string[], string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("get_hashtag_events", { hashtags, until }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async getHashtagEvents(hashtags: string[], until: string | null) : Promise<Result<string[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_hashtag_events", { hashtags, until }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async publish(
content: string,
tags: string[][],
): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("publish", { content, tags }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async publish(content: string, tags: string[][]) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("publish", { content, tags }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async repost(raw: string): Promise<Result<string, string>> {
try {
}
},
async repost(raw: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("repost", { raw }) };
} catch (e) {
if (e instanceof Error) throw e;
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async showInFolder(path: string): Promise<void> {
await TAURI_INVOKE("show_in_folder", { path });
},
async createColumn(
label: string,
x: number,
y: number,
width: number,
height: number,
url: string,
): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("create_column", {
label,
x,
y,
width,
height,
url,
}),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async showInFolder(path: string) : Promise<void> {
await TAURI_INVOKE("show_in_folder", { path });
},
async createColumn(label: string, x: number, y: number, width: number, height: number, url: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("create_column", { label, x, y, width, height, url }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async closeColumn(label: string): Promise<Result<boolean, null>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("close_column", { label }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async closeColumn(label: string) : Promise<Result<boolean, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("close_column", { label }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async repositionColumn(
label: string,
x: number,
y: number,
): Promise<Result<null, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("reposition_column", { label, x, y }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async repositionColumn(label: string, x: number, y: number) : Promise<Result<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("reposition_column", { label, x, y }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async resizeColumn(
label: string,
width: number,
height: number,
): Promise<Result<null, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("resize_column", { label, width, height }),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async resizeColumn(label: string, width: number, height: number) : Promise<Result<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("resize_column", { label, width, height }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async openWindow(
label: string,
title: string,
url: string,
width: number,
height: number,
): Promise<Result<null, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("open_window", {
label,
title,
url,
width,
height,
}),
};
} catch (e) {
if (e instanceof Error) throw e;
}
},
async openWindow(label: string, title: string, url: string, width: number, height: number) : Promise<Result<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("open_window", { label, title, url, width, height }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async setBadge(count: number): Promise<void> {
await TAURI_INVOKE("set_badge", { count });
},
};
}
},
async setBadge(count: number) : Promise<void> {
await TAURI_INVOKE("set_badge", { count });
}
}
/** user-defined types **/
export type Account = { npub: string; nsec: string };
export type Relays = {
connected: string[];
read: string[] | null;
write: string[] | null;
both: string[] | null;
};
export type Account = { npub: string; nsec: string }
export type Relays = { connected: string[]; read: string[] | null; write: string[] | null; both: string[] | null }
/** tauri-specta globals **/
import { invoke as TAURI_INVOKE } from "@tauri-apps/api/core";
import { invoke as TAURI_INVOKE } from "@tauri-apps/api/core";
import * as TAURI_API_EVENT from "@tauri-apps/api/event";
import { type WebviewWindow as __WebviewWindow__ } from "@tauri-apps/api/webviewWindow";
type __EventObj__<T> = {
listen: (
cb: TAURI_API_EVENT.EventCallback<T>,
cb: TAURI_API_EVENT.EventCallback<T>
) => ReturnType<typeof TAURI_API_EVENT.listen<T>>;
once: (
cb: TAURI_API_EVENT.EventCallback<T>,
cb: TAURI_API_EVENT.EventCallback<T>
) => ReturnType<typeof TAURI_API_EVENT.once<T>>;
emit: T extends null
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
@ -574,7 +383,7 @@ export type Result<T, E> =
| { status: "error"; error: E };
function __makeEvents__<T extends Record<string, any>>(
mappings: Record<keyof T, string>,
mappings: Record<keyof T, string>
) {
return new Proxy(
{} as unknown as {
@ -604,6 +413,8 @@ function __makeEvents__<T extends Record<string, any>>(
},
});
},
},
}
);
}

View File

@ -5,6 +5,7 @@ import { readFile, readTextFile } from "@tauri-apps/plugin-fs";
import { isPermissionGranted } from "@tauri-apps/plugin-notification";
import { open } from "@tauri-apps/plugin-dialog";
import { dedupEvents } from "./dedup";
import { invoke } from "@tauri-apps/api/core";
enum NSTORE_KEYS {
settings = "lume_user_settings",
@ -201,8 +202,11 @@ export class NostrQuery {
if (query.status === "ok") {
const settings: Settings = query.data ? JSON.parse(query.data) : null;
const isGranted = await isPermissionGranted();
const theme: "auto" | "light" | "dark" = await invoke(
"plugin:theme|get_theme",
);
return { ...settings, notification: isGranted };
return { ...settings, theme, notification: isGranted };
} else {
const initial: Settings = {
autoUpdate: false,
@ -210,6 +214,8 @@ export class NostrQuery {
notification: false,
zap: false,
nsfw: false,
gossip: false,
theme: "auto",
};
return initial;

View File

@ -5,6 +5,7 @@ export interface Settings {
zap: boolean;
nsfw: boolean;
gossip: boolean;
theme: "auto" | "light" | "dark";
[key: string]: string | number | boolean;
}

29
src-tauri/Cargo.lock generated
View File

@ -2907,6 +2907,7 @@ dependencies = [
"tauri-plugin-os",
"tauri-plugin-process",
"tauri-plugin-shell",
"tauri-plugin-theme",
"tauri-plugin-updater",
"tauri-plugin-upload",
"tauri-plugin-window-state",
@ -5514,6 +5515,24 @@ dependencies = [
"tokio",
]
[[package]]
name = "tauri-plugin-theme"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c23856e93f56cd8d1868e7dd8a4b529b836fd5da315cefd7702b252a850cdf5a"
dependencies = [
"cocoa",
"dirs-next",
"futures-lite 2.3.0",
"gtk",
"once_cell",
"serde",
"tauri",
"tauri-plugin",
"tintanum",
"tokio",
]
[[package]]
name = "tauri-plugin-updater"
version = "2.0.0-beta.5"
@ -5805,6 +5824,16 @@ dependencies = [
"time-core",
]
[[package]]
name = "tintanum"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abbcf9173afc80733c20b7e27a30bc9284d6535bdbde2a70904032de63e16e8"
dependencies = [
"futures-lite 1.13.0",
"zbus 3.15.1",
]
[[package]]
name = "tinyvec"
version = "1.6.0"

View File

@ -39,6 +39,7 @@ keyring = "2"
keyring-search = "0.2.0"
specta = "=2.0.0-rc.12"
tauri-specta = { version = "=2.0.0-rc.10", features = ["typescript"] }
tauri-plugin-theme = "0.4.1"
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.25.0"

View File

@ -56,6 +56,8 @@
"dialog:allow-message",
"process:allow-restart",
"fs:allow-read-file",
"theme:allow-set-theme",
"theme:allow-get-theme",
"shell:allow-open",
{
"identifier": "http:default",

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"desktop-capability":{"identifier":"desktop-capability","description":"Capability for the desktop","local":true,"windows":["main","splash","settings","search","nwc","activity","zap-*","event-*","user-*","editor-*","column-*"],"permissions":["path:default","event:default","window:default","app:default","resources:default","menu:default","tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","os:allow-os-type","updater:default","updater:allow-check","updater:allow-download-and-install","window:allow-start-dragging","window:allow-create","window:allow-close","window:allow-set-focus","window:allow-center","window:allow-minimize","window:allow-maximize","window:allow-set-size","window:allow-set-focus","window:allow-start-dragging","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","webview:allow-create-webview-window","webview:allow-create-webview","webview:allow-set-webview-size","webview:allow-set-webview-position","webview:allow-webview-close","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","fs:allow-read-file","shell:allow-open",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["linux","macOS","windows"]}}
{"desktop-capability":{"identifier":"desktop-capability","description":"Capability for the desktop","local":true,"windows":["main","splash","settings","search","nwc","activity","zap-*","event-*","user-*","editor-*","column-*"],"permissions":["path:default","event:default","window:default","app:default","resources:default","menu:default","tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","os:allow-os-type","updater:default","updater:allow-check","updater:allow-download-and-install","window:allow-start-dragging","window:allow-create","window:allow-close","window:allow-set-focus","window:allow-center","window:allow-minimize","window:allow-maximize","window:allow-set-size","window:allow-set-focus","window:allow-start-dragging","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","webview:allow-create-webview-window","webview:allow-create-webview","webview:allow-set-webview-size","webview:allow-set-webview-position","webview:allow-webview-close","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","fs:allow-read-file","theme:allow-set-theme","theme:allow-get-theme","shell:allow-open",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["linux","macOS","windows"]}}

View File

@ -5654,6 +5654,40 @@
"shell:deny-stdin-write"
]
},
{
"type": "string",
"enum": [
"theme:default"
]
},
{
"description": "theme:allow-get-theme -> Enables the get_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:allow-get-theme"
]
},
{
"description": "theme:allow-set-theme -> Enables the set_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:allow-set-theme"
]
},
{
"description": "theme:deny-get-theme -> Denies the get_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:deny-get-theme"
]
},
{
"description": "theme:deny-set-theme -> Denies the set_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:deny-set-theme"
]
},
{
"description": "tray:default -> Default permissions for the plugin.",
"type": "string",

View File

@ -5654,6 +5654,40 @@
"shell:deny-stdin-write"
]
},
{
"type": "string",
"enum": [
"theme:default"
]
},
{
"description": "theme:allow-get-theme -> Enables the get_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:allow-get-theme"
]
},
{
"description": "theme:allow-set-theme -> Enables the set_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:allow-set-theme"
]
},
{
"description": "theme:deny-get-theme -> Denies the get_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:deny-get-theme"
]
},
{
"description": "theme:deny-set-theme -> Denies the set_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:deny-set-theme"
]
},
{
"description": "tray:default -> Default permissions for the plugin.",
"type": "string",

View File

@ -24,6 +24,7 @@ pub struct Nostr {
}
fn main() {
let mut ctx = tauri::generate_context!();
let invoke_handler = {
let builder = tauri_specta::ts::builder().commands(tauri_specta::collect_commands![
nostr::relay::get_relays,
@ -135,13 +136,7 @@ fn main() {
Ok(())
})
.on_window_event(|window, event| match event {
tauri::WindowEvent::CloseRequested { api, .. } => {
window.hide().unwrap();
api.prevent_close();
}
_ => {}
})
.plugin(tauri_plugin_theme::init(ctx.config_mut()))
.plugin(tauri_plugin_decorum::init())
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_dialog::init())
@ -154,6 +149,6 @@ fn main() {
.plugin(tauri_plugin_upload::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.invoke_handler(invoke_handler)
.run(tauri::generate_context!())
.run(ctx)
.expect("error while running tauri application")
}