import { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from "@/components"; import { Column } from "@/components/column"; import { Toolbar } from "@/components/toolbar"; import { NostrQuery } from "@/system"; import type { ColumnEvent, LumeColumn } from "@/types"; import { createLazyFileRoute } from "@tanstack/react-router"; import { listen } from "@tauri-apps/api/event"; import { getCurrentWindow } from "@tauri-apps/api/window"; import useEmblaCarousel from "embla-carousel-react"; import { nanoid } from "nanoid"; import { useCallback, useEffect, useState } from "react"; import { useDebouncedCallback } from "use-debounce"; export const Route = createLazyFileRoute("/$account/home")({ component: Screen, }); function Screen() { const { account } = Route.useParams(); const initialColumnList = Route.useLoaderData(); const [columns, setColumns] = useState([]); const [emblaRef, emblaApi] = useEmblaCarousel({ watchDrag: false, loop: false, }); const scrollPrev = useCallback(() => { if (emblaApi) emblaApi.scrollPrev(); }, [emblaApi]); const scrollNext = useCallback(() => { if (emblaApi) emblaApi.scrollNext(); }, [emblaApi]); const emitScrollEvent = useCallback(() => { getCurrentWindow().emit("child_webview", { scroll: true }); }, []); const emitResizeEvent = useCallback(() => { getCurrentWindow().emit("child_webview", { resize: true, direction: "x" }); }, []); const openLumeStore = useCallback(async () => { await getCurrentWindow().emit("columns", { type: "add", column: { label: "store", name: "Column Gallery", content: "/store", }, }); }, []); const add = useDebouncedCallback((column: LumeColumn) => { column.label = `${column.label}-${nanoid()}`; // update col label setColumns((prev) => [column, ...prev]); }, 150); const remove = useDebouncedCallback((label: string) => { setColumns((prev) => prev.filter((t) => t.label !== label)); }, 150); const move = useDebouncedCallback( (label: string, direction: "left" | "right") => { const newCols = [...columns]; const col = newCols.find((el) => el.label === label); const colIndex = newCols.findIndex((el) => el.label === label); newCols.splice(colIndex, 1); if (direction === "left") newCols.splice(colIndex - 1, 0, col); if (direction === "right") newCols.splice(colIndex + 1, 0, col); setColumns(newCols); }, 150, ); const updateName = useDebouncedCallback((label: string, title: string) => { const currentColIndex = columns.findIndex((col) => col.label === label); const updatedCol = Object.assign({}, columns[currentColIndex]); updatedCol.name = title; const newCols = columns.slice(); newCols[currentColIndex] = updatedCol; setColumns(newCols); }, 150); const reset = useDebouncedCallback(() => setColumns([]), 150); const handleKeyDown = useDebouncedCallback((event) => { if (event.defaultPrevented) return; switch (event.code) { case "ArrowLeft": if (emblaApi) emblaApi.scrollPrev(); break; case "ArrowRight": if (emblaApi) emblaApi.scrollNext(); break; default: break; } event.preventDefault(); }, 150); useEffect(() => { if (emblaApi) { emblaApi.on("scroll", emitScrollEvent); emblaApi.on("resize", emitResizeEvent); emblaApi.on("slidesChanged", emitScrollEvent); } return () => { emblaApi?.off("scroll", emitScrollEvent); emblaApi?.off("resize", emitResizeEvent); emblaApi?.off("slidesChanged", emitScrollEvent); }; }, [emblaApi, emitScrollEvent, emitResizeEvent]); useEffect(() => { if (columns?.length) { NostrQuery.setColumns(columns).then(() => console.log("saved")); } }, [columns]); useEffect(() => { setColumns(initialColumnList); }, [initialColumnList]); // Listen for keyboard event useEffect(() => { window.addEventListener("keydown", handleKeyDown); return () => { window.removeEventListener("keydown", handleKeyDown); }; }, [handleKeyDown]); // Listen for columns event useEffect(() => { const unlisten = listen("columns", (data) => { if (data.payload.type === "reset") reset(); if (data.payload.type === "add") add(data.payload.column); if (data.payload.type === "remove") remove(data.payload.label); if (data.payload.type === "move") move(data.payload.label, data.payload.direction); if (data.payload.type === "set_title") updateName(data.payload.label, data.payload.title); }); return () => { unlisten.then((f) => f()); }; }, []); return (
{columns?.map((column) => ( ))}
); }