feat: re-add trending column
This commit is contained in:
@@ -21,10 +21,10 @@ function Screen() {
|
|||||||
<div className="mx-auto flex w-full max-w-4xl flex-col items-center gap-10">
|
<div className="mx-auto flex w-full max-w-4xl flex-col items-center gap-10">
|
||||||
<div className="flex flex-col items-center text-center">
|
<div className="flex flex-col items-center text-center">
|
||||||
<img
|
<img
|
||||||
src={`/heading-${context.locale}.png`}
|
src={`/heading-en.png`}
|
||||||
srcSet={`/heading-${context.locale}@2x.png 2x`}
|
srcSet={`/heading-en@2x.png 2x`}
|
||||||
alt="lume"
|
alt="lume"
|
||||||
className="w-3/4 xl:w-2/3"
|
className="xl:w-2/3"
|
||||||
/>
|
/>
|
||||||
<p className="mt-4 whitespace-pre-line text-lg font-medium leading-snug text-white/70">
|
<p className="mt-4 whitespace-pre-line text-lg font-medium leading-snug text-white/70">
|
||||||
{t("welcome.title")}
|
{t("welcome.title")}
|
||||||
@@ -62,7 +62,7 @@ function Screen() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex h-11 items-center justify-center"></div>
|
<div className="flex h-11 items-center justify-center"></div>
|
||||||
</div>
|
</div>
|
||||||
<div className="absolute z-10 h-full w-full bg-white/5 backdrop-blur-sm dark:bg-black/5" />
|
<div className="absolute z-10 h-full w-full bg-black/5 backdrop-blur-sm" />
|
||||||
<div className="absolute inset-0 h-full w-full">
|
<div className="absolute inset-0 h-full w-full">
|
||||||
<img
|
<img
|
||||||
src="/lock-screen.jpg"
|
src="/lock-screen.jpg"
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { RepostNote } from "@/components/repost";
|
import { RepostNote } from "@/components/repost";
|
||||||
import { Suggest } from "@/components/suggest";
|
import { Suggest } from "@/components/suggest";
|
||||||
import { TextNote } from "@/components/text";
|
import { TextNote } from "@/components/text";
|
||||||
import { useEvents } from "@lume/ark";
|
import { LoaderIcon, InfoIcon } from "@lume/icons";
|
||||||
import { LoaderIcon, ArrowRightCircleIcon, InfoIcon } from "@lume/icons";
|
|
||||||
import { Event, Kind } from "@lume/types";
|
import { Event, Kind } from "@lume/types";
|
||||||
import { Column } from "@lume/ui";
|
import { Column } from "@lume/ui";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Virtualizer } from "virtua";
|
import { Virtualizer } from "virtua";
|
||||||
|
import { fetch } from "@tauri-apps/plugin-http";
|
||||||
|
|
||||||
export const Route = createLazyFileRoute("/trending")({
|
export const Route = createLazyFileRoute("/trending")({
|
||||||
component: Screen,
|
component: Screen,
|
||||||
@@ -17,14 +18,16 @@ export function Screen() {
|
|||||||
// @ts-ignore, just work!!!
|
// @ts-ignore, just work!!!
|
||||||
const { id, name, account } = Route.useSearch();
|
const { id, name, account } = Route.useSearch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const {
|
const { data, isLoading } = useQuery({
|
||||||
data,
|
queryKey: ["trending", account],
|
||||||
hasNextPage,
|
queryFn: async () => {
|
||||||
isLoading,
|
const res = await fetch("https://api.nostr.band/v0/trending/notes");
|
||||||
isRefetching,
|
const data = await res.json();
|
||||||
isFetchingNextPage,
|
const events = data.notes.map((item) => item.event) as Event[];
|
||||||
fetchNextPage,
|
return events.sort((a, b) => b.created_at - a.created_at);
|
||||||
} = useEvents("local", account);
|
},
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
});
|
||||||
|
|
||||||
const renderItem = (event: Event) => {
|
const renderItem = (event: Event) => {
|
||||||
if (!event) return;
|
if (!event) return;
|
||||||
@@ -40,9 +43,11 @@ export function Screen() {
|
|||||||
<Column.Root>
|
<Column.Root>
|
||||||
<Column.Header id={id} name={name} />
|
<Column.Header id={id} name={name} />
|
||||||
<Column.Content>
|
<Column.Content>
|
||||||
{isLoading || isRefetching ? (
|
{isLoading ? (
|
||||||
<div className="flex h-20 w-full flex-col items-center justify-center gap-1">
|
<div className="flex h-20 w-full flex-col items-center justify-center gap-1">
|
||||||
<LoaderIcon className="size-5 animate-spin" />
|
<button type="button" className="size-5" disabled>
|
||||||
|
<LoaderIcon className="size-5 animate-spin" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) : !data.length ? (
|
) : !data.length ? (
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
@@ -60,25 +65,6 @@ export function Screen() {
|
|||||||
{data.map((item) => renderItem(item))}
|
{data.map((item) => renderItem(item))}
|
||||||
</Virtualizer>
|
</Virtualizer>
|
||||||
)}
|
)}
|
||||||
<div className="flex h-20 items-center justify-center">
|
|
||||||
{hasNextPage ? (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => fetchNextPage()}
|
|
||||||
disabled={!hasNextPage || isFetchingNextPage}
|
|
||||||
className="inline-flex h-12 w-36 items-center justify-center gap-2 rounded-full bg-neutral-100 px-3 font-medium hover:bg-neutral-200 focus:outline-none dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
|
||||||
>
|
|
||||||
{isFetchingNextPage ? (
|
|
||||||
<LoaderIcon className="size-5 animate-spin" />
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<ArrowRightCircleIcon className="size-5" />
|
|
||||||
Load more
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</Column.Content>
|
</Column.Content>
|
||||||
</Column.Root>
|
</Column.Root>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,30 +1,14 @@
|
|||||||
import {
|
|
||||||
MediaControlBar,
|
|
||||||
MediaController,
|
|
||||||
MediaMuteButton,
|
|
||||||
MediaPlayButton,
|
|
||||||
MediaTimeDisplay,
|
|
||||||
MediaTimeRange,
|
|
||||||
} from "media-chrome/dist/react";
|
|
||||||
|
|
||||||
export function VideoPreview({ url }: { url: string }) {
|
export function VideoPreview({ url }: { url: string }) {
|
||||||
return (
|
return (
|
||||||
<div className="my-1">
|
<div className="my-1 overflow-hidden rounded-xl">
|
||||||
<MediaController>
|
<video
|
||||||
<video
|
className="h-auto w-full bg-neutral-100 text-sm dark:bg-neutral-900"
|
||||||
slot="media"
|
controls
|
||||||
src={url}
|
muted
|
||||||
preload="auto"
|
>
|
||||||
muted
|
<source src={url} type="video/mp4" />
|
||||||
className="h-auto w-full"
|
Your browser does not support the video tag.
|
||||||
/>
|
</video>
|
||||||
<MediaControlBar>
|
|
||||||
<MediaPlayButton />
|
|
||||||
<MediaTimeRange />
|
|
||||||
<MediaTimeDisplay />
|
|
||||||
<MediaMuteButton />
|
|
||||||
</MediaControlBar>
|
|
||||||
</MediaController>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user