mirror of
https://github.com/lumehq/lume.git
synced 2025-10-04 18:02:36 +02:00
move space logic to zustand
This commit is contained in:
@@ -7,7 +7,7 @@ import { Fragment, useState } from "react";
|
|||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
|
||||||
export function AddFeedBlock({ parentState }: { parentState: any }) {
|
export function AddFeedBlock({ parentState }: { parentState: any }) {
|
||||||
const account = useActiveAccount((state: any) => state.account);
|
const addBlock = useActiveAccount((state: any) => state.addBlock);
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [isOpen, setIsOpen] = useState(true);
|
const [isOpen, setIsOpen] = useState(true);
|
||||||
@@ -36,7 +36,7 @@ export function AddFeedBlock({ parentState }: { parentState: any }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// insert to database
|
// insert to database
|
||||||
createBlock(account.id, 1, data.title, pubkey);
|
addBlock(1, data.title, pubkey);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
@@ -8,14 +8,16 @@ import { open } from "@tauri-apps/api/dialog";
|
|||||||
import { Body, fetch } from "@tauri-apps/api/http";
|
import { Body, fetch } from "@tauri-apps/api/http";
|
||||||
import { createBlobFromFile } from "@utils/createBlobFromFile";
|
import { createBlobFromFile } from "@utils/createBlobFromFile";
|
||||||
import { dateToUnix } from "@utils/date";
|
import { dateToUnix } from "@utils/date";
|
||||||
import { createBlock } from "@utils/storage";
|
|
||||||
import { getEventHash, getSignature } from "nostr-tools";
|
import { getEventHash, getSignature } from "nostr-tools";
|
||||||
import { Fragment, useContext, useEffect, useRef, useState } from "react";
|
import { Fragment, useContext, useEffect, useRef, useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
|
||||||
export function AddImageBlock({ parentState }: { parentState: any }) {
|
export function AddImageBlock({ parentState }: { parentState: any }) {
|
||||||
const pool: any = useContext(RelayContext);
|
const pool: any = useContext(RelayContext);
|
||||||
const account = useActiveAccount((state: any) => state.account);
|
const [account, addBlock] = useActiveAccount((state: any) => [
|
||||||
|
state.account,
|
||||||
|
state.addBlock,
|
||||||
|
]);
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [isOpen, setIsOpen] = useState(true);
|
const [isOpen, setIsOpen] = useState(true);
|
||||||
@@ -97,8 +99,6 @@ export function AddImageBlock({ parentState }: { parentState: any }) {
|
|||||||
tags: tags.current,
|
tags: tags.current,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(event);
|
|
||||||
|
|
||||||
event.id = getEventHash(event);
|
event.id = getEventHash(event);
|
||||||
event.sig = getSignature(event, account.privkey);
|
event.sig = getSignature(event, account.privkey);
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ export function AddImageBlock({ parentState }: { parentState: any }) {
|
|||||||
pool.publish(event, WRITEONLY_RELAYS);
|
pool.publish(event, WRITEONLY_RELAYS);
|
||||||
|
|
||||||
// insert to database
|
// insert to database
|
||||||
createBlock(account.id, 0, data.title, data.content);
|
addBlock(0, data.title, data.content);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
import { NoteBase } from "@app/note/components/base";
|
import { NoteBase } from "@app/note/components/base";
|
||||||
import { NoteQuoteRepost } from "@app/note/components/quoteRepost";
|
import { NoteQuoteRepost } from "@app/note/components/quoteRepost";
|
||||||
import { NoteSkeleton } from "@app/note/components/skeleton";
|
import { NoteSkeleton } from "@app/note/components/skeleton";
|
||||||
|
import { CancelIcon } from "@shared/icons";
|
||||||
|
import { useActiveAccount } from "@stores/accounts";
|
||||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||||
import { useVirtualizer } from "@tanstack/react-virtual";
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
||||||
import { getNotesByAuthor } from "@utils/storage";
|
import { getNotesByAuthor } from "@utils/storage";
|
||||||
@@ -10,6 +12,8 @@ const ITEM_PER_PAGE = 10;
|
|||||||
const TIME = Math.floor(Date.now() / 1000);
|
const TIME = Math.floor(Date.now() / 1000);
|
||||||
|
|
||||||
export function FeedBlock({ params }: { params: any }) {
|
export function FeedBlock({ params }: { params: any }) {
|
||||||
|
const removeBlock = useActiveAccount((state: any) => state.removeBlock);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
status,
|
status,
|
||||||
data,
|
data,
|
||||||
@@ -58,13 +62,25 @@ export function FeedBlock({ params }: { params: any }) {
|
|||||||
}
|
}
|
||||||
}, [fetchNextPage, allRows.length, rowVirtualizer.getVirtualItems()]);
|
}, [fetchNextPage, allRows.length, rowVirtualizer.getVirtualItems()]);
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
removeBlock(params.id);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="shrink-0 w-[420px] border-r border-zinc-900">
|
<div className="shrink-0 w-[420px] border-r border-zinc-900">
|
||||||
<div
|
<div
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
className="h-11 w-full inline-flex items-center justify-center border-b border-zinc-900"
|
className="h-11 w-full flex items-center justify-between px-3 border-b border-zinc-900"
|
||||||
>
|
>
|
||||||
|
<div className="w-9 h-6" />
|
||||||
<h3 className="font-semibold text-zinc-100">{params.title}</h3>
|
<h3 className="font-semibold text-zinc-100">{params.title}</h3>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => close()}
|
||||||
|
className="inline-flex h-6 w-9 shrink items-center justify-center rounded bg-zinc-900 group-hover:bg-zinc-800"
|
||||||
|
>
|
||||||
|
<CancelIcon width={14} height={14} className="text-zinc-500" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
ref={parentRef}
|
ref={parentRef}
|
||||||
|
@@ -1,13 +1,29 @@
|
|||||||
|
import { CancelIcon } from "@shared/icons";
|
||||||
import { Image } from "@shared/image";
|
import { Image } from "@shared/image";
|
||||||
|
import { useActiveAccount } from "@stores/accounts";
|
||||||
|
|
||||||
export function ImageBlock({ params }: { params: any }) {
|
export function ImageBlock({ params }: { params: any }) {
|
||||||
|
const removeBlock = useActiveAccount((state: any) => state.removeBlock);
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
removeBlock(params.id);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="shrink-0 w-[360px] flex-col flex border-r border-zinc-900">
|
<div className="shrink-0 w-[360px] flex-col flex border-r border-zinc-900">
|
||||||
<div
|
<div
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
className="h-11 w-full inline-flex items-center justify-center border-b border-zinc-900"
|
className="h-11 w-full flex items-center justify-between px-3 border-b border-zinc-900"
|
||||||
>
|
>
|
||||||
|
<div className="w-9 h-6" />
|
||||||
<h3 className="font-semibold text-zinc-100">{params.title}</h3>
|
<h3 className="font-semibold text-zinc-100">{params.title}</h3>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => close()}
|
||||||
|
className="inline-flex h-6 w-9 shrink items-center justify-center rounded bg-zinc-900 group-hover:bg-zinc-800"
|
||||||
|
>
|
||||||
|
<CancelIcon width={14} height={14} className="text-zinc-500" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex-1 p-3">
|
<div className="w-full flex-1 p-3">
|
||||||
<Image
|
<Image
|
||||||
|
@@ -3,23 +3,22 @@ import { FeedBlock } from "@app/space/components/blocks/feed";
|
|||||||
import { FollowingBlock } from "@app/space/components/blocks/following";
|
import { FollowingBlock } from "@app/space/components/blocks/following";
|
||||||
import { ImageBlock } from "@app/space/components/blocks/image";
|
import { ImageBlock } from "@app/space/components/blocks/image";
|
||||||
import { useActiveAccount } from "@stores/accounts";
|
import { useActiveAccount } from "@stores/accounts";
|
||||||
import { getBlocks } from "@utils/storage";
|
import { useEffect } from "react";
|
||||||
import useSWR from "swr";
|
|
||||||
|
|
||||||
const fetcher = ([, id]) => getBlocks(id);
|
|
||||||
|
|
||||||
export function Page() {
|
export function Page() {
|
||||||
const account = useActiveAccount((state: any) => state.account);
|
const blocks = useActiveAccount((state: any) => state.blocks);
|
||||||
const { data }: any = useSWR(
|
const fetchBlocks = useActiveAccount((state: any) => state.fetchBlocks);
|
||||||
account ? ["blocks", account.id] : null,
|
|
||||||
fetcher,
|
useEffect(() => {
|
||||||
);
|
if (blocks !== null) return;
|
||||||
|
fetchBlocks();
|
||||||
|
}, [fetchBlocks]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full w-full flex flex-nowrap overflow-x-auto overflow-y-hidden scrollbar-hide">
|
<div className="h-full w-full flex flex-nowrap overflow-x-auto overflow-y-hidden scrollbar-hide">
|
||||||
<FollowingBlock />
|
<FollowingBlock />
|
||||||
{data
|
{blocks
|
||||||
? data.map((block: any) =>
|
? blocks.map((block: any) =>
|
||||||
block.kind === 0 ? (
|
block.kind === 0 ? (
|
||||||
<ImageBlock key={block.id} params={block} />
|
<ImageBlock key={block.id} params={block} />
|
||||||
) : (
|
) : (
|
||||||
|
@@ -1,27 +1,75 @@
|
|||||||
import { getActiveAccount, getLastLogin } from "@utils/storage";
|
import {
|
||||||
|
addBlockToDB,
|
||||||
|
getActiveAccount,
|
||||||
|
getBlocks,
|
||||||
|
getLastLogin,
|
||||||
|
removeBlockFromDB,
|
||||||
|
} from "@utils/storage";
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { createJSONStorage, persist } from "zustand/middleware";
|
import { createJSONStorage, persist } from "zustand/middleware";
|
||||||
|
import { immer } from "zustand/middleware/immer";
|
||||||
|
|
||||||
export const useActiveAccount = create(
|
export const useActiveAccount = create(
|
||||||
persist(
|
immer(
|
||||||
(set) => ({
|
persist(
|
||||||
account: null,
|
(set: any, get: any) => ({
|
||||||
lastLogin: 0,
|
account: null,
|
||||||
fetch: async () => {
|
blocks: null,
|
||||||
const response = await getActiveAccount();
|
lastLogin: 0,
|
||||||
set({ account: response });
|
fetch: async () => {
|
||||||
|
const response = await getActiveAccount();
|
||||||
|
set({ account: response });
|
||||||
|
},
|
||||||
|
fetchLastLogin: async () => {
|
||||||
|
const response = await getLastLogin();
|
||||||
|
set({ lastLogin: parseInt(response) });
|
||||||
|
},
|
||||||
|
fetchBlocks: async () => {
|
||||||
|
const account = get().account;
|
||||||
|
const response = await getBlocks(account.id);
|
||||||
|
set({ blocks: response });
|
||||||
|
},
|
||||||
|
addBlock: (kind: number, title: string, content: string) => {
|
||||||
|
const account = get().account;
|
||||||
|
// add to db
|
||||||
|
addBlockToDB(account.id, kind, title, content);
|
||||||
|
// update state
|
||||||
|
set((state: any) => ({
|
||||||
|
blocks: [
|
||||||
|
...state.blocks,
|
||||||
|
{
|
||||||
|
id: account.id + kind,
|
||||||
|
account_id: account.id,
|
||||||
|
kind,
|
||||||
|
title,
|
||||||
|
content,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
removeBlock: (id: string) => {
|
||||||
|
// remove from db
|
||||||
|
removeBlockFromDB(id);
|
||||||
|
// update state
|
||||||
|
set((state: any) => {
|
||||||
|
const target = state.blocks.findIndex(
|
||||||
|
(b: { id: string }) => b.id === id,
|
||||||
|
);
|
||||||
|
if (target) {
|
||||||
|
state.blocks.splice(target, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateFollows: (list: any) => {
|
||||||
|
set((state: any) => ({
|
||||||
|
account: { ...state.account, follows: list },
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: "account",
|
||||||
|
storage: createJSONStorage(() => sessionStorage),
|
||||||
},
|
},
|
||||||
fetchLastLogin: async () => {
|
),
|
||||||
const response = await getLastLogin();
|
|
||||||
set({ lastLogin: parseInt(response) });
|
|
||||||
},
|
|
||||||
updateFollows: (list: any) => {
|
|
||||||
set((state: any) => ({ account: { ...state.account, follows: list } }));
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
name: "account",
|
|
||||||
storage: createJSONStorage(() => sessionStorage),
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@@ -3,7 +3,7 @@ import { create } from "zustand";
|
|||||||
import { immer } from "zustand/middleware/immer";
|
import { immer } from "zustand/middleware/immer";
|
||||||
|
|
||||||
export const useChats = create(
|
export const useChats = create(
|
||||||
immer((set: any, get: any) => ({
|
immer((set: any) => ({
|
||||||
chats: [],
|
chats: [],
|
||||||
fetch: async (pubkey: string) => {
|
fetch: async (pubkey: string) => {
|
||||||
const response: any = await getChatsByPubkey(pubkey);
|
const response: any = await getChatsByPubkey(pubkey);
|
||||||
|
@@ -386,7 +386,7 @@ export async function getBlocks(account_id: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create block
|
// create block
|
||||||
export async function createBlock(
|
export async function addBlockToDB(
|
||||||
account_id: number,
|
account_id: number,
|
||||||
kind: number,
|
kind: number,
|
||||||
title: string,
|
title: string,
|
||||||
@@ -398,3 +398,8 @@ export async function createBlock(
|
|||||||
[account_id, kind, title, content],
|
[account_id, kind, title, content],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function removeBlockFromDB(id: string) {
|
||||||
|
const db = await connect();
|
||||||
|
return await db.execute(`DELETE FROM blocks WHERE id = "${id}";`);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user