mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-19 19:46:34 +00:00
fixed duplicate note in newsfeed and minor fixes
This commit is contained in:
parent
66e45937de
commit
b778cf6198
@ -4,19 +4,19 @@ import FormBase from '@components/form/base';
|
|||||||
import { NoteBase } from '@components/note/base';
|
import { NoteBase } from '@components/note/base';
|
||||||
import { Placeholder } from '@components/note/placeholder';
|
import { Placeholder } from '@components/note/placeholder';
|
||||||
|
|
||||||
import { hasNewerNoteAtom } from '@stores/note';
|
import { filteredNotesAtom, hasNewerNoteAtom, notesAtom } from '@stores/note';
|
||||||
|
|
||||||
import { dateToUnix } from '@utils/getDate';
|
import { dateToUnix } from '@utils/getDate';
|
||||||
import { filterDuplicateParentID } from '@utils/transform';
|
|
||||||
|
|
||||||
import { ArrowUp } from 'iconoir-react';
|
import { ArrowUp } from 'iconoir-react';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
import { Virtuoso } from 'react-virtuoso';
|
import { Virtuoso } from 'react-virtuoso';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const [data, setData] = useState([]);
|
|
||||||
const [hasNewerNote, setHasNewerNote] = useAtom(hasNewerNoteAtom);
|
const [hasNewerNote, setHasNewerNote] = useAtom(hasNewerNoteAtom);
|
||||||
|
const setData = useSetAtom(notesAtom);
|
||||||
|
const data = useAtomValue(filteredNotesAtom);
|
||||||
|
|
||||||
const virtuosoRef = useRef(null);
|
const virtuosoRef = useRef(null);
|
||||||
const now = useRef(new Date());
|
const now = useRef(new Date());
|
||||||
@ -45,7 +45,7 @@ export default function Page() {
|
|||||||
offset: offset.current,
|
offset: offset.current,
|
||||||
});
|
});
|
||||||
setData((data) => [...data, ...result]);
|
setData((data) => [...data, ...result]);
|
||||||
}, []);
|
}, [setData]);
|
||||||
|
|
||||||
const loadMore = useCallback(async () => {
|
const loadMore = useCallback(async () => {
|
||||||
const { getNotes } = await import('@utils/bindings');
|
const { getNotes } = await import('@utils/bindings');
|
||||||
@ -57,14 +57,14 @@ export default function Page() {
|
|||||||
offset: offset.current,
|
offset: offset.current,
|
||||||
});
|
});
|
||||||
setData((data) => [...data, ...result]);
|
setData((data) => [...data, ...result]);
|
||||||
}, []);
|
}, [setData]);
|
||||||
|
|
||||||
const loadLatest = useCallback(async () => {
|
const loadLatest = useCallback(async () => {
|
||||||
const { getLatestNotes } = await import('@utils/bindings');
|
const { getLatestNotes } = await import('@utils/bindings');
|
||||||
// next query
|
// next query
|
||||||
const result: any = await getLatestNotes({ date: dateToUnix(now.current) });
|
const result: any = await getLatestNotes({ date: dateToUnix(now.current) });
|
||||||
// update data
|
// update data
|
||||||
if (result.length > 0) {
|
if (Array.isArray(result)) {
|
||||||
setData((data) => [...data, ...result]);
|
setData((data) => [...data, ...result]);
|
||||||
} else {
|
} else {
|
||||||
setData((data) => [...data, result]);
|
setData((data) => [...data, result]);
|
||||||
@ -72,8 +72,8 @@ export default function Page() {
|
|||||||
// hide newer trigger
|
// hide newer trigger
|
||||||
setHasNewerNote(false);
|
setHasNewerNote(false);
|
||||||
// scroll to top
|
// scroll to top
|
||||||
virtuosoRef.current.scrollToIndex({ index: 0 });
|
virtuosoRef.current.scrollToIndex({ index: -1 });
|
||||||
}, [setHasNewerNote]);
|
}, [setData, setHasNewerNote]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initialData().catch(console.error);
|
initialData().catch(console.error);
|
||||||
@ -94,7 +94,7 @@ export default function Page() {
|
|||||||
)}
|
)}
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
ref={virtuosoRef}
|
ref={virtuosoRef}
|
||||||
data={filterDuplicateParentID(data)}
|
data={data}
|
||||||
itemContent={itemContent}
|
itemContent={itemContent}
|
||||||
computeItemKey={computeItemKey}
|
computeItemKey={computeItemKey}
|
||||||
components={COMPONENTS}
|
components={COMPONENTS}
|
||||||
|
@ -123,7 +123,7 @@ export default function Page() {
|
|||||||
},
|
},
|
||||||
undefined,
|
undefined,
|
||||||
() => {
|
() => {
|
||||||
if (eose.current > relays.length - 7) {
|
if (eose.current > relays.length / 2) {
|
||||||
router.replace('/newsfeed/following');
|
router.replace('/newsfeed/following');
|
||||||
} else {
|
} else {
|
||||||
eose.current += 1;
|
eose.current += 1;
|
||||||
|
@ -32,15 +32,17 @@ export default function EventCollector() {
|
|||||||
const { createPleb } = await import('@utils/bindings');
|
const { createPleb } = await import('@utils/bindings');
|
||||||
for (const tag of tags) {
|
for (const tag of tags) {
|
||||||
const pubkey = tag[1];
|
const pubkey = tag[1];
|
||||||
const metadata: any = await fetchMetadata(pubkey);
|
fetchMetadata(pubkey)
|
||||||
|
.then((res: { content: string }) => {
|
||||||
createPleb({
|
createPleb({
|
||||||
pleb_id: pubkey + '-lume' + activeAccount.id.toString(),
|
pleb_id: pubkey + '-lume' + activeAccount.id.toString(),
|
||||||
pubkey: pubkey,
|
pubkey: pubkey,
|
||||||
kind: 0,
|
kind: 0,
|
||||||
metadata: metadata.content,
|
metadata: res.content,
|
||||||
account_id: activeAccount.id,
|
account_id: activeAccount.id,
|
||||||
}).catch(console.error);
|
}).catch(console.error);
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[activeAccount.id]
|
[activeAccount.id]
|
||||||
|
@ -2,7 +2,7 @@ import NoteMetadata from '@components/note/metadata';
|
|||||||
import { NoteParent } from '@components/note/parent';
|
import { NoteParent } from '@components/note/parent';
|
||||||
import { ImagePreview } from '@components/note/preview/image';
|
import { ImagePreview } from '@components/note/preview/image';
|
||||||
import { VideoPreview } from '@components/note/preview/video';
|
import { VideoPreview } from '@components/note/preview/video';
|
||||||
import { NoteRepost } from '@components/note/repost';
|
import { NoteQuote } from '@components/note/quote';
|
||||||
import { UserExtend } from '@components/user/extend';
|
import { UserExtend } from '@components/user/extend';
|
||||||
import { UserMention } from '@components/user/mention';
|
import { UserMention } from '@components/user/mention';
|
||||||
|
|
||||||
@ -48,10 +48,10 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) {
|
|||||||
parsedContent = reactStringReplace(parsedContent, /\#\[(\d+)\]/gm, (match, i) => {
|
parsedContent = reactStringReplace(parsedContent, /\#\[(\d+)\]/gm, (match, i) => {
|
||||||
if (tags[match][0] === 'p') {
|
if (tags[match][0] === 'p') {
|
||||||
// @-mentions
|
// @-mentions
|
||||||
return <UserMention key={match + i} pubkey={tags[match][1]} />;
|
return <UserMention key={tags[match][1]} pubkey={tags[match][1]} />;
|
||||||
} else if (tags[match][0] === 'e') {
|
} else if (tags[match][0] === 'e') {
|
||||||
// note-mentions
|
// note-quotes
|
||||||
return <NoteRepost key={match + i} id={tags[match][1]} />;
|
return <NoteQuote key={tags[match][1]} id={tags[match][1]} />;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -61,10 +61,10 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) {
|
|||||||
return parsedContent;
|
return parsedContent;
|
||||||
}, [event.content, event.tags]);
|
}, [event.content, event.tags]);
|
||||||
|
|
||||||
const getParent = useMemo(() => {
|
const parentNote = useMemo(() => {
|
||||||
if (event.parent_id) {
|
if (event.parent_id) {
|
||||||
if (event.parent_id !== event.eventId && !event.content.includes('#[0]')) {
|
if (event.parent_id !== event.eventId && !event.content.includes('#[0]')) {
|
||||||
return <NoteParent id={event.parent_id} />;
|
return <NoteParent key={event.parent_id} id={event.parent_id} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) {
|
|||||||
onClick={(e) => openThread(e)}
|
onClick={(e) => openThread(e)}
|
||||||
className="relative z-10 m-0 flex h-min min-h-min w-full select-text flex-col border-b border-zinc-800 px-3 py-5 hover:bg-black/20"
|
className="relative z-10 m-0 flex h-min min-h-min w-full select-text flex-col border-b border-zinc-800 px-3 py-5 hover:bg-black/20"
|
||||||
>
|
>
|
||||||
<>{getParent}</>
|
<>{parentNote}</>
|
||||||
<div className="relative z-10 flex flex-col">
|
<div className="relative z-10 flex flex-col">
|
||||||
<div onClick={(e) => openUserPage(e)}>
|
<div onClick={(e) => openUserPage(e)}>
|
||||||
<UserExtend pubkey={event.pubkey} time={event.createdAt || event.created_at} />
|
<UserExtend pubkey={event.pubkey} time={event.createdAt || event.created_at} />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import NoteMetadata from '@components/note/metadata';
|
import NoteMetadata from '@components/note/metadata';
|
||||||
import { ImagePreview } from '@components/note/preview/image';
|
import { ImagePreview } from '@components/note/preview/image';
|
||||||
import { VideoPreview } from '@components/note/preview/video';
|
import { VideoPreview } from '@components/note/preview/video';
|
||||||
import { NoteRepost } from '@components/note/repost';
|
import { NoteQuote } from '@components/note/quote';
|
||||||
import { UserExtend } from '@components/user/extend';
|
import { UserExtend } from '@components/user/extend';
|
||||||
import { UserMention } from '@components/user/mention';
|
import { UserMention } from '@components/user/mention';
|
||||||
|
|
||||||
@ -46,8 +46,8 @@ export const NoteComment = memo(function NoteComment({ event }: { event: any })
|
|||||||
// @-mentions
|
// @-mentions
|
||||||
return <UserMention key={match + i} pubkey={tags[match][1]} />;
|
return <UserMention key={match + i} pubkey={tags[match][1]} />;
|
||||||
} else if (tags[match][0] === 'e') {
|
} else if (tags[match][0] === 'e') {
|
||||||
// note-mentions
|
// note-quotes
|
||||||
return <NoteRepost key={match + i} id={tags[match][1]} />;
|
return <NoteQuote key={match + i} id={tags[match][1]} />;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import NoteMetadata from '@components/note/metadata';
|
import NoteMetadata from '@components/note/metadata';
|
||||||
import { ImagePreview } from '@components/note/preview/image';
|
import { ImagePreview } from '@components/note/preview/image';
|
||||||
import { VideoPreview } from '@components/note/preview/video';
|
import { VideoPreview } from '@components/note/preview/video';
|
||||||
import { NoteRepost } from '@components/note/repost';
|
import { NoteQuote } from '@components/note/quote';
|
||||||
import { UserLarge } from '@components/user/large';
|
import { UserLarge } from '@components/user/large';
|
||||||
import { UserMention } from '@components/user/mention';
|
import { UserMention } from '@components/user/mention';
|
||||||
|
|
||||||
@ -46,8 +46,8 @@ export const NoteExtend = memo(function NoteExtend({ event }: { event: any }) {
|
|||||||
// @-mentions
|
// @-mentions
|
||||||
return <UserMention key={match + i} pubkey={tags[match][1]} />;
|
return <UserMention key={match + i} pubkey={tags[match][1]} />;
|
||||||
} else if (tags[match][0] === 'e') {
|
} else if (tags[match][0] === 'e') {
|
||||||
// note-mentions
|
// note-quotes
|
||||||
return <NoteRepost key={match + i} id={tags[match][1]} />;
|
return <NoteQuote key={match + i} id={tags[match][1]} />;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import NoteMetadata from '@components/note/metadata';
|
import NoteMetadata from '@components/note/metadata';
|
||||||
import { ImagePreview } from '@components/note/preview/image';
|
import { ImagePreview } from '@components/note/preview/image';
|
||||||
import { VideoPreview } from '@components/note/preview/video';
|
import { VideoPreview } from '@components/note/preview/video';
|
||||||
import { NoteRepost } from '@components/note/repost';
|
import { NoteQuote } from '@components/note/quote';
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
import { UserExtend } from '@components/user/extend';
|
import { UserExtend } from '@components/user/extend';
|
||||||
import { UserMention } from '@components/user/mention';
|
import { UserMention } from '@components/user/mention';
|
||||||
@ -117,10 +117,10 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
|
|||||||
parsedContent = reactStringReplace(parsedContent, /\#\[(\d+)\]/gm, (match, i) => {
|
parsedContent = reactStringReplace(parsedContent, /\#\[(\d+)\]/gm, (match, i) => {
|
||||||
if (tags[match][0] === 'p') {
|
if (tags[match][0] === 'p') {
|
||||||
// @-mentions
|
// @-mentions
|
||||||
return <UserMention key={match + i} pubkey={tags[match][1]} />;
|
return <UserMention key={tags[match][1]} pubkey={tags[match][1]} />;
|
||||||
} else if (tags[match][0] === 'e') {
|
} else if (tags[match][0] === 'e') {
|
||||||
// note-mentions
|
// note-quotes
|
||||||
return <NoteRepost key={match + i} id={tags[match][1]} />;
|
return <NoteQuote key={tags[match][1]} id={tags[match][1]} />;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,14 @@ import { memo } from 'react';
|
|||||||
|
|
||||||
export const ImagePreview = memo(function ImagePreview({ url }: { url: string }) {
|
export const ImagePreview = memo(function ImagePreview({ url }: { url: string }) {
|
||||||
return (
|
return (
|
||||||
<div className="relative mt-3 mb-2 h-full w-full rounded-lg xl:w-2/3">
|
<div className="relative mb-2 mt-3 h-full w-full rounded-lg border border-zinc-800 xl:w-2/3">
|
||||||
<Image
|
<Image
|
||||||
src={url}
|
src={url}
|
||||||
alt={url}
|
alt={url}
|
||||||
width="0"
|
width="0"
|
||||||
height="0"
|
height="0"
|
||||||
sizes="100vw"
|
sizes="100vw"
|
||||||
className="h-auto w-full rounded-lg border border-zinc-800 object-cover"
|
className="h-auto w-full rounded-lg object-cover"
|
||||||
placeholder="blur"
|
|
||||||
blurDataURL="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkqAcAAIUAgUW0RjgAAAAASUVORK5CYII="
|
|
||||||
priority
|
priority
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,7 +9,7 @@ import destr from 'destr';
|
|||||||
import { memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
import { memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import reactStringReplace from 'react-string-replace';
|
import reactStringReplace from 'react-string-replace';
|
||||||
|
|
||||||
export const NoteRepost = memo(function NoteRepost({ id }: { id: string }) {
|
export const NoteQuote = memo(function NoteRepost({ id }: { id: string }) {
|
||||||
const [pool, relays]: any = useContext(RelayContext);
|
const [pool, relays]: any = useContext(RelayContext);
|
||||||
|
|
||||||
const [activeAccount]: any = useLocalStorage('activeAccount', {});
|
const [activeAccount]: any = useLocalStorage('activeAccount', {});
|
@ -1,7 +1,15 @@
|
|||||||
import { atom } from 'jotai';
|
import { atom } from 'jotai';
|
||||||
import { atomWithReset } from 'jotai/utils';
|
import { atomWithReset } from 'jotai/utils';
|
||||||
|
|
||||||
|
// notes
|
||||||
|
export const notesAtom = atom([]);
|
||||||
|
export const filteredNotesAtom = atom((get) => {
|
||||||
|
const notes = get(notesAtom);
|
||||||
|
return notes.filter((item, index) => index === notes.findIndex((other) => item.parent_id === other.parent_id));
|
||||||
|
});
|
||||||
|
|
||||||
// note content
|
// note content
|
||||||
export const noteContentAtom = atomWithReset('');
|
export const noteContentAtom = atomWithReset('');
|
||||||
|
|
||||||
// notify user that connector has receive newer note
|
// notify user that connector has receive newer note
|
||||||
export const hasNewerNoteAtom = atom(false);
|
export const hasNewerNoteAtom = atom(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user