feat: improve ui

This commit is contained in:
2024-02-29 13:02:16 +07:00
parent 09df8672d0
commit cfcb9bc6ed
27 changed files with 408 additions and 344 deletions

View File

@@ -71,7 +71,7 @@ export function RepostNote({
return (
<Note.Root
className={cn(
"mb-3 flex flex-col gap-2 border-b border-neutral-100 pb-3 dark:border-neutral-900",
"mb-5 flex flex-col gap-2 border-b border-neutral-100 pb-5 dark:border-neutral-900",
className,
)}
>
@@ -96,14 +96,13 @@ export function RepostNote({
<div className="size-11 shrink-0" />
<div className="min-w-0 flex-1">
<Note.Content />
<div className="mt-5 flex items-center justify-between">
<Note.Reaction />
<div className="inline-flex items-center gap-4">
<div className="mt-4 flex items-center justify-between">
<div className="-ml-1 inline-flex items-center gap-4">
<Note.Reply />
<Note.Repost />
<Note.Zap />
<Note.Menu />
</div>
<Note.Menu />
</div>
</div>
</div>

View File

@@ -13,7 +13,7 @@ export function TextNote({
<Note.Provider event={event}>
<Note.Root
className={cn(
"mb-3 flex flex-col gap-2 border-b border-neutral-100 pb-3 dark:border-neutral-900",
"mb-5 flex flex-col gap-2 border-b border-neutral-100 pb-5 dark:border-neutral-900",
className,
)}
>
@@ -21,16 +21,15 @@ export function TextNote({
<div className="flex gap-3">
<div className="size-11 shrink-0" />
<div className="min-w-0 flex-1">
<Note.Thread className="mb-2" />
<Note.Content />
<div className="mt-5 flex items-center justify-between">
<Note.Reaction />
<div className="inline-flex items-center gap-4">
<Note.Content className="mb-2" />
<Note.Thread />
<div className="mt-4 flex items-center justify-between">
<div className="-ml-1 inline-flex items-center gap-4">
<Note.Reply />
<Note.Repost />
<Note.Zap />
<Note.Menu />
</div>
<Note.Menu />
</div>
</div>
</div>

View File

@@ -1,9 +1,10 @@
import { useEvent } from "@lume/ark";
import { LoaderIcon } from "@lume/icons";
import { Note, User } from "@lume/ui";
import { Box, Container, Note, User } from "@lume/ui";
import { createLazyFileRoute } from "@tanstack/react-router";
import { WindowVirtualizer } from "virtua";
import { ReplyList } from "./-components/replyList";
import { Event } from "@lume/types";
export const Route = createLazyFileRoute("/events/$eventId")({
component: Event,
@@ -29,45 +30,43 @@ function Event() {
return (
<WindowVirtualizer>
<div className="flex h-screen w-screen flex-col bg-gradient-to-tr from-neutral-200 to-neutral-100 dark:from-neutral-950 dark:to-neutral-900">
<div data-tauri-drag-region className="h-11 w-full shrink-0" />
<div className="flex h-full min-h-0 w-full">
<div className="h-full w-full flex-1 px-2 pb-2">
<div className="h-full w-full overflow-hidden overflow-y-auto rounded-xl bg-white px-3 shadow-[rgba(50,_50,_105,_0.15)_0px_2px_5px_0px,_rgba(0,_0,_0,_0.05)_0px_1px_1px_0px] dark:bg-black dark:shadow-none dark:ring-1 dark:ring-white/5">
<Note.Provider event={data}>
<Note.Root className="flex flex-col">
<div className="mb-2 flex items-center justify-between pt-4">
<User.Provider pubkey={data.pubkey}>
<User.Root className="flex flex-1 items-center gap-3">
<User.Avatar className="size-11 shrink-0 rounded-full object-cover ring-1 ring-neutral-200/50 dark:ring-neutral-800/50" />
<div className="flex flex-1 flex-col">
<User.Name className="font-semibold text-neutral-900 dark:text-neutral-100" />
<div className="inline-flex items-center gap-2 text-sm text-neutral-600 dark:text-neutral-400">
<User.Time time={data.created_at} />
<span>·</span>
<User.NIP05 />
</div>
</div>
</User.Root>
</User.Provider>
<Note.Menu />
</div>
<Note.Thread className="mb-2" />
<Note.Content className="min-w-0" />
<div className="flex h-14 items-center justify-between">
<Note.Reaction />
<div className="inline-flex items-center gap-4">
<Note.Repost />
<Note.Zap />
</div>
</div>
</Note.Root>
</Note.Provider>
{data ? <ReplyList eventId={eventId} /> : null}
</div>
</div>
</div>
</div>
<Container withDrag>
<Box>
<MainNote data={data} />
{data ? <ReplyList eventId={eventId} /> : null}
</Box>
</Container>
</WindowVirtualizer>
);
}
function MainNote({ data }: { data: Event }) {
return (
<Note.Provider event={data}>
<Note.Root className="flex flex-col pb-3">
<User.Provider pubkey={data.pubkey}>
<User.Root className="mb-3 flex flex-1 items-center gap-3">
<User.Avatar className="size-11 shrink-0 rounded-full object-cover ring-1 ring-neutral-200/50 dark:ring-neutral-800/50" />
<div className="flex flex-1 flex-col">
<User.Name className="font-semibold text-neutral-900 dark:text-neutral-100" />
<div className="inline-flex items-center gap-2 text-sm text-neutral-600 dark:text-neutral-400">
<User.Time time={data.created_at} />
<span>·</span>
<User.NIP05 />
</div>
</div>
</User.Root>
</User.Provider>
<Note.Thread className="mb-2" />
<Note.Content className="min-w-0" />
<div className="mt-4 flex items-center justify-between">
<div className="-ml-1 inline-flex items-center gap-4">
<Note.Repost />
<Note.Zap />
</div>
<Note.Menu />
</div>
</Note.Root>
</Note.Provider>
);
}

View File

@@ -1,65 +1,47 @@
import { NavArrowDownIcon } from "@lume/icons";
import { EventWithReplies } from "@lume/types";
import { cn } from "@lume/utils";
import * as Collapsible from "@radix-ui/react-collapsible";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Note } from "@lume/ui";
import { Note, User } from "@lume/ui";
import { SubReply } from "./subReply";
export function Reply({ event }: { event: EventWithReplies }) {
const [t] = useTranslation();
const [open, setOpen] = useState(false);
return (
<Collapsible.Root open={open} onOpenChange={setOpen}>
<Note.Provider event={event}>
<Note.Root className="pt-2">
<div className="flex h-14 items-center justify-between">
<Note.User className="flex-1 pr-2" />
<Note.Menu />
</div>
<Note.Content />
<div className="flex h-14 items-center justify-between">
{event.replies?.length > 0 ? (
<Collapsible.Trigger asChild>
<div className="inline-flex h-14 items-center gap-1 text-sm font-semibold text-neutral-600 dark:text-neutral-400">
<NavArrowDownIcon
className={cn("size-5", open ? "rotate-180 transform" : "")}
/>
{`${event.replies?.length} ${
event.replies?.length === 1
? t("note.reply.single")
: t("note.reply.plural")
}`}
</div>
</Collapsible.Trigger>
) : (
<div />
)}
<div className="inline-flex items-center gap-4">
<Note.Reply />
<Note.Repost />
<Note.Zap />
<Note.Provider event={event}>
<Note.Root className="border-t border-neutral-100 pt-3 dark:border-neutral-900">
<User.Provider pubkey={event.pubkey}>
<User.Root className="mb-2 flex items-center justify-between">
<div className="inline-flex gap-2">
<User.Avatar className="size-6 rounded-full" />
<div className="inline-flex items-center gap-2">
<User.Name className="font-semibold" />
<User.NIP05 className="text-base lowercase text-neutral-600 dark:text-neutral-400" />
</div>
</div>
<User.Time time={event.created_at} />
</User.Root>
</User.Provider>
<Note.Content />
<div className="mt-4 flex items-center justify-between">
<div className="-ml-1 inline-flex items-center gap-4">
<Note.Reply />
<Note.Repost />
<Note.Zap />
</div>
<div
className={cn(
open
? "border-t border-neutral-100 pb-3 dark:border-neutral-900"
: "",
)}
>
{event.replies?.length > 0 ? (
<Collapsible.Content className="divide-y divide-neutral-100 pl-6 dark:divide-neutral-900">
{event.replies?.map((childEvent) => (
<SubReply key={childEvent.id} event={childEvent} />
))}
</Collapsible.Content>
) : null}
</div>
</Note.Root>
</Note.Provider>
</Collapsible.Root>
<Note.Menu />
</div>
<div
className={cn(
event.replies?.length > 0
? "my-3 mt-6 flex flex-col gap-3 divide-y divide-neutral-100 border-l-2 border-neutral-100 pl-6 dark:divide-neutral-900 dark:border-neutral-900"
: "",
)}
>
{event.replies?.length > 0
? event.replies?.map((childEvent) => (
<SubReply key={childEvent.id} event={childEvent} />
))
: null}
</div>
</Note.Root>
</Note.Provider>
);
}

View File

@@ -27,12 +27,7 @@ export function ReplyList({
}, [eventId]);
return (
<div
className={cn(
"flex flex-col divide-y divide-neutral-100 dark:divide-neutral-900",
className,
)}
>
<div className={cn("flex flex-col gap-3", className)}>
{!data ? (
<div className="mt-4 flex h-16 items-center justify-center p-3">
<LoaderIcon className="h-5 w-5 animate-spin" />

View File

@@ -1,18 +1,30 @@
import { Event } from "@lume/types";
import { Note } from "@lume/ui";
import { Note, User } from "@lume/ui";
export function SubReply({ event }: { event: Event; rootEventId?: string }) {
return (
<Note.Provider event={event}>
<Note.Root className="py-2">
<div className="flex h-14 items-center justify-between">
<Note.User className="flex-1 pr-2" />
<Note.Menu />
</div>
<Note.Root className="pt-3">
<User.Provider pubkey={event.pubkey}>
<User.Root className="mb-2 flex items-center justify-between">
<div className="inline-flex gap-2">
<User.Avatar className="size-6 rounded-full" />
<div className="inline-flex items-center gap-2">
<User.Name className="font-semibold" />
<User.NIP05 className="text-base lowercase text-neutral-600 dark:text-neutral-400" />
</div>
</div>
<User.Time time={event.created_at} />
</User.Root>
</User.Provider>
<Note.Content />
<div className="mt-2 flex items-center justify-end gap-4">
<Note.Repost />
<Note.Zap />
<div className="mt-4 flex items-center justify-between">
<div className="-ml-1 inline-flex items-center gap-4">
<Note.Reply />
<Note.Repost />
<Note.Zap />
</div>
<Note.Menu />
</div>
</Note.Root>
</Note.Provider>