From be333260f29dfd11f0ef8edfff41ed96f325ba0d Mon Sep 17 00:00:00 2001 From: reya Date: Fri, 29 Dec 2023 13:12:37 +0700 Subject: [PATCH] refactor(column): use context for manage column --- apps/desktop/package.json | 3 +- apps/desktop/src/routes/home/index.tsx | 54 +++---------- packages/ark/src/components/column/header.tsx | 10 +-- packages/ark/src/components/column/index.ts | 2 + .../ark/src/components/column/provider.tsx | 81 +++++++++++++++++++ .../ark/src/components/note/buttons/pin.tsx | 6 +- .../src/components/note/mentions/hashtag.tsx | 6 +- .../ark/src/components/note/mentions/user.tsx | 6 +- packages/ark/src/hooks/useWidget.ts | 79 ------------------ packages/ark/src/index.ts | 1 - packages/types/index.d.ts | 7 ++ packages/ui/src/layouts/home.tsx | 15 ++-- pnpm-lock.yaml | 31 ------- 13 files changed, 125 insertions(+), 176 deletions(-) create mode 100644 packages/ark/src/components/column/provider.tsx delete mode 100644 packages/ark/src/hooks/useWidget.ts diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 5003f1cf..9455ae81 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -79,8 +79,7 @@ "sonner": "^1.3.1", "tippy.js": "^6.3.7", "tiptap-markdown": "^0.8.8", - "virtua": "^0.18.0", - "zustand": "^4.4.7" + "virtua": "^0.18.0" }, "devDependencies": { "@lume/tailwindcss": "workspace:^", diff --git a/apps/desktop/src/routes/home/index.tsx b/apps/desktop/src/routes/home/index.tsx index 81ae7732..99c0c3c4 100644 --- a/apps/desktop/src/routes/home/index.tsx +++ b/apps/desktop/src/routes/home/index.tsx @@ -1,62 +1,30 @@ import { Thread } from "@columns/thread"; import { Timeline } from "@columns/timeline"; import { User } from "@columns/user"; -import { useStorage } from "@lume/ark"; -import { LoaderIcon } from "@lume/icons"; -import { WidgetProps } from "@lume/types"; +import { useColumnContext } from "@lume/ark"; +import { IColumn } from "@lume/types"; import { WIDGET_KIND } from "@lume/utils"; -import { useQuery } from "@tanstack/react-query"; import { useRef, useState } from "react"; import { VList, VListHandle } from "virtua"; export function HomeScreen() { - const storage = useStorage(); const ref = useRef(null); - - const { isLoading, data } = useQuery({ - queryKey: ["widgets"], - queryFn: async () => { - const dbWidgets = await storage.getWidgets(); - const defaultWidgets = [ - { - id: "9999", - title: "Newsfeed", - content: "", - kind: WIDGET_KIND.newsfeed, - }, - ]; - - return [...defaultWidgets, ...dbWidgets]; - }, - refetchOnMount: false, - refetchOnReconnect: false, - refetchOnWindowFocus: false, - staleTime: Infinity, - }); - + const { columns } = useColumnContext(); const [selectedIndex, setSelectedIndex] = useState(-1); - const renderItem = (widget: WidgetProps) => { - switch (widget.kind) { + const renderItem = (column: IColumn) => { + switch (column.kind) { case WIDGET_KIND.newsfeed: - return ; + return ; case WIDGET_KIND.thread: - return ; + return ; case WIDGET_KIND.user: - return ; + return ; default: - return ; + return ; } }; - if (isLoading) { - return ( -
- -
- ); - } - return (
- {data.map((widget) => renderItem(widget))} + {columns.map((column) => renderItem(column))}
diff --git a/packages/ark/src/components/column/header.tsx b/packages/ark/src/components/column/header.tsx index 4ff83038..75cc7cf4 100644 --- a/packages/ark/src/components/column/header.tsx +++ b/packages/ark/src/components/column/header.tsx @@ -9,7 +9,7 @@ import { import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; import { useQueryClient } from "@tanstack/react-query"; import { ReactNode } from "react"; -import { useWidget } from "../../hooks/useWidget"; +import { useColumnContext } from "./provider"; export function ColumnHeader({ id, @@ -23,22 +23,22 @@ export function ColumnHeader({ icon?: ReactNode; }) { const queryClient = useQueryClient(); - const { removeWidget } = useWidget(); + const { removeColumn } = useColumnContext(); const refresh = async () => { if (queryKey) await queryClient.refetchQueries({ queryKey }); }; const moveLeft = async () => { - removeWidget.mutate(id); + removeColumn(id); }; const moveRight = async () => { - removeWidget.mutate(id); + removeColumn(id); }; const deleteWidget = async () => { - removeWidget.mutate(id); + removeColumn(id); }; return ( diff --git a/packages/ark/src/components/column/index.ts b/packages/ark/src/components/column/index.ts index aecc1b5a..27b11611 100644 --- a/packages/ark/src/components/column/index.ts +++ b/packages/ark/src/components/column/index.ts @@ -11,3 +11,5 @@ export const Column = { Content: ColumnContent, Route: Route, }; + +export * from "./provider"; diff --git a/packages/ark/src/components/column/provider.tsx b/packages/ark/src/components/column/provider.tsx new file mode 100644 index 00000000..6759d587 --- /dev/null +++ b/packages/ark/src/components/column/provider.tsx @@ -0,0 +1,81 @@ +import { IColumn } from "@lume/types"; +import { WIDGET_KIND } from "@lume/utils"; +import { NDKEvent } from "@nostr-dev-kit/ndk"; +import { + ReactNode, + createContext, + useCallback, + useContext, + useEffect, + useState, +} from "react"; +import { useStorage } from "../../provider"; + +type ColumnContext = { + columns: IColumn[]; + addColumn: (column: IColumn) => void; + removeColumn: (id: string) => void; + loadAllColumns: () => void; +}; + +const ColumnContext = createContext(null); + +export function ColumnProvider({ children }: { children: ReactNode }) { + const storage = useStorage(); + const [columns, setColumns] = useState([ + { + id: "9999", + title: "Newsfeed", + content: "", + kind: WIDGET_KIND.newsfeed, + }, + ]); + + const loadAllColumns = useCallback(async () => { + return await storage.getWidgets(); + }, []); + + const addColumn = useCallback(async (column: IColumn) => { + const result = await storage.createWidget( + column.kind, + column.title, + column.content, + ); + if (result) setColumns((prev) => [...prev, column]); + }, []); + + const removeColumn = useCallback(async (id: string) => { + await storage.removeWidget(id); + setColumns((prev) => prev.filter((t) => t.id !== id)); + }, []); + + useEffect(() => { + let isMounted = true; + + loadAllColumns().then((data) => { + if (isMounted) setColumns((prev) => [...prev, ...data]); + }); + + return () => { + isMounted = false; + }; + }, []); + + return ( + + {children} + + ); +} + +export function useColumnContext() { + const context = useContext(ColumnContext); + if (!context) { + throw new Error( + "Please import Column Provider to use useColumnContext() hook", + ); + } + return context; +} diff --git a/packages/ark/src/components/note/buttons/pin.tsx b/packages/ark/src/components/note/buttons/pin.tsx index 00dd6503..139af123 100644 --- a/packages/ark/src/components/note/buttons/pin.tsx +++ b/packages/ark/src/components/note/buttons/pin.tsx @@ -2,11 +2,11 @@ import { PinIcon } from "@lume/icons"; import { WIDGET_KIND } from "@lume/utils"; import * as Tooltip from "@radix-ui/react-tooltip"; import { useNoteContext } from ".."; -import { useWidget } from "../../../hooks/useWidget"; +import { useColumnContext } from "../../column"; export function NotePin() { const event = useNoteContext(); - const { addWidget } = useWidget(); + const { addColumn } = useColumnContext(); return ( @@ -15,7 +15,7 @@ export function NotePin() {