Some improments and Negentropy (#219)

* feat: adjust default window size

* feat: save window state

* feat: add window state plugin

* feat: add search

* feat: use negentropy for newsfeed

* feat: live feeds

* feat: add search user
This commit is contained in:
雨宮蓮
2024-06-30 14:26:02 +07:00
committed by GitHub
parent 968b1ada94
commit 0fec21b9ce
46 changed files with 5633 additions and 3938 deletions

View File

@@ -1,8 +1,8 @@
import { LumeWindow, useEvent } from "@lume/system";
import { LinkIcon } from "@lume/icons";
import { cn } from "@lume/utils";
import { User } from "@/components/user";
import { LinkIcon } from "@lume/icons";
import { LumeWindow, useEvent } from "@lume/system";
import { Spinner } from "@lume/ui";
import { cn } from "@lume/utils";
export function MentionNote({
eventId,
@@ -40,7 +40,7 @@ export function MentionNote({
<div className="pl-4 py-3 flex flex-col w-full border-l-2 border-black/5 dark:border-white/5">
<User.Provider pubkey={data.pubkey}>
<User.Root className="flex items-center gap-2 h-8">
<User.Avatar className="object-cover rounded-full size-6 shrink-0" />
<User.Avatar className="rounded-full size-6" />
<div className="inline-flex items-center flex-1 gap-2">
<User.Name className="font-semibold text-neutral-900 dark:text-neutral-100" />
<span className="text-neutral-600 dark:text-neutral-400">·</span>

View File

@@ -96,7 +96,7 @@ export function Images({ urls }: { urls: string[] }) {
}
return (
<div className="relative pl-2 overflow-hidden group">
<div className="relative px-3 overflow-hidden group">
<div ref={emblaRef} className="w-full h-[320px]">
<div className="flex w-full gap-2 scrollbar-none">
{imageUrls.map((url, index) => (

View File

@@ -20,10 +20,11 @@ export function VideoPreview({ url }: { url: string }) {
<div className="my-1">
<video
className="max-h-[600px] w-auto object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15"
preload="metadata"
controls
muted
>
<source src={url} type="video/mp4" />
<source src={`${url}#t=0.1`} type="video/mp4" />
Your browser does not support the video tag.
</video>
</div>

View File

@@ -5,12 +5,12 @@ export function Videos({ urls }: { urls: string[] }) {
return (
<div className="group px-3">
<video
className="w-full h-auto object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15"
className="max-h-[400px] w-auto object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15"
preload="metadata"
controls
muted
>
<source src={urls[0]} type="video/mp4" />
<source src={`${urls[0]}#t=0.1`} type="video/mp4" />
Your browser does not support the video tag.
</video>
</div>
@@ -28,7 +28,7 @@ export function Videos({ urls }: { urls: string[] }) {
controls={false}
muted
>
<source src={item} type="video/mp4" />
<source src={`${item}#t=0.1`} type="video/mp4" />
Your browser does not support the video tag.
</video>
</CarouselItem>

View File

@@ -42,7 +42,7 @@ export function NoteUser({ className }: { className?: string }) {
onClick={(e) => showContextMenu(e)}
className="shrink-0"
>
<User.Avatar className="object-cover rounded-full size-8 outline outline-1 -outline-offset-1 outline-black/15" />
<User.Avatar className="rounded-full size-8" />
</button>
<div className="flex items-center w-full gap-3">
<div className="flex items-center gap-1">

View File

@@ -69,7 +69,7 @@ export const RepostNote = memo(function RepostNote({
<div className="text-sm font-medium text-neutral-800 dark:text-neutral-200">
Reposted by
</div>
<User.Avatar className="object-cover rounded-full size-6 shrink-0 ring-1 ring-neutral-200/50 dark:ring-neutral-800/50" />
<User.Avatar className="rounded-full size-6" />
</User.Root>
</User.Provider>
</div>

View File

@@ -10,8 +10,6 @@ export const TextNote = memo(function TextNote({
event: LumeEvent;
className?: string;
}) {
console.log("Rendered at: ", event.id, new Date().toLocaleTimeString());
return (
<Note.Provider event={event}>
<Note.Root

View File

@@ -2,7 +2,6 @@ import { cn } from "@lume/utils";
import * as Avatar from "@radix-ui/react-avatar";
import { useRouteContext } from "@tanstack/react-router";
import { minidenticon } from "minidenticons";
import { nanoid } from "nanoid";
import { useMemo } from "react";
import { useUserContext } from "./provider";
@@ -22,22 +21,29 @@ export function UserAvatar({ className }: { className?: string }) {
}
}, [user.profile?.picture]);
const fallbackAvatar = useMemo(
const fallback = useMemo(
() =>
`data:image/svg+xml;utf8,${encodeURIComponent(
minidenticon(user.pubkey || nanoid(), 90, 50),
minidenticon(user.pubkey, 60, 50),
)}`,
[user.pubkey],
);
if (settings && !settings.display_avatar) {
return (
<Avatar.Root className="shrink-0">
<Avatar.Root
className={cn(
"shrink-0 block overflow-hidden bg-neutral-200 dark:bg-neutral-800",
className,
)}
>
<Avatar.Fallback delayMs={120}>
<img
src={fallbackAvatar}
src={fallback}
alt={user.pubkey}
className={cn("bg-black dark:bg-white", className)}
loading="lazy"
decoding="async"
className="size-full bg-black dark:bg-white outline-[.5px] outline-black/5 content-visibility-auto contain-intrinsic-size-[auto]"
/>
</Avatar.Fallback>
</Avatar.Root>
@@ -45,19 +51,24 @@ export function UserAvatar({ className }: { className?: string }) {
}
return (
<Avatar.Root className="shrink-0">
<Avatar.Root
className={cn(
"shrink-0 block overflow-hidden bg-neutral-200 dark:bg-neutral-800",
className,
)}
>
<Avatar.Image
src={picture}
alt={user.pubkey}
loading="eager"
loading="lazy"
decoding="async"
className={cn("outline-[.5px] outline-black/5 object-cover", className)}
className="w-full aspect-square object-cover outline-[.5px] outline-black/5 content-visibility-auto contain-intrinsic-size-[auto]"
/>
<Avatar.Fallback delayMs={120}>
<Avatar.Fallback>
<img
src={fallbackAvatar}
src={fallback}
alt={user.pubkey}
className={cn("bg-black dark:bg-white", className)}
className="size-full bg-black dark:bg-white outline-[.5px] outline-black/5 content-visibility-auto contain-intrinsic-size-[auto]"
/>
</Avatar.Fallback>
</Avatar.Root>