rename following to daily page
This commit is contained in:
@@ -22,8 +22,8 @@ export default function ChannelMembers() {
|
|||||||
{miniMembersList.map((member, index) => (
|
{miniMembersList.map((member, index) => (
|
||||||
<MiniMember key={index} pubkey={member} />
|
<MiniMember key={index} pubkey={member} />
|
||||||
))}
|
))}
|
||||||
{totalMembers > 0 ? (
|
{totalMembers ? (
|
||||||
<div className="inline-block inline-flex h-8 w-8 items-center justify-center rounded-md bg-zinc-900 ring-2 ring-zinc-950 transition-all duration-150 ease-in-out group-hover:bg-zinc-800">
|
<div className="inline-flex h-8 w-8 items-center justify-center rounded-md bg-zinc-900 ring-2 ring-zinc-950 transition-all duration-150 ease-in-out group-hover:bg-zinc-800">
|
||||||
<span className="text-xs font-medium text-zinc-400 group-hover:text-zinc-200">{totalMembers}</span>
|
<span className="text-xs font-medium text-zinc-400 group-hover:text-zinc-200">{totalMembers}</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
1
src/app/daily/_default.page.tsx
Normal file
1
src/app/daily/_default.page.tsx
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { LayoutNewsfeed as Layout } from './layout';
|
||||||
29
src/app/daily/layout.tsx
Normal file
29
src/app/daily/layout.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import AppHeader from '@lume/shared/appHeader';
|
||||||
|
import MultiAccounts from '@lume/shared/multiAccounts';
|
||||||
|
import Navigation from '@lume/shared/navigation';
|
||||||
|
|
||||||
|
export function LayoutNewsfeed({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-zinc-950 dark:text-white">
|
||||||
|
<div className="flex h-screen w-full flex-col">
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
className="relative h-11 shrink-0 border-b border-zinc-100 bg-white dark:border-zinc-900 dark:bg-black"
|
||||||
|
>
|
||||||
|
<AppHeader />
|
||||||
|
</div>
|
||||||
|
<div className="relative flex min-h-0 w-full flex-1">
|
||||||
|
<div className="relative w-[68px] shrink-0 border-r border-zinc-900">
|
||||||
|
<MultiAccounts />
|
||||||
|
</div>
|
||||||
|
<div className="grid w-full grid-cols-4 xl:grid-cols-5">
|
||||||
|
<div className="scrollbar-hide col-span-1 overflow-y-auto overflow-x-hidden border-r border-zinc-900">
|
||||||
|
<Navigation />
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3 m-3 overflow-hidden xl:col-span-4">{children}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
92
src/app/daily/pages/index.page.tsx
Normal file
92
src/app/daily/pages/index.page.tsx
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import NoteBase from '@lume/app/note/components/base';
|
||||||
|
import { Placeholder } from '@lume/app/note/components/placeholder';
|
||||||
|
import { NoteQuoteRepost } from '@lume/app/note/components/quoteRepost';
|
||||||
|
import { getNotes } from '@lume/utils/storage';
|
||||||
|
|
||||||
|
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||||
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
const ITEM_PER_PAGE = 10;
|
||||||
|
const TIME = Math.floor(Date.now() / 1000);
|
||||||
|
|
||||||
|
export function Page() {
|
||||||
|
const { status, error, data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage }: any = useInfiniteQuery({
|
||||||
|
queryKey: ['following'],
|
||||||
|
queryFn: async ({ pageParam = 0 }) => {
|
||||||
|
return await getNotes(TIME, ITEM_PER_PAGE, pageParam);
|
||||||
|
},
|
||||||
|
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
||||||
|
});
|
||||||
|
|
||||||
|
const allRows = data ? data.pages.flatMap((d: { data: any }) => d.data) : [];
|
||||||
|
const parentRef = useRef();
|
||||||
|
|
||||||
|
const rowVirtualizer = useVirtualizer({
|
||||||
|
count: hasNextPage ? allRows.length + 1 : allRows.length,
|
||||||
|
getScrollElement: () => parentRef.current,
|
||||||
|
estimateSize: () => 400,
|
||||||
|
overscan: 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
const itemsVirtualizer = rowVirtualizer.getVirtualItems();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const [lastItem] = [...rowVirtualizer.getVirtualItems()].reverse();
|
||||||
|
|
||||||
|
if (!lastItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastItem.index >= allRows.length - 1 && hasNextPage && !isFetchingNextPage) {
|
||||||
|
fetchNextPage();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [fetchNextPage, allRows.length, rowVirtualizer.getVirtualItems()]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative h-full w-full rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20">
|
||||||
|
{status === 'loading' ? (
|
||||||
|
<Placeholder />
|
||||||
|
) : status === 'error' ? (
|
||||||
|
<div>{error.message}</div>
|
||||||
|
) : (
|
||||||
|
<div ref={parentRef} className="scrollbar-hide h-full w-full overflow-y-auto" style={{ contain: 'strict' }}>
|
||||||
|
<div
|
||||||
|
className="relative w-full"
|
||||||
|
style={{
|
||||||
|
height: `${rowVirtualizer.getTotalSize()}px`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="absolute left-0 top-0 w-full"
|
||||||
|
style={{
|
||||||
|
transform: `translateY(${itemsVirtualizer[0].start - rowVirtualizer.options.scrollMargin}px)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
||||||
|
const note = allRows[virtualRow.index];
|
||||||
|
if (note) {
|
||||||
|
if (note.kind === 1) {
|
||||||
|
return (
|
||||||
|
<div key={virtualRow.index} data-index={virtualRow.index} ref={rowVirtualizer.measureElement}>
|
||||||
|
<NoteBase key={note.event_id} event={note} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div key={virtualRow.index} data-index={virtualRow.index} ref={rowVirtualizer.measureElement}>
|
||||||
|
<NoteQuoteRepost key={note.event_id} event={note} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div>{isFetching && !isFetchingNextPage ? <Placeholder /> : null}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -126,7 +126,7 @@ export function Page() {
|
|||||||
() => {
|
() => {
|
||||||
updateLastLogin(dateToUnix(now.current));
|
updateLastLogin(dateToUnix(now.current));
|
||||||
timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
navigate('/app/newsfeed/following', { overwriteLastHistoryEntry: true });
|
navigate('/app/daily', { overwriteLastHistoryEntry: true });
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -95,6 +95,13 @@ export async function getNotes(time: number, limit: number, offset: number) {
|
|||||||
return notes;
|
return notes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get all note authors
|
||||||
|
export async function getNoteAuthors() {
|
||||||
|
const db = await connect();
|
||||||
|
const result = await db.select(`SELECT DISTINCT pubkey FROM notes ORDER BY created_at DESC`);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// get note by id
|
// get note by id
|
||||||
export async function getNoteByID(event_id: string) {
|
export async function getNoteByID(event_id: string) {
|
||||||
const db = await connect();
|
const db = await connect();
|
||||||
|
|||||||
Reference in New Issue
Block a user