final design (#184)
* feat: redesign * feat: update other columns to new design * chore: small fixes * fix: better manage external webview * feat: redesign note * feat: update ui * chore: update * chore: update * chore: polish ui * chore: update auth ui * feat: finalize note design * chore: small fixes * feat: add window management in rust * chore: format * feat: update ui for event screen * feat: update event screen * feat: final
This commit is contained in:
@@ -1,66 +1,60 @@
|
||||
import { RepostNote } from "@/components/repost";
|
||||
import { TextNote } from "@/components/text";
|
||||
import { Event, Kind } from "@lume/types";
|
||||
import { type Event, Kind } from "@lume/types";
|
||||
import { Spinner } from "@lume/ui";
|
||||
import { Await, createFileRoute } from "@tanstack/react-router";
|
||||
import { Virtualizer } from "virtua";
|
||||
import { defer } from "@tanstack/react-router";
|
||||
import { Suspense } from "react";
|
||||
import { Spinner } from "@lume/ui";
|
||||
import { Virtualizer } from "virtua";
|
||||
|
||||
export const Route = createFileRoute("/trending/notes")({
|
||||
loader: async ({ abortController }) => {
|
||||
try {
|
||||
return {
|
||||
data: defer(
|
||||
fetch("https://api.nostr.band/v0/trending/notes", {
|
||||
signal: abortController.signal,
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((res) => res.notes.map((item) => item.event) as Event[]),
|
||||
),
|
||||
};
|
||||
} catch (e) {
|
||||
throw new Error(String(e));
|
||||
}
|
||||
},
|
||||
component: Screen,
|
||||
loader: async ({ abortController }) => {
|
||||
try {
|
||||
return {
|
||||
data: defer(
|
||||
fetch("https://api.nostr.band/v0/trending/notes", {
|
||||
signal: abortController.signal,
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((res) => res.notes.map((item) => item.event) as Event[]),
|
||||
),
|
||||
};
|
||||
} catch (e) {
|
||||
throw new Error(String(e));
|
||||
}
|
||||
},
|
||||
component: Screen,
|
||||
});
|
||||
|
||||
export function Screen() {
|
||||
const { data } = Route.useLoaderData();
|
||||
const { data } = Route.useLoaderData();
|
||||
|
||||
const renderItem = (event: Event) => {
|
||||
if (!event) return;
|
||||
switch (event.kind) {
|
||||
case Kind.Repost:
|
||||
return <RepostNote key={event.id} event={event} />;
|
||||
default:
|
||||
return <TextNote key={event.id} event={event} />;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full h-full">
|
||||
<Virtualizer overscan={3}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="flex h-20 w-full flex-col items-center justify-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex items-center gap-2 text-sm font-medium"
|
||||
disabled
|
||||
>
|
||||
<Spinner className="size-5" />
|
||||
Loading...
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Await promise={data}>
|
||||
{(notes) => notes.map((event) => renderItem(event))}
|
||||
</Await>
|
||||
</Suspense>
|
||||
</Virtualizer>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="w-full h-full">
|
||||
<Virtualizer overscan={3}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="flex h-20 w-full flex-col items-center justify-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex items-center gap-2 text-sm font-medium"
|
||||
disabled
|
||||
>
|
||||
<Spinner className="size-5" />
|
||||
Loading...
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Await promise={data}>
|
||||
{(notes) =>
|
||||
notes.map((event) => (
|
||||
<TextNote key={event.id} event={event} className="mb-3" />
|
||||
))
|
||||
}
|
||||
</Await>
|
||||
</Suspense>
|
||||
</Virtualizer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user