feat: add nstore

This commit is contained in:
2024-04-07 15:11:20 +07:00
parent 999073f84c
commit 420be77b5c
75 changed files with 410 additions and 349 deletions

View File

@@ -6,6 +6,7 @@ import type {
EventWithReplies,
Interests,
Keys,
LumeColumn,
Metadata,
Settings,
} from "@lume/types";
@@ -14,6 +15,13 @@ import { open } from "@tauri-apps/plugin-dialog";
import { readFile } from "@tauri-apps/plugin-fs";
import { generateContentTags } from "@lume/utils";
enum NSTORE_KEYS {
settings = "lume_user_settings",
interests = "lume_user_interests",
columns = "lume_user_columns",
group = "lume_group_",
}
export class Ark {
public windows: WebviewWindow[];
@@ -565,13 +573,36 @@ export class Ark {
}
}
public async get_settings(id: string) {
public async get_columns() {
try {
const cmd: string = await invoke("get_settings", { id });
if (!cmd) return null;
if (!cmd.length) return null;
const cmd: string = await invoke("get_nstore", {
key: NSTORE_KEYS.columns,
});
const columns: LumeColumn[] = cmd ? JSON.parse(cmd) : [];
return columns;
} catch {
return [];
}
}
const settings: Settings = JSON.parse(cmd);
public async set_columns(columns: LumeColumn[]) {
try {
const cmd: string = await invoke("set_nstore", {
key: NSTORE_KEYS.columns,
content: JSON.stringify(columns),
});
return cmd;
} catch (e) {
throw new Error(e);
}
}
public async get_settings() {
try {
const cmd: string = await invoke("get_nstore", {
key: NSTORE_KEYS.settings,
});
const settings: Settings = cmd ? JSON.parse(cmd) : null;
return settings;
} catch {
const defaultSettings: Settings = {
@@ -585,7 +616,8 @@ export class Ark {
public async set_settings(settings: Settings) {
try {
const cmd: string = await invoke("set_settings", {
const cmd: string = await invoke("set_nstore", {
key: NSTORE_KEYS.settings,
content: JSON.stringify(settings),
});
return cmd;
@@ -594,13 +626,12 @@ export class Ark {
}
}
public async get_interest(id: string) {
public async get_interest() {
try {
const cmd: string = await invoke("get_interest", { id });
if (!cmd) return null;
if (!cmd.length) return null;
const interests: Interests = JSON.parse(cmd);
const cmd: string = await invoke("get_nstore", {
key: NSTORE_KEYS.interests,
});
const interests: Interests = cmd ? JSON.parse(cmd) : null;
return interests;
} catch {
return null;
@@ -618,7 +649,8 @@ export class Ark {
users: users ?? [],
hashtags: hashtags ?? [],
};
const cmd: string = await invoke("set_interest", {
const cmd: string = await invoke("set_nstore", {
key: NSTORE_KEYS.interests,
content: JSON.stringify(interests),
});
return cmd;

View File

@@ -1,18 +1,17 @@
export function RefreshIcon(props: JSX.IntrinsicElements['svg']) {
export function RefreshIcon(props: JSX.IntrinsicElements["svg"]) {
return (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
>
<path d="M17.5 2.474c.51 1.192.861 2.444 1.049 3.726a.479.479 0 0 1-.298.515l-.181.07M6.5 21.527A15 15 0 0 1 5.451 17.8a.48.48 0 0 1 .298-.515l.181-.07M14.5 7.67a15 15 0 0 0 3.57-.884m0 0a8 8 0 0 0-13.912 6.797m15.75-2.79A8 8 0 0 1 5.93 17.215m3.571-.885a15.002 15.002 0 0 0-3.57.884" />
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" {...props}>
<path
fill="currentColor"
d="M13 21a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm8-10a1 1 0 1 0-2 0 1 1 0 0 0 2 0Zm-1.07 3.268a1 1 0 1 1-1 1.732 1 1 0 0 1 1-1.732Zm-2.562 5.026a1 1 0 1 0-1-1.732 1 1 0 0 0 1 1.732ZM18.927 8a1 1 0 1 1-1-1.732 1 1 0 0 1 1 1.732Z"
/>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.5"
d="M9.25 14.75v5.5h-5.5M9 19.688a8.25 8.25 0 1 1 6.25-15.273"
/>
</svg>
);
}

View File

@@ -75,8 +75,14 @@ export interface RichContent {
notes: string[];
}
export interface ColumnRouteSearch {
account: string;
label: string;
name: string;
}
export interface LumeColumn {
id: number;
label: string;
name: string;
content: URL | string;
description?: string;
@@ -89,7 +95,7 @@ export interface LumeColumn {
export interface EventColumns {
type: "add" | "remove" | "update" | "left" | "right";
id?: number;
label?: string;
column?: LumeColumn;
}

View File

@@ -1,16 +1,18 @@
import { ChevronDownIcon, RefreshIcon, TrashIcon } from "@lume/icons";
import { CancelIcon, RefreshIcon } from "@lume/icons";
import { cn } from "@lume/utils";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { getCurrent } from "@tauri-apps/api/window";
import { ReactNode } from "react";
export function ColumnHeader({
id,
label,
name,
className,
children,
}: {
id: number;
label: string;
name: string;
className?: string;
children?: ReactNode;
}) {
const reload = () => {
window.location.reload();
@@ -18,46 +20,37 @@ export function ColumnHeader({
const close = async () => {
const mainWindow = getCurrent();
await mainWindow.emit("columns", { type: "remove", id });
await mainWindow.emit("columns", { type: "remove", label });
};
return (
<DropdownMenu.Root>
<div
className={cn(
"flex h-11 w-full shrink-0 items-center justify-center gap-2 border-b border-neutral-100 dark:border-neutral-900",
className,
)}
>
<DropdownMenu.Trigger asChild>
<button type="button" className="inline-flex items-center gap-2">
<div className="text-[13px] font-medium">{name}</div>
<ChevronDownIcon className="size-4" />
</button>
</DropdownMenu.Trigger>
</div>
<DropdownMenu.Portal>
<DropdownMenu.Content
sideOffset={5}
className="flex w-[200px] flex-col overflow-hidden rounded-xl bg-black p-1 focus:outline-none dark:bg-white"
<div
className={cn(
"h-11 w-full flex items-center justify-between shrink-0 px-3 border-b border-neutral-100 dark:border-neutral-900",
className,
)}
>
{!children ? (
<div className="text-[13px] font-medium">{name}</div>
) : (
children
)}
<div className="inline-flex items-center gap-1">
<button
type="button"
onClick={reload}
className="size-7 inline-flex hover:bg-neutral-100 rounded-md dark:hover:bg-neutral-900 items-center justify-center text-neutral-600 dark:text-neutral-400 hover:text-neutral-800 dark:hover:text-neutral-200"
>
<DropdownMenu.Item
onClick={reload}
className="inline-flex h-9 items-center gap-2 rounded-lg px-3 text-sm font-medium text-white hover:bg-neutral-900 focus:outline-none dark:text-black dark:hover:bg-neutral-100"
>
<RefreshIcon className="size-4" />
Reload
</DropdownMenu.Item>
<DropdownMenu.Item
onClick={close}
className="inline-flex h-9 items-center gap-2 rounded-lg px-3 text-sm font-medium text-white hover:bg-neutral-900 focus:outline-none dark:text-black dark:hover:bg-neutral-100"
>
<TrashIcon className="size-4" />
Close
</DropdownMenu.Item>
<DropdownMenu.Arrow className="fill-black dark:fill-white" />
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>
<RefreshIcon className="size-4" />
</button>
<button
type="button"
onClick={close}
className="size-7 inline-flex items-center hover:bg-neutral-100 rounded-md dark:hover:bg-neutral-900 justify-center text-neutral-600 dark:text-neutral-400 hover:text-neutral-800 dark:hover:text-neutral-200"
>
<CancelIcon className="size-4" />
</button>
</div>
</div>
);
}

View File

@@ -3,20 +3,20 @@ import { ReactNode } from "react";
export function ColumnRoot({
children,
shadow = true,
background = true,
className,
background = true,
shadow = true,
}: {
children: ReactNode;
shadow?: boolean;
background?: boolean;
className?: string;
background?: boolean;
shadow?: boolean;
}) {
return (
<div className="h-full w-full p-2">
<div
className={cn(
"relative flex h-full w-full flex-col rounded-xl",
"relative flex h-full w-full flex-col rounded-xl overflow-hidden",
shadow ? "shadow-primary" : "",
background ? "bg-white dark:bg-black" : "",
className,