Settings Manager (#211)

* refactor: landing screen

* fix: code debt

* feat: add settings screen

* chore: clean up

* feat: settings

* feat: small updates
This commit is contained in:
雨宮蓮
2024-06-19 14:00:58 +07:00
committed by GitHub
parent 0061ecea78
commit 18c133d096
50 changed files with 937 additions and 1167 deletions

View File

@@ -129,6 +129,16 @@ export class NostrAccount {
}
}
static async getContactList() {
const query = await commands.getContactList();
if (query.status === "ok") {
return query.data;
} else {
return [];
}
}
static async isContactListEmpty() {
const query = await commands.isContactListEmpty();

View File

@@ -100,17 +100,9 @@ try {
else return { status: "error", error: e as any };
}
},
async verifyNip05(key: string, nip05: string) : Promise<Result<boolean, string>> {
async getCurrentProfile() : Promise<Result<string, 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 getCurrentUserProfile() : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_current_user_profile") };
return { status: "ok", data: await TAURI_INVOKE("get_current_profile") };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
@@ -244,6 +236,30 @@ try {
else return { status: "error", error: e as any };
}
},
async getSettings() : Promise<Result<Settings, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_settings") };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async setNewSettings(settings: string) : Promise<Result<null, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("set_new_settings", { settings }) };
} 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;
else return { status: "error", error: e as any };
}
},
async getEventMeta(content: string) : Promise<Result<Meta, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_event_meta", { content }) };
@@ -399,11 +415,11 @@ try {
else return { status: "error", error: e as any };
}
},
async setBadge(count: number) : Promise<void> {
await TAURI_INVOKE("set_badge", { count });
},
async openMainWindow() : Promise<void> {
await TAURI_INVOKE("open_main_window");
},
async setBadge(count: number) : Promise<void> {
await TAURI_INVOKE("set_badge", { count });
}
}
@@ -421,6 +437,7 @@ export type Account = { npub: string; nsec: string }
export type Meta = { content: string; images: string[]; videos: string[]; events: string[]; mentions: string[]; hashtags: string[] }
export type Relays = { connected: string[]; read: string[] | null; write: string[] | null; both: string[] | null }
export type RichEvent = { raw: string; parsed: Meta | null }
export type Settings = { proxy: string | null; image_resize_service: string | null; use_relay_hint: boolean; content_warning: boolean; display_avatar: boolean; display_zap_button: boolean; display_repost_button: boolean; display_media: boolean }
/** tauri-specta globals **/

View File

@@ -1,28 +0,0 @@
import { NostrEvent } from "@lume/types";
export function dedupEvents(nostrEvents: NostrEvent[], nsfw: boolean = false) {
const seens = new Set<string>();
const events = nostrEvents.filter((event) => {
const eTags = event.tags.filter((el) => el[0] === "e");
const ids = eTags.map((item) => item[1]);
const isDup = ids.some((id) => seens.has(id));
// Add found ids to seen list
for (const id of ids) {
seens.add(id);
}
// Filter NSFW event
if (nsfw) {
const wTags = event.tags.filter((t) => t[0] === "content-warning");
const isLewd = wTags.length > 0;
return !isDup && !isLewd;
}
// Filter duplicate event
return !isDup;
});
return events;
}

View File

@@ -24,6 +24,11 @@ export class LumeEvent {
Object.assign(this, event);
}
get isWarning() {
const tag = this.tags.find((tag) => tag[0] === "content-warning");
return tag?.[1]; // return: reason;
}
get isQuote() {
return this.tags.filter((tag) => tag[0] === "q").length > 0;
}

View File

@@ -1,25 +1,12 @@
import type {
LumeColumn,
Metadata,
NostrEvent,
Relay,
Settings,
} from "@lume/types";
import { type Result, type RichEvent, commands } from "./commands";
import type { LumeColumn, Metadata, NostrEvent, Relay } from "@lume/types";
import { resolveResource } from "@tauri-apps/api/path";
import { readFile, readTextFile } from "@tauri-apps/plugin-fs";
import { isPermissionGranted } from "@tauri-apps/plugin-notification";
import { open } from "@tauri-apps/plugin-dialog";
import { invoke } from "@tauri-apps/api/core";
import { readFile, readTextFile } from "@tauri-apps/plugin-fs";
import { relaunch } from "@tauri-apps/plugin-process";
import { nip19 } from "nostr-tools";
import { type Result, type RichEvent, commands } from "./commands";
import { LumeEvent } from "./event";
enum NSTORE_KEYS {
settings = "lume_user_settings",
columns = "lume_user_columns",
}
export class NostrQuery {
static #toLumeEvents(richEvents: RichEvent[]) {
const events = richEvents.map((item) => {
@@ -200,18 +187,7 @@ export class NostrQuery {
const query = await commands.getEventsBy(pubkey, until);
if (query.status === "ok") {
const data = query.data.map((item) => {
const raw = JSON.parse(item.raw) as NostrEvent;
if (item.parsed) {
raw.meta = item.parsed;
} else {
raw.meta = null;
}
return raw;
});
const data = NostrQuery.#toLumeEvents(query.data);
return data;
} else {
return [];
@@ -235,18 +211,7 @@ export class NostrQuery {
const query = await commands.getGroupEvents(pubkeys, until);
if (query.status === "ok") {
const data = query.data.map((item) => {
const raw = JSON.parse(item.raw) as NostrEvent;
if (item.parsed) {
raw.meta = item.parsed;
} else {
raw.meta = null;
}
return raw;
});
const data = NostrQuery.#toLumeEvents(query.data);
return data;
} else {
return [];
@@ -258,18 +223,7 @@ export class NostrQuery {
const query = await commands.getGlobalEvents(until);
if (query.status === "ok") {
const data = query.data.map((item) => {
const raw = JSON.parse(item.raw) as NostrEvent;
if (item.parsed) {
raw.meta = item.parsed;
} else {
raw.meta = null;
}
return raw;
});
const data = NostrQuery.#toLumeEvents(query.data);
return data;
} else {
return [];
@@ -282,18 +236,7 @@ export class NostrQuery {
const query = await commands.getHashtagEvents(nostrTags, until);
if (query.status === "ok") {
const data = query.data.map((item) => {
const raw = JSON.parse(item.raw) as NostrEvent;
if (item.parsed) {
raw.meta = item.parsed;
} else {
raw.meta = null;
}
return raw;
});
const data = NostrQuery.#toLumeEvents(query.data);
return data;
} else {
return [];
@@ -314,9 +257,7 @@ export class NostrQuery {
const query = await commands.getNstore(key);
if (query.status === "ok") {
const data: string | string[] = query.data
? JSON.parse(query.data)
: null;
const data = query.data ? JSON.parse(query.data) : null;
return data;
} else {
return null;
@@ -333,51 +274,33 @@ export class NostrQuery {
}
}
static async getSettings() {
const query = await commands.getNstore(NSTORE_KEYS.settings);
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, theme, notification: isGranted };
} else {
const initial: Settings = {
autoUpdate: false,
enhancedPrivacy: false,
notification: false,
zap: false,
nsfw: false,
gossip: false,
theme: "auto",
};
return initial;
}
}
static async setSettings(settings: Settings) {
const query = await commands.setNstore(
NSTORE_KEYS.settings,
JSON.stringify(settings),
);
static async getUserSettings() {
const query = await commands.getSettings();
if (query.status === "ok") {
return query.data;
} else {
throw new Error(query.error);
return query.error;
}
}
static async setUserSettings(newSettings: string) {
const query = await commands.setNewSettings(newSettings);
if (query.status === "ok") {
return query.data;
} else {
return query.error;
}
}
static async getColumns() {
const key = "lume:columns";
const systemPath = "resources/system_columns.json";
const resourcePath = await resolveResource(systemPath);
const resourceFile = await readTextFile(resourcePath);
const systemColumns: LumeColumn[] = JSON.parse(resourceFile);
const query = await commands.getNstore(NSTORE_KEYS.columns);
const query = await commands.getNstore(key);
try {
if (query.status === "ok") {
@@ -399,8 +322,9 @@ export class NostrQuery {
}
static async setColumns(columns: LumeColumn[]) {
const key = "lume:columns";
const content = JSON.stringify(columns);
const query = await commands.setNstore(NSTORE_KEYS.columns, content);
const query = await commands.setNstore(key, content);
if (query.status === "ok") {
return query.data;

View File

@@ -1,16 +1,11 @@
import type { NostrEvent } from "@lume/types";
import type { LumeEvent } from "./event";
import { commands } from "./commands";
import type { LumeEvent } from "./event";
export class LumeWindow {
static async openMainWindow() {
const query = await commands.openMainWindow();
if (query.status === "ok") {
return query.data;
} else {
throw new Error(query.error);
}
return query;
}
static async openEvent(event: NostrEvent | LumeEvent) {