feat: improve performance

This commit is contained in:
reya
2024-08-04 09:34:02 +07:00
parent b075e374b1
commit 35620fb1a9
8 changed files with 144 additions and 152 deletions

View File

@@ -235,17 +235,15 @@ function List() {
>
{isLoading ? (
<>
<div className="flex items-center justify-between gap-3 my-1.5 px-3">
<div className="flex items-center gap-3 my-1.5 px-3">
<div className="flex-1 min-w-0 inline-flex">
<div className="w-44 h-[35px] py-2 max-w-[400px] bg-neutral-100 dark:bg-neutral-800 animate-pulse rounded-tl-3xl rounded-tr-3xl rounded-br-3xl rounded-bl-md" />
</div>
<div className="shrink-0 w-16 flex items-center justify-end" />
</div>
<div className="flex items-center justify-between gap-3 my-1.5 px-3">
<div className="flex items-center gap-3 my-1.5 px-3">
<div className="flex-1 min-w-0 inline-flex justify-end">
<div className="w-44 h-[35px] py-2 max-w-[400px] bg-blue-500 text-white animate-pulse rounded-tl-3xl rounded-tr-3xl rounded-br-md rounded-bl-3xl" />
</div>
<div className="shrink-0 w-16 flex items-center justify-end" />
</div>
</>
) : isError ? (

View File

@@ -10,6 +10,7 @@ import {
X,
} from "@phosphor-icons/react";
import * as Dialog from "@radix-ui/react-dialog";
import * as Progress from "@radix-ui/react-progress";
import * as ScrollArea from "@radix-ui/react-scroll-area";
import { useQuery } from "@tanstack/react-query";
import { Link, Outlet, createLazyFileRoute } from "@tanstack/react-router";
@@ -19,10 +20,6 @@ import { message } from "@tauri-apps/plugin-dialog";
import type { NostrEvent } from "nostr-tools";
import { useCallback, useEffect, useState, useTransition } from "react";
type ChatPayload = {
events: string[];
};
type EventPayload = {
event: string;
sender: string;
@@ -98,21 +95,21 @@ function ChatList() {
refetchOnWindowFocus: false,
});
useEffect(() => {
const unlisten = listen<ChatPayload>("sync_chat", async (data) => {
const raw = data.payload.events;
const events: NostrEvent[] = raw.map((item) => JSON.parse(item));
const chats: NostrEvent[] = await queryClient.getQueryData(["chats"]);
const [isSync, setIsSync] = useState(false);
const [progress, setProgress] = useState(0);
if (chats?.length) {
const newEvents = [...events, ...chats];
const uniqs = [
...new Map(newEvents.map((item) => [item.pubkey, item])).values(),
];
await queryClient.setQueryData(["chats"], uniqs);
} else {
await queryClient.setQueryData(["chats"], events);
}
useEffect(() => {
const timer = setInterval(
() => setProgress((prev) => (prev <= 100 ? prev + 4 : 100)),
1200,
);
return () => clearInterval(timer);
}, []);
useEffect(() => {
const unlisten = listen("synchronized", async () => {
await queryClient.refetchQueries({ queryKey: ["chats"] });
setIsSync(true);
});
return () => {
@@ -158,11 +155,11 @@ function ChatList() {
<ScrollArea.Root
type={"scroll"}
scrollHideDelay={300}
className="overflow-hidden flex-1 w-full"
className="relative overflow-hidden flex-1 w-full"
>
<ScrollArea.Viewport className="relative h-full px-1.5">
{isLoading || !data.length ? (
<div>
{isLoading || !isSync ? (
<>
{[...Array(5).keys()].map((i) => (
<div
key={i}
@@ -172,8 +169,8 @@ function ChatList() {
<div className="size-4 w-20 rounded animate-pulse bg-black/10 dark:bg-white/10" />
</div>
))}
</div>
) : !data?.length ? (
</>
) : isSync && !data.length ? (
<div className="p-2">
<div className="px-2 h-12 w-full rounded-lg bg-black/5 dark:bg-white/5 flex items-center justify-center text-sm">
No chats.
@@ -213,6 +210,25 @@ function ChatList() {
))
)}
</ScrollArea.Viewport>
{!isSync ? (
<div className="absolute bottom-0 w-full p-4">
<div className="flex flex-col items-center gap-1.5">
<Progress.Root
className="relative overflow-hidden bg-black/20 dark:bg-white/20 rounded-full w-full h-1"
style={{
transform: "translateZ(0)",
}}
value={progress}
>
<Progress.Indicator
className="bg-blue-500 size-full transition-transform duration-[660ms] ease-[cubic-bezier(0.65, 0, 0.35, 1)]"
style={{ transform: `translateX(-${100 - progress}%)` }}
/>
</Progress.Root>
<span className="text-center text-xs">Syncing message...</span>
</div>
</div>
) : null}
<ScrollArea.Scrollbar
className="flex select-none touch-none p-0.5 duration-[160ms] ease-out data-[orientation=vertical]:w-2"
orientation="vertical"