wip: migrate frontend to new backend
This commit is contained in:
@@ -1,2 +1 @@
|
||||
export * from "./storage";
|
||||
export * from "./provider";
|
||||
|
||||
@@ -1,26 +1,118 @@
|
||||
import { LumeColumn } from "@lume/types";
|
||||
import { locale, platform } from "@tauri-apps/plugin-os";
|
||||
import { Store } from "@tauri-apps/plugin-store";
|
||||
import { PropsWithChildren, createContext, useContext } from "react";
|
||||
import {
|
||||
MutableRefObject,
|
||||
PropsWithChildren,
|
||||
useCallback,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { createContext, useContextSelector } from "use-context-selector";
|
||||
import { type VListHandle } from "virtua";
|
||||
import { LumeStorage } from "./storage";
|
||||
|
||||
const StorageContext = createContext<LumeStorage>(null);
|
||||
|
||||
const store = new Store("lume.data");
|
||||
const platformName = await platform();
|
||||
const osLocale = await locale();
|
||||
|
||||
const db = new LumeStorage(store, platformName, osLocale);
|
||||
const store = new Store("lume.dat");
|
||||
const storage = new LumeStorage(store, platformName, osLocale);
|
||||
await storage.init();
|
||||
|
||||
type StorageContext = {
|
||||
storage: LumeStorage;
|
||||
column: {
|
||||
columns: LumeColumn[];
|
||||
vlistRef: MutableRefObject<VListHandle>;
|
||||
create: (column: LumeColumn) => void;
|
||||
remove: (id: number) => void;
|
||||
move: (id: number, position: "left" | "right") => void;
|
||||
update: (id: number, title: string, content: string) => void;
|
||||
};
|
||||
};
|
||||
|
||||
const StorageContext = createContext<StorageContext>(null);
|
||||
|
||||
export const StorageProvider = ({ children }: PropsWithChildren<object>) => {
|
||||
const vlistRef = useRef<VListHandle>(null);
|
||||
|
||||
const [columns, setColumns] = useState<LumeColumn[]>([
|
||||
{
|
||||
id: 1,
|
||||
title: "Newsfeed",
|
||||
content: "",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "For You",
|
||||
content: "",
|
||||
},
|
||||
]);
|
||||
|
||||
const create = useCallback((column: LumeColumn) => {
|
||||
setColumns((prev) => [...prev, column]);
|
||||
vlistRef?.current.scrollToIndex(columns.length);
|
||||
}, []);
|
||||
|
||||
const remove = useCallback((id: number) => {
|
||||
setColumns((prev) => prev.filter((t) => t.id !== id));
|
||||
}, []);
|
||||
|
||||
const update = useCallback(
|
||||
(id: number, title: string, content: string) => {
|
||||
const newCols = columns.map((col) => {
|
||||
if (col.id === id) {
|
||||
return { ...col, title, content };
|
||||
}
|
||||
return col;
|
||||
});
|
||||
|
||||
setColumns(newCols);
|
||||
},
|
||||
[columns],
|
||||
);
|
||||
|
||||
const move = useCallback(
|
||||
(id: number, position: "left" | "right") => {
|
||||
const newCols = [...columns];
|
||||
|
||||
const col = newCols.find((el) => el.id === id);
|
||||
const colIndex = newCols.findIndex((el) => el.id === id);
|
||||
|
||||
newCols.splice(colIndex, 1);
|
||||
|
||||
if (position === "left") newCols.splice(colIndex - 1, 0, col);
|
||||
if (position === "right") newCols.splice(colIndex + 1, 0, col);
|
||||
|
||||
setColumns(newCols);
|
||||
},
|
||||
[columns],
|
||||
);
|
||||
|
||||
return (
|
||||
<StorageContext.Provider value={db}>{children}</StorageContext.Provider>
|
||||
<StorageContext.Provider
|
||||
value={{
|
||||
storage,
|
||||
column: { columns, vlistRef, create, remove, move, update },
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</StorageContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useStorage = () => {
|
||||
const context = useContext(StorageContext);
|
||||
const context = useContextSelector(StorageContext, (state) => state.storage);
|
||||
if (context === undefined) {
|
||||
throw new Error("Please import Storage Provider to use useStorage() hook");
|
||||
throw new Error("Storage Provider is required");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export const useColumn = () => {
|
||||
const context = useContextSelector(StorageContext, (state) => state.column);
|
||||
if (context === undefined) {
|
||||
throw new Error("Storage Provider is required");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Settings } from "@lume/types";
|
||||
import { Platform } from "@tauri-apps/plugin-os";
|
||||
import { Store } from "@tauri-apps/plugin-store";
|
||||
|
||||
@@ -5,17 +6,7 @@ export class LumeStorage {
|
||||
#store: Store;
|
||||
readonly platform: Platform;
|
||||
readonly locale: string;
|
||||
public settings: {
|
||||
autoupdate: boolean;
|
||||
nsecbunker: boolean;
|
||||
media: boolean;
|
||||
hashtag: boolean;
|
||||
lowPower: boolean;
|
||||
translation: boolean;
|
||||
translateApiKey: string;
|
||||
instantZap: boolean;
|
||||
defaultZapAmount: number;
|
||||
};
|
||||
public settings: Settings;
|
||||
|
||||
constructor(store: Store, platform: Platform, locale: string) {
|
||||
this.#store = store;
|
||||
@@ -34,8 +25,24 @@ export class LumeStorage {
|
||||
};
|
||||
}
|
||||
|
||||
public async createSetting(key: string, value: string | boolean) {
|
||||
public async init() {
|
||||
this.loadSettings();
|
||||
}
|
||||
|
||||
public async loadSettings() {
|
||||
const settings: Settings = JSON.parse(await this.#store.get("settings"));
|
||||
for (const [key, value] of Object.entries(settings)) {
|
||||
this.settings[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public async createSetting(key: string, value: string | number | boolean) {
|
||||
this.settings[key] = value;
|
||||
await this.#store.set(this.settings[key], { value });
|
||||
|
||||
const settings: Settings = JSON.parse(await this.#store.get("settings"));
|
||||
const newSettings = { ...settings, key: value };
|
||||
|
||||
await this.#store.set("settings", newSettings);
|
||||
await this.#store.save();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user