119 lines
2.8 KiB
TypeScript
119 lines
2.8 KiB
TypeScript
import { LumeColumn } from "@lume/types";
|
|
import { locale, platform } from "@tauri-apps/plugin-os";
|
|
import { Store } from "@tauri-apps/plugin-store";
|
|
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 platformName = await platform();
|
|
const osLocale = await locale();
|
|
|
|
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={{
|
|
storage,
|
|
column: { columns, vlistRef, create, remove, move, update },
|
|
}}
|
|
>
|
|
{children}
|
|
</StorageContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useStorage = () => {
|
|
const context = useContextSelector(StorageContext, (state) => state.storage);
|
|
if (context === undefined) {
|
|
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;
|
|
};
|