diff --git a/src/components/KindFilter/index.tsx b/src/components/KindFilter/index.tsx index d6af3f87..ff923ed1 100644 --- a/src/components/KindFilter/index.tsx +++ b/src/components/KindFilter/index.tsx @@ -32,12 +32,13 @@ const KIND_FILTER_OPTIONS = [ function buildShowKindsFromOptions( baseKinds: number[], showKind1OPs: boolean, - showRepliesAndComments: boolean + showKind1Replies: boolean, + showKind1111: boolean ): number[] { const rest = baseKinds.filter((k) => k !== KIND_1 && k !== KIND_1111) const out = [...rest] - if (showKind1OPs || showRepliesAndComments) out.push(KIND_1) - if (showRepliesAndComments) out.push(KIND_1111) + if (showKind1OPs || showKind1Replies) out.push(KIND_1) + if (showKind1111) out.push(KIND_1111) return out.sort((a, b) => a - b) } @@ -53,15 +54,15 @@ export default function KindFilter({ const { showKinds: savedShowKinds, showKind1OPs: savedShowKind1OPs, - showRepliesAndComments: savedShowRepliesAndComments, + showKind1Replies: savedShowKind1Replies, + showKind1111: savedShowKind1111, updateShowKinds } = useKindFilter() const [open, setOpen] = useState(false) const [temporaryShowKinds, setTemporaryShowKinds] = useState(showKinds) const [temporaryShowKind1OPs, setTemporaryShowKind1OPs] = useState(savedShowKind1OPs) - const [temporaryShowRepliesAndComments, setTemporaryShowRepliesAndComments] = useState( - savedShowRepliesAndComments - ) + const [temporaryShowKind1Replies, setTemporaryShowKind1Replies] = useState(savedShowKind1Replies) + const [temporaryShowKind1111, setTemporaryShowKind1111] = useState(savedShowKind1111) const [isPersistent, setIsPersistent] = useState(false) const isDifferentFromSaved = useMemo( () => !isSameKindFilter(showKinds, savedShowKinds), @@ -71,14 +72,17 @@ export default function KindFilter({ () => !isSameKindFilter(temporaryShowKinds, savedShowKinds) || temporaryShowKind1OPs !== savedShowKind1OPs || - temporaryShowRepliesAndComments !== savedShowRepliesAndComments, + temporaryShowKind1Replies !== savedShowKind1Replies || + temporaryShowKind1111 !== savedShowKind1111, [ temporaryShowKinds, savedShowKinds, temporaryShowKind1OPs, - temporaryShowRepliesAndComments, + temporaryShowKind1Replies, + temporaryShowKind1111, savedShowKind1OPs, - savedShowRepliesAndComments + savedShowKind1Replies, + savedShowKind1111 ] ) @@ -86,19 +90,21 @@ export default function KindFilter({ if (open) { setTemporaryShowKinds(showKinds) setTemporaryShowKind1OPs(savedShowKind1OPs) - setTemporaryShowRepliesAndComments(savedShowRepliesAndComments) + setTemporaryShowKind1Replies(savedShowKind1Replies) + setTemporaryShowKind1111(savedShowKind1111) setIsPersistent(false) } - }, [open, showKinds, savedShowKind1OPs, savedShowRepliesAndComments]) + }, [open, showKinds, savedShowKind1OPs, savedShowKind1Replies, savedShowKind1111]) const appliedShowKinds = useMemo( () => buildShowKindsFromOptions( temporaryShowKinds, temporaryShowKind1OPs, - temporaryShowRepliesAndComments + temporaryShowKind1Replies, + temporaryShowKind1111 ), - [temporaryShowKinds, temporaryShowKind1OPs, temporaryShowRepliesAndComments] + [temporaryShowKinds, temporaryShowKind1OPs, temporaryShowKind1Replies, temporaryShowKind1111] ) const canApply = appliedShowKinds.length > 0 @@ -111,7 +117,8 @@ export default function KindFilter({ } updateShowKinds(newShowKinds, { showKind1OPs: temporaryShowKind1OPs, - showRepliesAndComments: temporaryShowRepliesAndComments + showKind1Replies: temporaryShowKind1Replies, + showKind1111: temporaryShowKind1111 }) setIsPersistent(false) setOpen(false) @@ -153,16 +160,27 @@ export default function KindFilter({

{t('Posts (OPs)')}

kind {KIND_1}

- {/* Replies & comments - kind 1 replies + kind 1111 */} + {/* Kind 1 replies - kind 1 that are replies */} +
setTemporaryShowKind1Replies((prev) => !prev)} + > +

{t('Kind 1 replies')}

+

kind {KIND_1}

+
+ {/* Comments - kind 1111 */}
setTemporaryShowRepliesAndComments((prev) => !prev)} + onClick={() => setTemporaryShowKind1111((prev) => !prev)} > -

{t('Replies & comments')}

-

kind {KIND_1}, {KIND_1111}

+

{t('Comments')}

+

kind {KIND_1111}

{KIND_FILTER_OPTIONS.map(({ kindGroup, label }) => { const checked = kindGroup.every((k) => temporaryShowKinds.includes(k)) @@ -196,7 +214,8 @@ export default function KindFilter({ SUPPORTED_KINDS.filter((k) => k !== kinds.Repost && k !== KIND_1 && k !== KIND_1111) ) setTemporaryShowKind1OPs(true) - setTemporaryShowRepliesAndComments(true) + setTemporaryShowKind1Replies(true) + setTemporaryShowKind1111(true) }} > {t('Select All')} @@ -206,7 +225,8 @@ export default function KindFilter({ onClick={() => { setTemporaryShowKinds([]) setTemporaryShowKind1OPs(false) - setTemporaryShowRepliesAndComments(false) + setTemporaryShowKind1Replies(false) + setTemporaryShowKind1111(false) }} > {t('Clear All')} @@ -216,7 +236,8 @@ export default function KindFilter({ onClick={() => { setTemporaryShowKinds(savedShowKinds) setTemporaryShowKind1OPs(savedShowKind1OPs) - setTemporaryShowRepliesAndComments(savedShowRepliesAndComments) + setTemporaryShowKind1Replies(savedShowKind1Replies) + setTemporaryShowKind1111(savedShowKind1111) }} disabled={!isTemporaryDifferentFromSaved} > diff --git a/src/components/NormalFeed/index.tsx b/src/components/NormalFeed/index.tsx index 276b34df..9fc24ba8 100644 --- a/src/components/NormalFeed/index.tsx +++ b/src/components/NormalFeed/index.tsx @@ -30,7 +30,7 @@ const NormalFeed = forwardRef(() => { // Get stored mode preference @@ -268,7 +268,8 @@ const NormalFeed = forwardRef { if (!showKinds.includes(evt.kind)) return false - // Kind 1: show only OPs if showKind1OPs, only replies if showRepliesAndComments + // Kind 1: show only OPs if showKind1OPs, only replies if showKind1Replies if (evt.kind === kinds.ShortTextNote) { const isReply = isReplyNoteEvent(evt) - if (isReply && !showRepliesAndComments) return false + if (isReply && !showKind1Replies) return false if (!isReply && !showKind1OPs) return false } - // Kind 1111 (comments): show only if showRepliesAndComments - if (evt.kind === ExtendedKind.COMMENT && !showRepliesAndComments) return false + // Kind 1111 (comments): show only if showKind1111 + if (evt.kind === ExtendedKind.COMMENT && !showKind1111) return false if (shouldHideEvent(evt)) return false const id = isReplaceableEvent(evt.kind) ? getReplaceableCoordinateFromEvent(evt) : evt.id @@ -158,7 +160,7 @@ const NoteList = forwardRef( idSet.add(id) return true }) - }, [events, showCount, shouldHideEvent, showKinds, showKind1OPs, showRepliesAndComments]) + }, [events, showCount, shouldHideEvent, showKinds, showKind1OPs, showKind1Replies, showKind1111]) const filteredNewEvents = useMemo(() => { const idSet = new Set() @@ -167,10 +169,10 @@ const NoteList = forwardRef( if (!showKinds.includes(event.kind)) return false if (event.kind === kinds.ShortTextNote) { const isReply = isReplyNoteEvent(event) - if (isReply && !showRepliesAndComments) return false + if (isReply && !showKind1Replies) return false if (!isReply && !showKind1OPs) return false } - if (event.kind === ExtendedKind.COMMENT && !showRepliesAndComments) return false + if (event.kind === ExtendedKind.COMMENT && !showKind1111) return false if (shouldHideEvent(event)) return false const id = isReplaceableEvent(event.kind) @@ -182,7 +184,7 @@ const NoteList = forwardRef( idSet.add(id) return true }) - }, [newEvents, shouldHideEvent, showKinds, showKind1OPs, showRepliesAndComments]) + }, [newEvents, shouldHideEvent, showKinds, showKind1OPs, showKind1Replies, showKind1111]) const scrollToTop = (behavior: ScrollBehavior = 'instant') => { setTimeout(() => { @@ -240,10 +242,10 @@ const NoteList = forwardRef( if (!showKinds.includes(event.kind)) return if (event.kind === kinds.ShortTextNote) { const isReply = isReplyNoteEvent(event) - if (isReply && !showRepliesAndComments) return + if (isReply && !showKind1Replies) return if (!isReply && !showKind1OPs) return } - if (event.kind === ExtendedKind.COMMENT && !showRepliesAndComments) return + if (event.kind === ExtendedKind.COMMENT && !showKind1111) return if (pubkey && event.pubkey === pubkey) { // If the new event is from the current user, insert it directly into the feed setEvents((oldEvents) => @@ -287,7 +289,7 @@ const NoteList = forwardRef( return () => { promise.then((closer) => closer()) } - }, [subRequestsKey, refreshCount, showKinds, showKind1OPs, showRepliesAndComments]) + }, [subRequestsKey, refreshCount, showKinds, showKind1OPs, showKind1Replies, showKind1111]) useEffect(() => { const options = { diff --git a/src/constants.ts b/src/constants.ts index baf9809b..6ea0a215 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -43,6 +43,9 @@ export const StorageKey = { SHOW_KINDS: 'showKinds', SHOW_KINDS_VERSION: 'showKindsVersion', SHOW_KIND_1_OPs: 'showKind1OPs', + SHOW_KIND_1_REPLIES: 'showKind1Replies', + SHOW_KIND_1111: 'showKind1111', + /** @deprecated use SHOW_KIND_1_REPLIES + SHOW_KIND_1111 */ SHOW_REPLIES_AND_COMMENTS: 'showRepliesAndComments', HIDE_CONTENT_MENTIONING_MUTED_USERS: 'hideContentMentioningMutedUsers', NOTIFICATION_LIST_STYLE: 'notificationListStyle', diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts index 17f3a52a..d14cb05e 100644 --- a/src/i18n/locales/de.ts +++ b/src/i18n/locales/de.ts @@ -378,6 +378,8 @@ export default { "Don't remind me again": 'Nicht mehr erinnern', Posts: 'Beiträge', 'Posts (OPs)': 'Beiträge (OPs)', + 'Kind 1 replies': 'Kind-1-Antworten', + 'Comments': 'Kommentare', 'Replies & comments': 'Antworten & Kommentare', Articles: 'Artikel', Highlights: 'Highlights', diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index b2ef8c42..050e9815 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -385,6 +385,8 @@ export default { "Don't remind me again": "Don't remind me again", Posts: 'Posts', 'Posts (OPs)': 'Posts (OPs)', + 'Kind 1 replies': 'Kind 1 replies', + 'Comments': 'Comments', 'Replies & comments': 'Replies & comments', Articles: 'Articles', Highlights: 'Highlights', diff --git a/src/providers/KindFilterProvider.tsx b/src/providers/KindFilterProvider.tsx index 038113ba..056900ee 100644 --- a/src/providers/KindFilterProvider.tsx +++ b/src/providers/KindFilterProvider.tsx @@ -6,26 +6,29 @@ import { kinds } from 'nostr-tools' const KIND_1 = kinds.ShortTextNote const KIND_1111 = ExtendedKind.COMMENT -/** Build showKinds array from base kinds (excluding 1 and 1111) plus the two post/reply flags */ +/** Build showKinds array from base kinds (excluding 1 and 1111) plus kind 1 OP/reply and kind 1111 flags */ function buildShowKinds( baseKinds: number[], showKind1OPs: boolean, - showRepliesAndComments: boolean + showKind1Replies: boolean, + showKind1111: boolean ): number[] { const rest = baseKinds.filter((k) => k !== KIND_1 && k !== KIND_1111) const out = [...rest] - if (showKind1OPs || showRepliesAndComments) out.push(KIND_1) - if (showRepliesAndComments) out.push(KIND_1111) + if (showKind1OPs || showKind1Replies) out.push(KIND_1) + if (showKind1111) out.push(KIND_1111) return out.sort((a, b) => a - b) } type TKindFilterContext = { showKinds: number[] showKind1OPs: boolean - showRepliesAndComments: boolean - updateShowKinds: (kinds: number[], options?: { showKind1OPs?: boolean; showRepliesAndComments?: boolean }) => void + showKind1Replies: boolean + showKind1111: boolean + updateShowKinds: (kinds: number[], options?: { showKind1OPs?: boolean; showKind1Replies?: boolean; showKind1111?: boolean }) => void updateShowKind1OPs: (value: boolean) => void - updateShowRepliesAndComments: (value: boolean) => void + updateShowKind1Replies: (value: boolean) => void + updateShowKind1111: (value: boolean) => void } const KindFilterContext = createContext(undefined) @@ -48,22 +51,27 @@ export function KindFilterProvider({ children }: { children: React.ReactNode }) ) const storedShowKinds = storage.getShowKinds() const storedShowKind1OPs = storage.getShowKind1OPs() - const storedShowRepliesAndComments = storage.getShowRepliesAndComments() + const storedShowKind1Replies = storage.getShowKind1Replies() + const storedShowKind1111 = storage.getShowKind1111() const [showKinds, setShowKindsState] = useState( storedShowKinds.length > 0 ? storedShowKinds : defaultShowKinds ) const [showKind1OPs, setShowKind1OPsState] = useState(storedShowKind1OPs) - const [showRepliesAndComments, setShowRepliesAndCommentsState] = useState(storedShowRepliesAndComments) + const [showKind1Replies, setShowKind1RepliesState] = useState(storedShowKind1Replies) + const [showKind1111, setShowKind1111State] = useState(storedShowKind1111) const updateShowKinds = useCallback( - (newKinds: number[], options?: { showKind1OPs?: boolean; showRepliesAndComments?: boolean }) => { + (newKinds: number[], options?: { showKind1OPs?: boolean; showKind1Replies?: boolean; showKind1111?: boolean }) => { const op = options?.showKind1OPs ?? newKinds.includes(KIND_1) - const replies = options?.showRepliesAndComments ?? newKinds.includes(KIND_1111) + const kind1Replies = options?.showKind1Replies ?? newKinds.includes(KIND_1) + const kind1111 = options?.showKind1111 ?? newKinds.includes(KIND_1111) storage.setShowKind1OPs(op) - storage.setShowRepliesAndComments(replies) + storage.setShowKind1Replies(kind1Replies) + storage.setShowKind1111(kind1111) setShowKind1OPsState(op) - setShowRepliesAndCommentsState(replies) + setShowKind1RepliesState(kind1Replies) + setShowKind1111State(kind1111) storage.setShowKinds(newKinds) setShowKindsState(newKinds) }, @@ -73,29 +81,39 @@ export function KindFilterProvider({ children }: { children: React.ReactNode }) const updateShowKind1OPs = useCallback((value: boolean) => { storage.setShowKind1OPs(value) setShowKind1OPsState(value) - const next = buildShowKinds(showKinds, value, showRepliesAndComments) + const next = buildShowKinds(showKinds, value, showKind1Replies, showKind1111) storage.setShowKinds(next) setShowKindsState(next) - }, [showKinds, showRepliesAndComments]) + }, [showKinds, showKind1Replies, showKind1111]) - const updateShowRepliesAndComments = useCallback((value: boolean) => { - storage.setShowRepliesAndComments(value) - setShowRepliesAndCommentsState(value) - const next = buildShowKinds(showKinds, showKind1OPs, value) + const updateShowKind1Replies = useCallback((value: boolean) => { + storage.setShowKind1Replies(value) + setShowKind1RepliesState(value) + const next = buildShowKinds(showKinds, showKind1OPs, value, showKind1111) storage.setShowKinds(next) setShowKindsState(next) - }, [showKinds, showKind1OPs]) + }, [showKinds, showKind1OPs, showKind1111]) + + const updateShowKind1111 = useCallback((value: boolean) => { + storage.setShowKind1111(value) + setShowKind1111State(value) + const next = buildShowKinds(showKinds, showKind1OPs, showKind1Replies, value) + storage.setShowKinds(next) + setShowKindsState(next) + }, [showKinds, showKind1OPs, showKind1Replies]) const value = useMemo( () => ({ showKinds, showKind1OPs, - showRepliesAndComments, + showKind1Replies, + showKind1111, updateShowKinds, updateShowKind1OPs, - updateShowRepliesAndComments + updateShowKind1Replies, + updateShowKind1111 }), - [showKinds, showKind1OPs, showRepliesAndComments, updateShowKinds, updateShowKind1OPs, updateShowRepliesAndComments] + [showKinds, showKind1OPs, showKind1Replies, showKind1111, updateShowKinds, updateShowKind1OPs, updateShowKind1Replies, updateShowKind1111] ) return {children} diff --git a/src/services/local-storage.service.ts b/src/services/local-storage.service.ts index af00221e..b6d3458a 100644 --- a/src/services/local-storage.service.ts +++ b/src/services/local-storage.service.ts @@ -49,7 +49,8 @@ class LocalStorageService { private dismissedTooManyRelaysAlert: boolean = false private showKinds: number[] = [] private showKind1OPs: boolean = true - private showRepliesAndComments: boolean = true + private showKind1Replies: boolean = true + private showKind1111: boolean = true private hideContentMentioningMutedUsers: boolean = false private notificationListStyle: TNotificationStyle = NOTIFICATION_LIST_STYLE.DETAILED private mediaAutoLoadPolicy: TMediaAutoLoadPolicy = MEDIA_AUTO_LOAD_POLICY.ALWAYS @@ -243,18 +244,29 @@ class LocalStorageService { window.localStorage.setItem(StorageKey.SHOW_KINDS, JSON.stringify(this.showKinds)) window.localStorage.setItem(StorageKey.SHOW_KINDS_VERSION, '6') - // Feed filter: kind 1 OPs vs replies+comments (migrate from showKinds if not set) + // Feed filter: kind 1 OPs, kind 1 replies, kind 1111 (migrate from legacy showRepliesAndComments if set) const showKind1OPsStr = window.localStorage.getItem(StorageKey.SHOW_KIND_1_OPs) const showRepliesStr = window.localStorage.getItem(StorageKey.SHOW_REPLIES_AND_COMMENTS) + const showKind1RepliesStr = window.localStorage.getItem(StorageKey.SHOW_KIND_1_REPLIES) + const showKind1111Str = window.localStorage.getItem(StorageKey.SHOW_KIND_1111) if (showKind1OPsStr !== null) { this.showKind1OPs = showKind1OPsStr === 'true' } else { this.showKind1OPs = this.showKinds.includes(kinds.ShortTextNote) } - if (showRepliesStr !== null) { - this.showRepliesAndComments = showRepliesStr === 'true' + if (showKind1RepliesStr !== null) { + this.showKind1Replies = showKind1RepliesStr === 'true' + } else if (showRepliesStr !== null) { + this.showKind1Replies = showRepliesStr === 'true' } else { - this.showRepliesAndComments = this.showKinds.includes(ExtendedKind.COMMENT) + this.showKind1Replies = this.showKinds.includes(kinds.ShortTextNote) + } + if (showKind1111Str !== null) { + this.showKind1111 = showKind1111Str === 'true' + } else if (showRepliesStr !== null) { + this.showKind1111 = showRepliesStr === 'true' + } else { + this.showKind1111 = this.showKinds.includes(ExtendedKind.COMMENT) } this.hideContentMentioningMutedUsers = @@ -594,13 +606,22 @@ class LocalStorageService { window.localStorage.setItem(StorageKey.SHOW_KIND_1_OPs, value.toString()) } - getShowRepliesAndComments(): boolean { - return this.showRepliesAndComments + getShowKind1Replies(): boolean { + return this.showKind1Replies + } + + setShowKind1Replies(value: boolean) { + this.showKind1Replies = value + window.localStorage.setItem(StorageKey.SHOW_KIND_1_REPLIES, value.toString()) + } + + getShowKind1111(): boolean { + return this.showKind1111 } - setShowRepliesAndComments(value: boolean) { - this.showRepliesAndComments = value - window.localStorage.setItem(StorageKey.SHOW_REPLIES_AND_COMMENTS, value.toString()) + setShowKind1111(value: boolean) { + this.showKind1111 = value + window.localStorage.setItem(StorageKey.SHOW_KIND_1111, value.toString()) } getHideContentMentioningMutedUsers() {