diff --git a/package-lock.json b/package-lock.json index e9bf35f..389dd51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-switch": "^1.1.1", "@radix-ui/react-toast": "^1.2.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", @@ -2529,6 +2530,34 @@ } } }, + "node_modules/@radix-ui/react-switch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.1.tgz", + "integrity": "sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-toast": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.2.tgz", diff --git a/package.json b/package.json index 47d50ee..7386960 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-switch": "^1.1.1", "@radix-ui/react-toast": "^1.2.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", diff --git a/src/renderer/src/components/NoteList/index.tsx b/src/renderer/src/components/NoteList/index.tsx index f98a709..0d29a94 100644 --- a/src/renderer/src/components/NoteList/index.tsx +++ b/src/renderer/src/components/NoteList/index.tsx @@ -1,8 +1,10 @@ import { Button } from '@renderer/components/ui/button' +import { Switch } from '@renderer/components/ui/switch' import { useFetchRelayInfos } from '@renderer/hooks' import { isReplyNoteEvent } from '@renderer/lib/event' import { cn } from '@renderer/lib/utils' import { useNostr } from '@renderer/providers/NostrProvider' +import { useScreenSize } from '@renderer/providers/ScreenSizeProvider' import client from '@renderer/services/client.service' import dayjs from 'dayjs' import { Event, Filter, kinds } from 'nostr-tools' @@ -27,6 +29,7 @@ export default function NoteList({ const [until, setUntil] = useState(() => dayjs().unix()) const [hasMore, setHasMore] = useState(true) const [initialized, setInitialized] = useState(false) + const [displayReplies, setDisplayReplies] = useState(false) const observer = useRef(null) const bottomRef = useRef(null) const noteFilter = useMemo(() => { @@ -53,9 +56,8 @@ export default function NoteList({ if (!areAlgoRelays) { events.sort((a, b) => b.created_at - a.created_at) } - const processedEvents = events.filter((e) => !isReplyNoteEvent(e)) - if (processedEvents.length > 0) { - setEvents((pre) => [...pre, ...processedEvents]) + if (events.length > 0) { + setEvents((pre) => [...pre, ...events]) } if (events.length > 0) { setUntil(events[events.length - 1].created_at - 1) @@ -66,9 +68,7 @@ export default function NoteList({ setInitialized(true) }, onNew: (event) => { - if (!isReplyNoteEvent(event)) { - setNewEvents((oldEvents) => [event, ...oldEvents]) - } + setNewEvents((oldEvents) => [event, ...oldEvents]) } }, signEvent @@ -119,9 +119,8 @@ export default function NoteList({ return } - const processedEvents = sortedEvents.filter((e) => !isReplyNoteEvent(e)) - if (processedEvents.length > 0) { - setEvents((oldEvents) => [...oldEvents, ...processedEvents]) + if (sortedEvents.length > 0) { + setEvents((oldEvents) => [...oldEvents, ...sortedEvents]) } setUntil(sortedEvents[sortedEvents.length - 1].created_at - 1) @@ -133,7 +132,8 @@ export default function NoteList({ } return ( -
+
+ {newEvents.length > 0 && (
)} -
- {events.map((event, i) => ( - - ))} +
+ {events + .filter((event) => displayReplies || !isReplyNoteEvent(event)) + .map((event, i) => ( + + ))}
{hasMore ?
{t('loading...')}
: t('no more notes')} @@ -152,3 +154,47 @@ export default function NoteList({
) } + +function DisplayRepliesSwitch({ + displayReplies, + setDisplayReplies +}: { + displayReplies: boolean + setDisplayReplies: (value: boolean) => void +}) { + const { t } = useTranslation() + const { isSmallScreen } = useScreenSize() + + if (isSmallScreen) { + return ( +
+
+
setDisplayReplies(false)} + > + {t('Notes')} +
+
setDisplayReplies(true)} + > + {t('Notes & Replies')} +
+
+
+
+
+
+ ) + } + + return ( +
+
{t('Display replies')}
+ +
+ ) +} diff --git a/src/renderer/src/components/ui/switch.tsx b/src/renderer/src/components/ui/switch.tsx new file mode 100644 index 0000000..6d839b8 --- /dev/null +++ b/src/renderer/src/components/ui/switch.tsx @@ -0,0 +1,27 @@ +import * as React from "react" +import * as SwitchPrimitives from "@radix-ui/react-switch" + +import { cn } from "@renderer/lib/utils" + +const Switch = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +Switch.displayName = SwitchPrimitives.Root.displayName + +export { Switch } diff --git a/src/renderer/src/i18n/en.ts b/src/renderer/src/i18n/en.ts index 42fcd8e..783a8b5 100644 --- a/src/renderer/src/i18n/en.ts +++ b/src/renderer/src/i18n/en.ts @@ -69,6 +69,9 @@ export default { 'The relays you are connected to do not support search', 'supports search': 'supports search', 'Show more...': 'Show more...', - 'all users': 'all users' + 'all users': 'all users', + 'Display replies': 'Display replies', + Notes: 'Notes', + 'Notes & Replies': 'Notes & Replies' } } diff --git a/src/renderer/src/i18n/zh.ts b/src/renderer/src/i18n/zh.ts index 58467ef..21e82ef 100644 --- a/src/renderer/src/i18n/zh.ts +++ b/src/renderer/src/i18n/zh.ts @@ -68,6 +68,9 @@ export default { 'The relays you are connected to do not support search': '您连接的服务器不支持搜索', 'supports search': '支持搜索', 'Show more...': '查看更多...', - 'all users': '所有用户' + 'all users': '所有用户', + 'Display replies': '显示回复', + Notes: '笔记', + 'Notes & Replies': '笔记 & 回复' } } diff --git a/src/renderer/src/layouts/PrimaryPageLayout/index.tsx b/src/renderer/src/layouts/PrimaryPageLayout/index.tsx index f5a259d..920b6ad 100644 --- a/src/renderer/src/layouts/PrimaryPageLayout/index.tsx +++ b/src/renderer/src/layouts/PrimaryPageLayout/index.tsx @@ -32,10 +32,10 @@ const PrimaryPageLayout = forwardRef(({ children }: { children?: React.ReactNode const handleScroll = () => { const scrollTop = scrollAreaRef.current?.scrollTop || 0 const diff = scrollTop - lastScrollTop - if (diff > 20) { + if (diff > 50) { setVisible(false) setLastScrollTop(scrollTop) - } else if (diff < -20) { + } else if (diff < -50) { setVisible(true) setLastScrollTop(scrollTop) } diff --git a/src/renderer/src/pages/secondary/ProfilePage/index.tsx b/src/renderer/src/pages/secondary/ProfilePage/index.tsx index 79cfb76..9aafb3f 100644 --- a/src/renderer/src/pages/secondary/ProfilePage/index.tsx +++ b/src/renderer/src/pages/secondary/ProfilePage/index.tsx @@ -98,11 +98,12 @@ export default function ProfilePage({ id }: { id?: string }) {
- + )