From 6538fd0f26b91a8ba51062ad02e30eec0ab2467f Mon Sep 17 00:00:00 2001 From: Silberengel Date: Mon, 25 May 2026 12:22:01 +0200 Subject: [PATCH] bug-fixes remove emojito link remove quiet tag functionality remove untrusted interactions functionality --- src/App.tsx | 3 - .../HideUntrustedContentButton/index.tsx | 77 ---------- .../InBrowserCacheSetting/index.tsx | 83 +---------- src/components/NormalFeed/index.tsx | 3 - src/components/Note/MoneroTip.tsx | 4 - src/components/Note/Zap.tsx | 7 - src/components/Note/index.tsx | 4 +- src/components/NoteBoostBadges/index.tsx | 3 +- src/components/NoteInteractions/index.tsx | 8 - src/components/NoteList/index.tsx | 6 - src/components/NoteStats/LikeButton.tsx | 12 +- .../NoteStats/NoteStatsCountHover.tsx | 23 +-- src/components/NoteStats/ReplyButton.tsx | 8 +- src/components/NoteStats/RepostButton.tsx | 8 +- src/components/NoteStats/index.tsx | 11 +- src/components/PostEditor/PostContent.tsx | 41 +----- src/components/Profile/ProfileFeed.tsx | 1 - .../RelayInfo/RelayReviewsPreview.tsx | 6 +- src/components/ReplyNoteList/index.tsx | 16 -- src/components/RssUrlThreadStatsBar/index.tsx | 19 +-- src/components/Sidebar/index.tsx | 14 +- src/constants.ts | 7 - src/contexts/user-trust-context.tsx | 27 ---- src/hooks/useConsoleLogBuffer.ts | 19 +++ src/index.css | 21 +++ src/lib/console-log-buffer.ts | 131 +++++++++++++++++ src/lib/draft-event.ts | 76 ---------- src/lib/event-filtering.ts | 36 ----- src/lib/note-stats-interactors.ts | 10 -- src/main.tsx | 1 + src/pages/primary/SpellsPage/index.tsx | 7 - .../secondary/GeneralSettingsPage/index.tsx | 29 ---- .../PostSettingsPage/QuietSettings.tsx | 108 -------------- .../secondary/PostSettingsPage/index.tsx | 5 - src/providers/UserTrustProvider.tsx | 100 ------------- src/services/local-storage.service.ts | 138 +----------------- 36 files changed, 218 insertions(+), 854 deletions(-) delete mode 100644 src/components/HideUntrustedContentButton/index.tsx delete mode 100644 src/contexts/user-trust-context.tsx create mode 100644 src/hooks/useConsoleLogBuffer.ts create mode 100644 src/lib/console-log-buffer.ts delete mode 100644 src/pages/secondary/PostSettingsPage/QuietSettings.tsx delete mode 100644 src/providers/UserTrustProvider.tsx diff --git a/src/App.tsx b/src/App.tsx index 519f30ee..189abffd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -23,7 +23,6 @@ import { ScreenSizeProvider } from '@/providers/ScreenSizeProvider' import { ThemeProvider } from '@/providers/ThemeProvider' import { LiveActivitiesProvider } from '@/providers/LiveActivitiesProvider' import { UserPreferencesProvider } from '@/providers/UserPreferencesProvider' -import { UserTrustProvider } from '@/providers/UserTrustProvider' import { ZapProvider } from '@/providers/ZapProvider' import SlowConnectionHint from '@/components/SlowConnectionHint' import StartupSessionBanner from '@/components/StartupSessionBanner' @@ -51,7 +50,6 @@ export default function App(): JSX.Element { - @@ -71,7 +69,6 @@ export default function App(): JSX.Element { - diff --git a/src/components/HideUntrustedContentButton/index.tsx b/src/components/HideUntrustedContentButton/index.tsx deleted file mode 100644 index 44a5b33d..00000000 --- a/src/components/HideUntrustedContentButton/index.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, - AlertDialogTrigger -} from '@/components/ui/alert-dialog' -import { Button, buttonVariants } from '@/components/ui/button' -import { useUserTrust } from '@/contexts/user-trust-context' -import { VariantProps } from 'class-variance-authority' -import { Shield, ShieldCheck } from 'lucide-react' -import { useTranslation } from 'react-i18next' - -export default function HideUntrustedContentButton({ - type, - size = 'icon' -}: { - type: 'interactions' | 'notifications' - size?: VariantProps['size'] -}) { - const { t } = useTranslation() - const { - hideUntrustedInteractions, - hideUntrustedNotifications, - updateHideUntrustedInteractions, - updateHideUntrustedNotifications - } = useUserTrust() - - const enabled = type === 'interactions' ? hideUntrustedInteractions : hideUntrustedNotifications - - const updateEnabled = - type === 'interactions' ? updateHideUntrustedInteractions : updateHideUntrustedNotifications - - const typeText = t(type) - - return ( - - - - - - - - {enabled - ? t('Show untrusted {type}', { type: typeText }) - : t('Hide untrusted {type}', { type: typeText })} - - - {enabled - ? t('Currently hiding {type} from untrusted users.', { type: typeText }) - : t('Currently showing all {type}.', { type: typeText })}{' '} - {t('Trusted users include people you follow and people they follow.')}{' '} - {enabled - ? t('Click continue to show all {type}.', { type: typeText }) - : t('Click continue to hide {type} from untrusted users.', { type: typeText })} - - - - {t('Cancel')} - updateEnabled(!enabled)}> - {t('Continue')} - - - - - ) -} diff --git a/src/components/InBrowserCacheSetting/index.tsx b/src/components/InBrowserCacheSetting/index.tsx index 6c5d29d9..12cd6e7e 100644 --- a/src/components/InBrowserCacheSetting/index.tsx +++ b/src/components/InBrowserCacheSetting/index.tsx @@ -1,7 +1,9 @@ import { Button } from '@/components/ui/button' +import { clearConsoleLogBuffer } from '@/lib/console-log-buffer' +import { useConsoleLogBuffer } from '@/hooks/useConsoleLogBuffer' import logger from '@/lib/logger' import { useNostr } from '@/providers/NostrProvider' -import { useEffect, useState, useMemo, useRef } from 'react' +import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { Trash2, RefreshCw, Database, X, Terminal, XCircle } from 'lucide-react' import { Input } from '@/components/ui/input' @@ -25,12 +27,11 @@ export default function InBrowserCacheSetting() { requestAccountNetworkHydrate } = useNostr() const { openBrowseCache } = useCacheBrowser() - const [consoleLogs, setConsoleLogs] = useState; timestamp: number }>>([]) + const consoleLogs = useConsoleLogBuffer() const [showConsoleLogs, setShowConsoleLogs] = useState(false) const [consoleLogSearch, setConsoleLogSearch] = useState('') const [consoleLogLevel, setConsoleLogLevel] = useState<'errors-warnings' | 'all'>('all') const [cacheRefreshBusy, setCacheRefreshBusy] = useState(false) - const consoleLogRef = useRef; timestamp: number }>>([]) const handleClearCache = async () => { if (!confirm(t('Are you sure you want to clear all cached data? This will delete all stored events and settings from your browser.'))) { @@ -189,86 +190,14 @@ export default function InBrowserCacheSetting() { } } - useEffect(() => { - const originalLog = console.log - const originalError = console.error - const originalWarn = console.warn - const originalInfo = console.info - - const captureLog = (type: string, ...args: any[]) => { - let message = '' - let formattedParts: Array<{ text: string; style?: string }> = [] - - if (args.length > 0 && typeof args[0] === 'string' && args[0].includes('%c')) { - const formatString = args[0] - const parts = formatString.split(/%c/g) - formattedParts = [] - - for (let i = 0; i < parts.length; i++) { - const text = parts[i] - const style = i < args.length - 1 && typeof args[i + 1] === 'string' ? args[i + 1] : undefined - formattedParts.push({ text, style }) - } - - const remainingArgs = args.slice(parts.length) - if (remainingArgs.length > 0) { - const remainingText = remainingArgs.map(arg => { - if (typeof arg === 'object') { - try { return JSON.stringify(arg, null, 2) } catch { return String(arg) } - } - return String(arg) - }).join(' ') - if (formattedParts.length > 0) { - formattedParts[formattedParts.length - 1].text += ' ' + remainingText - } else { - formattedParts.push({ text: remainingText }) - } - } - - message = formattedParts.map(p => p.text).join('') - } else { - message = args.map(arg => { - if (typeof arg === 'object') { - try { return JSON.stringify(arg, null, 2) } catch { return String(arg) } - } - return String(arg) - }).join(' ') - formattedParts = [{ text: message }] - } - - const logEntry = { type, message, formattedParts, timestamp: Date.now() } - consoleLogRef.current.push(logEntry) - if (consoleLogRef.current.length > 1000) { - consoleLogRef.current = consoleLogRef.current.slice(-1000) - } - if (showConsoleLogs) { - setConsoleLogs([...consoleLogRef.current]) - } - } - - console.log = (...args: any[]) => { captureLog('log', ...args); originalLog.apply(console, args) } - console.error = (...args: any[]) => { captureLog('error', ...args); originalError.apply(console, args) } - console.warn = (...args: any[]) => { captureLog('warn', ...args); originalWarn.apply(console, args) } - console.info = (...args: any[]) => { captureLog('info', ...args); originalInfo.apply(console, args) } - - return () => { - console.log = originalLog - console.error = originalError - console.warn = originalWarn - console.info = originalInfo - } - }, [showConsoleLogs]) - const handleShowConsoleLogs = () => { - setConsoleLogs([...consoleLogRef.current]) setShowConsoleLogs(true) setConsoleLogSearch('') setConsoleLogLevel('all') } const handleClearConsoleLogs = () => { - consoleLogRef.current = [] - setConsoleLogs([]) + clearConsoleLogBuffer() toast.success(t('Console logs cleared')) } @@ -406,7 +335,7 @@ export default function InBrowserCacheSetting() { diff --git a/src/components/NormalFeed/index.tsx b/src/components/NormalFeed/index.tsx index 7e3a5ec7..649362d4 100644 --- a/src/components/NormalFeed/index.tsx +++ b/src/components/NormalFeed/index.tsx @@ -4,7 +4,6 @@ import { RefreshButton } from '@/components/RefreshButton' import Tabs, { TabDefinition } from '@/components/Tabs' import { useGlobalRelayBootstrapDefaults } from '@/hooks/use-global-relay-bootstrap-defaults' import { useKindFilterOrDefaults } from '@/providers/KindFilterProvider' -import { useUserTrust } from '@/contexts/user-trust-context' import { PROFILE_MEDIA_TAB_KINDS, FAST_READ_RELAY_URLS } from '@/constants' import { isWispTrendingNotesRelayUrl } from '@/lib/wisp-trending-relay' import type { TPrimaryPageName } from '@/PageManager' @@ -170,7 +169,6 @@ const NormalFeed = forwardRef { window.location.href = url }) - const inQuietMode = targetEvent ? shouldHideInteractions(targetEvent) : false - if (inQuietMode) return null - if (!tipInfo || !tipInfo.senderPubkey) { return (
diff --git a/src/components/Note/Zap.tsx b/src/components/Note/Zap.tsx index 50ccf96a..0acd545e 100644 --- a/src/components/Note/Zap.tsx +++ b/src/components/Note/Zap.tsx @@ -1,7 +1,6 @@ import { useFetchEvent } from '@/hooks' import { usePaymentAttestationStatus } from '@/hooks/usePaymentAttestationStatus' import { getZapInfoFromEvent } from '@/lib/event-metadata' -import { shouldHideInteractions } from '@/lib/event-filtering' import { formatAmount } from '@/lib/lightning' import { openNoteFromFetchOrCache } from '@/lib/navigation-related-events' import { relayHintsFromEventTags } from '@/lib/relay-list-builder' @@ -64,12 +63,6 @@ export default function Zap({ const secondaryPage = useSecondaryPageOptional() const push = secondaryPage?.push ?? ((url: string) => { window.location.href = url }) - const inQuietMode = targetEvent ? shouldHideInteractions(targetEvent) : false - - if (inQuietMode) { - return null - } - if (!zapInfo || !zapInfo.senderPubkey) { return (
diff --git a/src/components/Note/index.tsx b/src/components/Note/index.tsx index 874753c0..ee750ba8 100644 --- a/src/components/Note/index.tsx +++ b/src/components/Note/index.tsx @@ -8,7 +8,6 @@ import { isNip25ReactionKind, isNsfwEvent } from '@/lib/event' -import { shouldHideInteractions } from '@/lib/event-filtering' import { mergeNip84MarkedIntervals, renderPlaintextWithNip84MergedMarks } from '@/lib/nip84-op-body-marks' import { getCachedThreadContextEvents } from '@/lib/navigation-related-events' import { relayHintsFromEventTags } from '@/lib/relay-list-builder' @@ -383,8 +382,7 @@ export default function Note({ } if ( nip84HighlightEvents?.length && - displayEvent.kind === kinds.ShortTextNote && - !shouldHideInteractions(displayEvent) + displayEvent.kind === kinds.ShortTextNote ) { const merged = mergeNip84MarkedIntervals( displayEvent.content ?? '', diff --git a/src/components/NoteBoostBadges/index.tsx b/src/components/NoteBoostBadges/index.tsx index 7d98645c..132caea9 100644 --- a/src/components/NoteBoostBadges/index.tsx +++ b/src/components/NoteBoostBadges/index.tsx @@ -1,6 +1,5 @@ import { ExtendedKind } from '@/constants' import { useNoteStatsById } from '@/hooks/useNoteStatsById' -import { shouldHideInteractions } from '@/lib/event-filtering' import { cn } from '@/lib/utils' import { Event } from 'nostr-tools' import { useMemo } from 'react' @@ -22,7 +21,7 @@ export default function NoteBoostBadges({ event, className }: { event: Event; cl return [...(noteStats?.reposts ?? [])].sort((a, b) => b.created_at - a.created_at) }, [noteStats, event.kind]) - if (shouldHideInteractions(event) || boosters.length === 0) { + if (boosters.length === 0) { return null } diff --git a/src/components/NoteInteractions/index.tsx b/src/components/NoteInteractions/index.tsx index 221f0002..7052222f 100644 --- a/src/components/NoteInteractions/index.tsx +++ b/src/components/NoteInteractions/index.tsx @@ -1,10 +1,8 @@ import { Separator } from '@/components/ui/separator' import { ExtendedKind } from '@/constants' -import { shouldHideInteractions } from '@/lib/event-filtering' import { Event } from 'nostr-tools' import { useState } from 'react' import { useTranslation } from 'react-i18next' -import HideUntrustedContentButton from '../HideUntrustedContentButton' import ReplyNoteList from '../ReplyNoteList' import ReplySort, { ReplySortOption } from './ReplySort' @@ -32,11 +30,6 @@ export default function NoteInteractions({ const isDiscussion = event.kind === ExtendedKind.DISCUSSION const showQuotes = showQuotesProp ?? !isDiscussion - // Hide interactions if event is in quiet mode - if (shouldHideInteractions(event)) { - return null - } - return ( <>
@@ -47,7 +40,6 @@ export default function NoteInteractions({ {isDiscussion && ( )} -
diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx index 8236176f..cd7dbf70 100644 --- a/src/components/NoteList/index.tsx +++ b/src/components/NoteList/index.tsx @@ -38,7 +38,6 @@ import { useDeletedEventSafe } from '@/providers/DeletedEventProvider' import { useMuteList } from '@/contexts/mute-list-context' import { muteSetHas } from '@/lib/mute-set' import { useNostr } from '@/providers/NostrProvider' -import { useUserTrust } from '@/contexts/user-trust-context' import client from '@/services/client.service' import noteStatsService from '@/services/note-stats.service' import indexedDb from '@/services/indexed-db.service' @@ -658,7 +657,6 @@ const NoteList = forwardRef( allowKindlessRelayExplore = false, filterMutedNotes = true, hideReplies = false, - hideUntrustedNotes = false, areAlgoRelays = false, relayCapabilityReady = true, pinnedEventIds = [], @@ -796,7 +794,6 @@ const NoteList = forwardRef( allowKindlessRelayExplore?: boolean filterMutedNotes?: boolean hideReplies?: boolean - hideUntrustedNotes?: boolean areAlgoRelays?: boolean /** * When false (e.g. home relay feed waiting on `getRelayInfos`), skip timeline subscribe so @@ -851,7 +848,6 @@ const NoteList = forwardRef( ) => { const { t } = useTranslation() const { startLogin, pubkey } = useNostr() - const { isUserTrusted } = useUserTrust() const { mutePubkeySet } = useMuteList() const contentPolicy = useContentPolicyOptional() const hideContentMentioningMutedUsers = contentPolicy?.hideContentMentioningMutedUsers ?? false @@ -1309,7 +1305,6 @@ const NoteList = forwardRef( if (pinnedEventHexIdSet.has(evt.id)) return true if (isEventDeleted(evt)) return true if (hideReplies && isReplyNoteEvent(evt)) return true - if (hideUntrustedNotes && !isUserTrusted(evt.pubkey)) return true if (filterMutedNotes && muteSetHas(mutePubkeySet, evt.pubkey)) return true if ( filterMutedNotes && @@ -1345,7 +1340,6 @@ const NoteList = forwardRef( [ filterMutedNotes, hideReplies, - hideUntrustedNotes, hideContentMentioningMutedUsers, mutePubkeySet, pinnedEventIds, diff --git a/src/components/NoteStats/LikeButton.tsx b/src/components/NoteStats/LikeButton.tsx index f9741e30..3f0baf50 100644 --- a/src/components/NoteStats/LikeButton.tsx +++ b/src/components/NoteStats/LikeButton.tsx @@ -9,7 +9,6 @@ import { Skeleton } from '@/components/ui/skeleton' import { ExtendedKind } from '@/constants' import { useNoteStatsById } from '@/hooks/useNoteStatsById' import { useReplyUnderDiscussionRoot } from '@/hooks/useReplyUnderDiscussionRoot' -import { shouldHideInteractions } from '@/lib/event-filtering' import { createDeletionRequestDraftEvent, createReactionDraftEvent } from '@/lib/draft-event' import { DISCUSSION_DOWNVOTE_DISPLAY, @@ -23,7 +22,6 @@ import { import { useNoteStatsRelayHints } from '@/hooks/useNoteStatsRelayHints' import { useNostr } from '@/providers/NostrProvider' import { useScreenSize } from '@/providers/ScreenSizeProvider' -import { useUserTrust } from '@/contexts/user-trust-context' import { eventService } from '@/services/client.service' import noteStatsService from '@/services/note-stats.service' import type { TNoteStats } from '@/services/note-stats.service' @@ -66,11 +64,9 @@ export function LikeButtonWithStats({ const { isSmallScreen } = useScreenSize() const { pubkey, publish, checkLogin } = useNostr() const { relays: statsRelays } = useNoteStatsRelayHints() - const { hideUntrustedInteractions, isUserTrusted } = useUserTrust() const [liking, setLiking] = useState(false) const [isEmojiReactionsOpen, setIsEmojiReactionsOpen] = useState(false) const isDiscussion = event.kind === ExtendedKind.DISCUSSION - const inQuietMode = shouldHideInteractions(event) const isReplyToDiscussion = isReplyToDiscussionProp ?? false const showDiscussionVotes = isDiscussion || isReplyToDiscussion @@ -78,9 +74,7 @@ export function LikeButtonWithStats({ const { myLastEmoji, likeCount, upVoteCount, downVoteCount } = useMemo(() => { const stats = noteStats || {} - const likes = hideUntrustedInteractions - ? stats.likes?.filter((like) => isUserTrusted(like.pubkey)) - : stats.likes + const likes = stats.likes const myLike = likes?.find((like) => { if (like.pubkey !== pubkey) return false @@ -101,7 +95,7 @@ export function LikeButtonWithStats({ upVoteCount, downVoteCount } - }, [noteStats, pubkey, hideUntrustedInteractions, showDiscussionVotes]) + }, [noteStats, pubkey, showDiscussionVotes]) /** Same idea as {@link ReplyButton}: merged likes (thread fetch / publish) can exist before snapshot sets `updatedAt`. */ const showLikeCount = !hideCount && (statsLoaded || (likeCount ?? 0) > 0) @@ -258,7 +252,7 @@ export function LikeButtonWithStats({ {liking ? ( ) : myLastEmoji && !useIconOnlyLikeTrigger ? ( - + ) : ( )} diff --git a/src/components/NoteStats/NoteStatsCountHover.tsx b/src/components/NoteStats/NoteStatsCountHover.tsx index 713a6d4f..d6a14814 100644 --- a/src/components/NoteStats/NoteStatsCountHover.tsx +++ b/src/components/NoteStats/NoteStatsCountHover.tsx @@ -14,14 +14,12 @@ import { aggregateZapsByPubkey, dedupeBoostersByPubkey, emojiStatsKey, - filterStatsInteractors, groupReactionsByEmoji, MAX_NOTE_STATS_INTERACTORS_SHOWN } from '@/lib/note-stats-interactors' import { cn } from '@/lib/utils' import type { TNoteStats } from '@/services/note-stats.service' import { useNoteFeedProfileContext } from '@/providers/NoteFeedProfileContext' -import { useUserTrust } from '@/contexts/user-trust-context' import { TEmoji } from '@/types' import { useMemo, useState, type PointerEvent, type ReactNode } from 'react' import { useTranslation } from 'react-i18next' @@ -240,11 +238,10 @@ export function BoostCountHover({ children: ReactNode }) { const { t } = useTranslation() - const { hideUntrustedInteractions, isUserTrusted } = useUserTrust() const pubkeys = useMemo(() => { - const filtered = filterStatsInteractors(noteStats?.reposts, hideUntrustedInteractions, isUserTrusted) + const filtered = noteStats?.reposts ?? [] return dedupeBoostersByPubkey(filtered).map((r) => r.pubkey) - }, [noteStats?.reposts, hideUntrustedInteractions, isUserTrusted]) + }, [noteStats?.reposts]) return ( { - let likes = filterStatsInteractors(noteStats?.likes, hideUntrustedInteractions, isUserTrusted) + let likes = noteStats?.likes ?? [] if (emojiFilter) likes = likes.filter((l) => emojiFilter(l.emoji)) return { groups: groupReactionsByEmoji(likes), title: titleProp ?? t('Liked by:') } - }, [noteStats?.likes, hideUntrustedInteractions, isUserTrusted, emojiFilter, titleProp, t]) + }, [noteStats?.likes, emojiFilter, titleProp, t]) const total = groups.reduce((n, g) => n + g.pubkeys.length, 0) @@ -303,10 +299,8 @@ export function DiscussionVoteCountHover({ const { t } = useTranslation() const emojiFilter = vote === 'up' ? isDiscussionUpvoteEmoji : isDiscussionDownvoteEmoji - const { hideUntrustedInteractions, isUserTrusted } = useUserTrust() const pubkeys = useMemo(() => { - const likes = filterStatsInteractors(noteStats?.likes, hideUntrustedInteractions, isUserTrusted) - .filter((l) => emojiFilter(l.emoji)) + const likes = (noteStats?.likes ?? []).filter((l) => emojiFilter(l.emoji)) const byPk = new Map() for (const l of likes) { const pk = l.pubkey.toLowerCase() @@ -316,7 +310,7 @@ export function DiscussionVoteCountHover({ return [...byPk.entries()] .sort((a, b) => b[1] - a[1]) .map(([pk]) => pk) - }, [noteStats?.likes, hideUntrustedInteractions, isUserTrusted, emojiFilter]) + }, [noteStats?.likes, emojiFilter]) const title = ( @@ -345,11 +339,10 @@ export function ZapCountHover({ children: ReactNode }) { const { t } = useTranslation() - const { hideUntrustedInteractions, isUserTrusted } = useUserTrust() const zappers = useMemo(() => { - const filtered = filterStatsInteractors(noteStats?.zaps, hideUntrustedInteractions, isUserTrusted) + const filtered = noteStats?.zaps ?? [] return aggregateZapsByPubkey(filtered) - }, [noteStats?.zaps, hideUntrustedInteractions, isUserTrusted]) + }, [noteStats?.zaps]) return ( { const hasReplied = pubkey ? noteStats?.replies?.some((reply) => reply.pubkey === pubkey) : false return { - replyCount: hideUntrustedInteractions - ? noteStats?.replies?.filter((reply) => isUserTrusted(reply.pubkey)).length ?? 0 - : noteStats?.replies?.length ?? 0, + replyCount: noteStats?.replies?.length ?? 0, hasReplied } - }, [noteStats, event.id, hideUntrustedInteractions, isUserTrusted, pubkey]) + }, [noteStats, event.id, pubkey]) const statsLoaded = noteStats?.updatedAt != null const replyCountLabel = statsLoaded ? replyCount >= 100 diff --git a/src/components/NoteStats/RepostButton.tsx b/src/components/NoteStats/RepostButton.tsx index dd58163e..c4fda1e2 100644 --- a/src/components/NoteStats/RepostButton.tsx +++ b/src/components/NoteStats/RepostButton.tsx @@ -15,7 +15,6 @@ import { cn } from '@/lib/utils' import { useNoteStatsRelayHints } from '@/hooks/useNoteStatsRelayHints' import { useNostr } from '@/providers/NostrProvider' import { useScreenSize } from '@/providers/ScreenSizeProvider' -import { useUserTrust } from '@/contexts/user-trust-context' import noteStatsService from '@/services/note-stats.service' import type { TNoteStats } from '@/services/note-stats.service' import { PencilLine, Repeat } from 'lucide-react' @@ -37,7 +36,6 @@ type RepostButtonProps = { export function RepostButtonWithStats({ event, hideCount = false, noteStats }: RepostButtonProps) { const { t } = useTranslation() const { isSmallScreen } = useScreenSize() - const { hideUntrustedInteractions, isUserTrusted } = useUserTrust() const { publish, checkLogin, pubkey } = useNostr() const { relays: statsRelays } = useNoteStatsRelayHints() const [reposting, setReposting] = useState(false) @@ -46,12 +44,10 @@ export function RepostButtonWithStats({ event, hideCount = false, noteStats }: R const statsLoaded = noteStats?.updatedAt != null const { repostCount, hasReposted } = useMemo(() => { return { - repostCount: hideUntrustedInteractions - ? noteStats?.reposts?.filter((repost) => isUserTrusted(repost.pubkey)).length - : noteStats?.reposts?.length, + repostCount: noteStats?.reposts?.length, hasReposted: pubkey ? noteStats?.repostPubkeySet?.has(pubkey) : false } - }, [noteStats, event.id, hideUntrustedInteractions, isUserTrusted]) + }, [noteStats, event.id, pubkey]) const showRepostCount = !hideCount && (statsLoaded || (repostCount ?? 0) > 0) const canRepost = !hasReposted && !reposting diff --git a/src/components/NoteStats/index.tsx b/src/components/NoteStats/index.tsx index 236305fe..b3382197 100644 --- a/src/components/NoteStats/index.tsx +++ b/src/components/NoteStats/index.tsx @@ -7,7 +7,6 @@ import { useRssUrlThreadQueryRelays } from '@/hooks/useRssUrlThreadQueryRelays' import noteStatsService from '@/services/note-stats.service' import { ExtendedKind } from '@/constants' import { useReplyUnderDiscussionRoot } from '@/hooks/useReplyUnderDiscussionRoot' -import { shouldHideInteractions } from '@/lib/event-filtering' import { normalizeAnyRelayUrl } from '@/lib/url' import { Event } from 'nostr-tools' import { useEffect, useRef, useState } from 'react' @@ -59,9 +58,6 @@ export default function NoteStats({ const isDiscussion = event.kind === ExtendedKind.DISCUSSION const isReplyToDiscussion = useReplyUnderDiscussionRoot(event) - // Hide interaction counts if event is in quiet mode - const hideInteractions = shouldHideInteractions(event) - /** Synthetic RSS article root: no boost/quote/zap bar entries that normal notes have. */ const isRssArticleRoot = event.kind === ExtendedKind.RSS_THREAD_ROOT /** Match {@link RssUrlThreadStatsBar}: inbox/favorites/fast-read merge — plain hints miss many #i indexers. */ @@ -119,19 +115,18 @@ export default function NoteStats({ const interactionButtons = ( <> - + {!isDiscussion && !isReplyToDiscussion && !isRssArticleRoot && ( - + )} {!isRssArticleRoot && ( - + )} ) diff --git a/src/components/PostEditor/PostContent.tsx b/src/components/PostEditor/PostContent.tsx index 4632bbac..d3a6fec2 100644 --- a/src/components/PostEditor/PostContent.tsx +++ b/src/components/PostEditor/PostContent.tsx @@ -801,7 +801,7 @@ export default function PostContent({ const createDraftEvent = useCallback(async (cleanedText: string): Promise => { const uploadImetaTagsOpt = mediaImetaTags.length > 0 ? mediaImetaTags : undefined - // Get expiration and quiet settings + // Get expiration settings const isChattingKind = (kind: number) => kind === kinds.ShortTextNote || kind === ExtendedKind.COMMENT || @@ -810,9 +810,6 @@ export default function PostContent({ const addExpirationTag = storage.getDefaultExpirationEnabled() const expirationMonths = storage.getDefaultExpirationMonths() - const addQuietTag = storage.getDefaultQuietEnabled() - const quietDays = storage.getDefaultQuietDays() - // Determine if we should use protected event tag let shouldUseProtectedEvent = false if (parentEvent) { @@ -828,8 +825,6 @@ export default function PostContent({ isNsfw, addExpirationTag: false, expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt }) } else if (parentEvent && parentEvent.kind === ExtendedKind.PUBLIC_MESSAGE) { @@ -839,8 +834,6 @@ export default function PostContent({ isNsfw, addExpirationTag: false, expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt }) } @@ -885,8 +878,6 @@ export default function PostContent({ isNsfw, addExpirationTag: addExpirationTag && isChattingKind(ExtendedKind.VOICE_COMMENT), expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt } ) @@ -907,8 +898,6 @@ export default function PostContent({ isNsfw, addExpirationTag: addExpirationTag && isChattingKind(ExtendedKind.VOICE), expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt } ) @@ -922,8 +911,6 @@ export default function PostContent({ isNsfw, addExpirationTag: false, expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt } ) @@ -938,8 +925,6 @@ export default function PostContent({ isNsfw, addExpirationTag: false, expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt } ) @@ -988,9 +973,7 @@ export default function PostContent({ addClientTag, isNsfw, addExpirationTag: false, - expirationMonths, - addQuietTag, - quietDays + expirationMonths }) } else if (isWikiArticle) { return await createWikiArticleDraftEvent(cleanedText, mentions, { @@ -1002,9 +985,7 @@ export default function PostContent({ addClientTag, isNsfw, addExpirationTag: false, - expirationMonths, - addQuietTag, - quietDays + expirationMonths }) } else if (isNostrSpecification) { const affectedKinds = parseNostrSpecAffectedKinds(nostrSpecAffectedKindRows) @@ -1017,9 +998,7 @@ export default function PostContent({ addClientTag, isNsfw, addExpirationTag: false, - expirationMonths, - addQuietTag, - quietDays + expirationMonths }) } else if (isPublicationContent) { return await createPublicationContentDraftEvent(cleanedText, mentions, { @@ -1031,9 +1010,7 @@ export default function PostContent({ addClientTag, isNsfw, addExpirationTag: false, - expirationMonths, - addQuietTag, - quietDays + expirationMonths }) } @@ -1119,8 +1096,6 @@ export default function PostContent({ isNsfw, addExpirationTag: false, expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt } ) @@ -1135,8 +1110,6 @@ export default function PostContent({ isNsfw, addExpirationTag: addExpirationTag && isChattingKind(ExtendedKind.COMMENT), expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt }) } @@ -1148,8 +1121,6 @@ export default function PostContent({ isNsfw, addExpirationTag: false, expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt }) } @@ -1162,8 +1133,6 @@ export default function PostContent({ isNsfw, addExpirationTag: addExpirationTag && isChattingKind(kinds.ShortTextNote), expirationMonths, - addQuietTag, - quietDays, mediaImetaTags: uploadImetaTagsOpt }) }, [ diff --git a/src/components/Profile/ProfileFeed.tsx b/src/components/Profile/ProfileFeed.tsx index b3ca9941..b45ca55d 100644 --- a/src/components/Profile/ProfileFeed.tsx +++ b/src/components/Profile/ProfileFeed.tsx @@ -136,7 +136,6 @@ const ProfileFeed = forwardRef< mergeTimelineWhenSubRequestFiltersMatch pinnedEventIds={pinnedEventIds} hideReplies={false} - hideUntrustedNotes={false} filterMutedNotes={false} showKind1OPs={showKind1OPs} showKind1Replies={showKind1Replies} diff --git a/src/components/RelayInfo/RelayReviewsPreview.tsx b/src/components/RelayInfo/RelayReviewsPreview.tsx index 74b6120d..48b5180e 100644 --- a/src/components/RelayInfo/RelayReviewsPreview.tsx +++ b/src/components/RelayInfo/RelayReviewsPreview.tsx @@ -26,7 +26,6 @@ import { cn, isTouchDevice } from '@/lib/utils' import { useMuteList } from '@/contexts/mute-list-context' import { muteSetHas } from '@/lib/mute-set' import { useNostr } from '@/providers/NostrProvider' -import { useUserTrust } from '@/contexts/user-trust-context' import { queryService } from '@/services/client.service' import { getSessionFeedSnapshot } from '@/services/session-feed-snapshot.service' import { WheelGesturesPlugin } from 'embla-carousel-wheel-gestures' @@ -42,7 +41,6 @@ export default function RelayReviewsPreview({ relayUrl }: { relayUrl: string }) const { push } = useSecondaryPage() const { pubkey, checkLogin, relayList } = useNostr() const { favoriteRelays, blockedRelays } = useFavoriteRelays() - const { hideUntrustedNotes, isUserTrusted } = useUserTrust() const { mutePubkeySet } = useMuteList() const [showEditor, setShowEditor] = useState(false) const [myReview, setMyReview] = useState(null) @@ -68,7 +66,6 @@ export default function RelayReviewsPreview({ relayUrl }: { relayUrl: string }) const ingestReviewEvent = useCallback( (evt: NostrEvent) => { if (muteSetHas(mutePubkeySet, evt.pubkey)) return - if (hideUntrustedNotes && !isUserTrusted(evt.pubkey)) return const stars = getStarsFromRelayReviewEvent(evt) if (!stars) return @@ -84,7 +81,7 @@ export default function RelayReviewsPreview({ relayUrl }: { relayUrl: string }) return [...filtered, evt].sort((a, b) => compareEvents(b, a)) }) }, - [pubkey, mutePubkeySet, hideUntrustedNotes, isUserTrusted] + [pubkey, mutePubkeySet] ) useEffect(() => { @@ -104,7 +101,6 @@ export default function RelayReviewsPreview({ relayUrl }: { relayUrl: string }) if (evt.kind !== ExtendedKind.RELAY_REVIEW || !relayReviewEventTargetsRelay(evt, relayUrl)) continue if (muteSetHas(mutePubkeySet, evt.pubkey)) continue - if (hideUntrustedNotes && !isUserTrusted(evt.pubkey)) continue const st = getStarsFromRelayReviewEvent(evt) if (!st) continue if (pubkey && evt.pubkey === pubkey) { diff --git a/src/components/ReplyNoteList/index.tsx b/src/components/ReplyNoteList/index.tsx index 3f6e2731..abfac536 100644 --- a/src/components/ReplyNoteList/index.tsx +++ b/src/components/ReplyNoteList/index.tsx @@ -30,7 +30,6 @@ import { useContentPolicy } from '@/providers/ContentPolicyProvider' import { useMuteList } from '@/contexts/mute-list-context' import { useNostr } from '@/providers/NostrProvider' import { useReplyIngress } from '@/hooks/useReplyIngress' -import { useUserTrust } from '@/contexts/user-trust-context' import { useCurrentRelays } from '@/providers/CurrentRelaysProvider' import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider' import { @@ -109,7 +108,6 @@ function ReplyNoteList({ }) { const { t } = useTranslation() const { navigateToNote } = useSmartNoteNavigation() - const { hideUntrustedInteractions, isUserTrusted, isTrustLoaded } = useUserTrust() const noteStats = useNoteStatsById(event.id) const { mutePubkeySet } = useMuteList() const { hideContentMentioningMutedUsers } = useContentPolicy() @@ -1138,26 +1136,12 @@ function ReplyNoteList({ if (isSuperchatKind(item.kind)) return true // Backlink rows (quotes, highlights, …): show even when author is not in the trust list. if (isQuote) return true - if (isTrustLoaded && hideUntrustedInteractions && !isUserTrusted(item.pubkey)) { - if (rootInfo?.type !== 'I') { - const repliesForThisReply = repliesMap.get(item.id) - if ( - !repliesForThisReply || - repliesForThisReply.events.every((evt) => !isUserTrusted(evt.pubkey)) - ) { - return false - } - } - } return true }, [ mutePubkeySet, hideContentMentioningMutedUsers, quoteUiIdSet, - isTrustLoaded, - hideUntrustedInteractions, - isUserTrusted, rootInfo?.type, repliesMap, event, diff --git a/src/components/RssUrlThreadStatsBar/index.tsx b/src/components/RssUrlThreadStatsBar/index.tsx index 5fa14782..9008dddd 100644 --- a/src/components/RssUrlThreadStatsBar/index.tsx +++ b/src/components/RssUrlThreadStatsBar/index.tsx @@ -1,5 +1,4 @@ import { useNoteStatsById } from '@/hooks/useNoteStatsById' -import { useUserTrust } from '@/contexts/user-trust-context' import { cn } from '@/lib/utils' import noteStatsService from '@/services/note-stats.service' import { useRssUrlThreadQueryRelays } from '@/hooks/useRssUrlThreadQueryRelays' @@ -21,7 +20,6 @@ export default function RssUrlThreadStatsBar({ const { relayUrls: statsRelays, relayMergeTier, currentRelaysKey } = useRssUrlThreadQueryRelays() const statsRelaysRef = useRef(statsRelays) statsRelaysRef.current = statsRelays - const { hideUntrustedInteractions, isUserTrusted } = useUserTrust() const noteStats = useNoteStatsById(event.id) const [loading, setLoading] = useState(false) @@ -38,23 +36,14 @@ export default function RssUrlThreadStatsBar({ const replies = noteStats?.replies ?? [] const likes = noteStats?.likes ?? [] const highlights = noteStats?.highlights ?? [] - const trustedReplyCount = hideUntrustedInteractions - ? replies.filter((r) => isUserTrusted(r.pubkey)).length - : replies.length - const trustedReactionCount = hideUntrustedInteractions - ? likes.filter((l) => isUserTrusted(l.pubkey)).length - : likes.length - const trustedHighlightCount = hideUntrustedInteractions - ? highlights.filter((h) => isUserTrusted(h.pubkey)).length - : highlights.length const bookmarkCountInner = noteStats?.bookmarkPubkeySet?.size ?? 0 return { - replyCount: trustedReplyCount, - reactionCount: trustedReactionCount, - highlightCount: trustedHighlightCount, + replyCount: replies.length, + reactionCount: likes.length, + highlightCount: highlights.length, bookmarkCount: bookmarkCountInner } - }, [noteStats, hideUntrustedInteractions, isUserTrusted]) + }, [noteStats]) return (
+
-
+
- {/* Full-bleed banner at xl: span entire sidebar column (undo pl-4 + pr-6) */} -
+ {/* Full-bleed banner at xl: cancel horizontal inset without widening scroll overflow */} +
@@ -50,7 +54,7 @@ export default function PrimaryPageSidebar() {
-
+
diff --git a/src/constants.ts b/src/constants.ts index 26d4c098..8b79c8b5 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -341,10 +341,7 @@ export const StorageKey = { /** Per-pubkey ms timestamps: last full network hydrate (see ACCOUNT_SESSION_NETWORK_HYDRATE_MIN_INTERVAL_MS). */ ACCOUNT_NETWORK_HYDRATE_AT_MAP: 'accountNetworkHydrateAtMap', AUTOPLAY: 'autoplay', - HIDE_UNTRUSTED_INTERACTIONS: 'hideUntrustedInteractions', - HIDE_UNTRUSTED_NOTIFICATIONS: 'hideUntrustedNotifications', MEDIA_UPLOAD_SERVICE_CONFIG_MAP: 'mediaUploadServiceConfigMap', - HIDE_UNTRUSTED_NOTES: 'hideUntrustedNotes', DEFAULT_SHOW_NSFW: 'defaultShowNsfw', DISMISSED_TOO_MANY_RELAYS_ALERT: 'dismissedTooManyRelaysAlert', SHOW_KINDS: 'showKinds', @@ -363,10 +360,6 @@ export const StorageKey = { SHOW_RECOMMENDED_RELAYS_PANEL: 'showRecommendedRelaysPanel', DEFAULT_EXPIRATION_ENABLED: 'defaultExpirationEnabled', DEFAULT_EXPIRATION_MONTHS: 'defaultExpirationMonths', - DEFAULT_QUIET_ENABLED: 'defaultQuietEnabled', - DEFAULT_QUIET_DAYS: 'defaultQuietDays', - RESPECT_QUIET_TAGS: 'respectQuietTags', - GLOBAL_QUIET_MODE: 'globalQuietMode', SHOW_RSS_FEED: 'showRssFeed', PANE_MODE: 'paneMode', ADD_RANDOM_RELAYS_TO_PUBLISH: 'addRandomRelaysToPublish', diff --git a/src/contexts/user-trust-context.tsx b/src/contexts/user-trust-context.tsx deleted file mode 100644 index 8c8d6294..00000000 --- a/src/contexts/user-trust-context.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { createContext, useContext } from 'react' - -export type TUserTrustContext = { - isTrustLoaded: boolean - hideUntrustedInteractions: boolean - hideUntrustedNotifications: boolean - hideUntrustedNotes: boolean - updateHideUntrustedInteractions: (hide: boolean) => void - updateHideUntrustedNotifications: (hide: boolean) => void - updateHideUntrustedNotes: (hide: boolean) => void - isUserTrusted: (pubkey: string) => boolean -} - -/** - * Lives in a dedicated module so lazy chunks (e.g. NoteListPage → NormalFeed) share the same - * context instance as App’s UserTrustProvider. Importing useUserTrust from UserTrustProvider into - * those chunks can duplicate the module and break Provider matching. - */ -export const UserTrustContext = createContext(undefined) - -export function useUserTrust(): TUserTrustContext { - const context = useContext(UserTrustContext) - if (!context) { - throw new Error('useUserTrust must be used within a UserTrustProvider') - } - return context -} diff --git a/src/hooks/useConsoleLogBuffer.ts b/src/hooks/useConsoleLogBuffer.ts new file mode 100644 index 00000000..b5959f9f --- /dev/null +++ b/src/hooks/useConsoleLogBuffer.ts @@ -0,0 +1,19 @@ +import { + getConsoleLogBuffer, + subscribeConsoleLogBuffer, + type ConsoleLogEntry +} from '@/lib/console-log-buffer' +import { useSyncExternalStore } from 'react' + +function subscribe(onStoreChange: () => void) { + return subscribeConsoleLogBuffer(onStoreChange) +} + +function getSnapshot(): ConsoleLogEntry[] { + return getConsoleLogBuffer() +} + +/** Live view of the global console log ring buffer (see Settings → Cache). */ +export function useConsoleLogBuffer(): ConsoleLogEntry[] { + return useSyncExternalStore(subscribe, getSnapshot, getSnapshot) +} diff --git a/src/index.css b/src/index.css index 292b33a1..66c3406d 100644 --- a/src/index.css +++ b/src/index.css @@ -297,6 +297,27 @@ border-right: 1px solid hsl(var(--sidebar-border)); } + /* Reserve a right gutter so the track sits beside labels, not over icons/text. */ + .imwald-sidebar__scroll { + direction: ltr; + scrollbar-gutter: stable; + scrollbar-width: thin; + } + .imwald-sidebar__scroll::-webkit-scrollbar { + width: 8px; + } + .imwald-sidebar__scroll::-webkit-scrollbar-thumb { + border-radius: 9999px; + background-color: hsl(var(--muted-foreground) / 0.35); + } + .imwald-sidebar__scroll::-webkit-scrollbar-thumb:hover { + background-color: hsl(var(--muted-foreground) / 0.5); + } + .imwald-sidebar__scroll::-webkit-scrollbar-track { + border-radius: 9999px; + background-color: hsl(var(--muted) / 0.35); + } + .imwald-sidebar__atmosphere { position: absolute; inset: 0; diff --git a/src/lib/console-log-buffer.ts b/src/lib/console-log-buffer.ts new file mode 100644 index 00000000..536f6dc7 --- /dev/null +++ b/src/lib/console-log-buffer.ts @@ -0,0 +1,131 @@ +export type ConsoleLogEntry = { + type: string + message: string + formattedParts?: Array<{ text: string; style?: string }> + timestamp: number +} + +const MAX_ENTRIES = 1000 + +const buffer: ConsoleLogEntry[] = [] +const listeners = new Set<() => void>() +let initialized = false + +function notifyListeners() { + for (const listener of listeners) { + listener() + } +} + +function formatArgs(args: unknown[]): { message: string; formattedParts: Array<{ text: string; style?: string }> } { + if (args.length > 0 && typeof args[0] === 'string' && args[0].includes('%c')) { + const formatString = args[0] + const parts = formatString.split(/%c/g) + const formattedParts: Array<{ text: string; style?: string }> = [] + + for (let i = 0; i < parts.length; i++) { + const text = parts[i] + const style = i < args.length - 1 && typeof args[i + 1] === 'string' ? String(args[i + 1]) : undefined + formattedParts.push({ text, style }) + } + + const remainingArgs = args.slice(parts.length) + if (remainingArgs.length > 0) { + const remainingText = remainingArgs + .map((arg) => { + if (typeof arg === 'object') { + try { + return JSON.stringify(arg, null, 2) + } catch { + return String(arg) + } + } + return String(arg) + }) + .join(' ') + if (formattedParts.length > 0) { + formattedParts[formattedParts.length - 1].text += ' ' + remainingText + } else { + formattedParts.push({ text: remainingText }) + } + } + + return { message: formattedParts.map((p) => p.text).join(''), formattedParts } + } + + const message = args + .map((arg) => { + if (typeof arg === 'object') { + try { + return JSON.stringify(arg, null, 2) + } catch { + return String(arg) + } + } + return String(arg) + }) + .join(' ') + + return { message, formattedParts: [{ text: message }] } +} + +function captureLog(type: string, ...args: unknown[]) { + const { message, formattedParts } = formatArgs(args) + buffer.push({ type, message, formattedParts, timestamp: Date.now() }) + if (buffer.length > MAX_ENTRIES) { + buffer.splice(0, buffer.length - MAX_ENTRIES) + } + notifyListeners() +} + +/** Ring buffer of recent console output (installed at app startup). */ +export function getConsoleLogBuffer(): ConsoleLogEntry[] { + return [...buffer] +} + +export function clearConsoleLogBuffer() { + buffer.length = 0 + notifyListeners() +} + +export function subscribeConsoleLogBuffer(listener: () => void): () => void { + listeners.add(listener) + return () => listeners.delete(listener) +} + +/** Wrap console.* after other patches (e.g. error-suppression) so all output is retained. */ +export function initConsoleLogCapture() { + if (initialized || typeof window === 'undefined') return + initialized = true + + const originalLog = console.log.bind(console) + const originalError = console.error.bind(console) + const originalWarn = console.warn.bind(console) + const originalInfo = console.info.bind(console) + const originalDebug = console.debug.bind(console) + + console.log = (...args: unknown[]) => { + captureLog('log', ...args) + originalLog(...args) + } + console.error = (...args: unknown[]) => { + captureLog('error', ...args) + originalError(...args) + } + console.warn = (...args: unknown[]) => { + captureLog('warn', ...args) + originalWarn(...args) + } + console.info = (...args: unknown[]) => { + captureLog('info', ...args) + originalInfo(...args) + } + console.debug = (...args: unknown[]) => { + captureLog('debug', ...args) + originalDebug(...args) + } +} + +if (typeof window !== 'undefined') { + initConsoleLogCapture() +} diff --git a/src/lib/draft-event.ts b/src/lib/draft-event.ts index 3e66dd68..8af4d801 100644 --- a/src/lib/draft-event.ts +++ b/src/lib/draft-event.ts @@ -229,8 +229,6 @@ export async function createShortTextNoteDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number /** NIP-94 imeta rows from uploads (audio/video/images as plain URLs in content). */ mediaImetaTags?: string[][] } = {} @@ -280,9 +278,6 @@ export async function createShortTextNoteDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } const baseDraft = { kind: kinds.ShortTextNote, @@ -317,8 +312,6 @@ export async function createCommentDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number mediaImetaTags?: string[][] } = {} ): Promise { @@ -403,9 +396,6 @@ export async function createCommentDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } const baseDraft = { kind: ExtendedKind.COMMENT, @@ -425,8 +415,6 @@ export async function createPublicMessageReplyDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number mediaImetaTags?: string[][] // Allow media imeta tags for audio/video } = {} ): Promise { @@ -478,9 +466,6 @@ export async function createPublicMessageReplyDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } // console.log('📝 Final public message reply draft tags:', { // pTags: tags.filter(tag => tag[0] === 'p'), @@ -505,8 +490,6 @@ export async function createPublicMessageDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number mediaImetaTags?: string[][] // Allow media imeta tags for audio/video } = {} ): Promise { @@ -538,9 +521,6 @@ export async function createPublicMessageDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } const baseDraft = { kind: ExtendedKind.PUBLIC_MESSAGE, @@ -1146,16 +1126,12 @@ export async function createPollDraftEvent( isNsfw, addExpirationTag, expirationMonths, - addQuietTag, - quietDays, mediaImetaTags }: { addClientTag?: boolean // accepted for API compat; client tag is added in publish() isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number mediaImetaTags?: string[][] } = {} ): Promise { @@ -1210,9 +1186,6 @@ export async function createPollDraftEvent( tags.push(buildExpirationTag(expirationMonths)) } - if (addQuietTag && quietDays) { - tags.push(buildQuietTag(quietDays)) - } const baseDraft = { content: transformedEmojisContent.trim(), @@ -1658,10 +1631,6 @@ function buildExpirationTag(months: number): string[] { return ['expiration', expirationTime.toString()] } -function buildQuietTag(days: number): string[] { - const quietEndTime = dayjs().add(days, 'day').unix() - return ['quiet', quietEndTime.toString()] -} function trimTagEnd(tag: string[]) { let endIndex = tag.length - 1 @@ -1691,8 +1660,6 @@ export async function createHighlightDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number mediaImetaTags?: string[][] } ): Promise { @@ -1818,9 +1785,6 @@ export async function createHighlightDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options?.addQuietTag && options?.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } mergeUploadImetaTagsInto(tags, options?.mediaImetaTags) @@ -1843,8 +1807,6 @@ export async function createVoiceDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number /** Extra NIP-94 rows from uploads (merged after content-derived imeta, deduped by URL). */ mediaImetaTags?: string[][] } = {} @@ -1871,9 +1833,6 @@ export async function createVoiceDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } return setDraftEventCache({ kind: ExtendedKind.VOICE, @@ -1894,8 +1853,6 @@ export async function createVoiceCommentDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number /** NIP-94 rows from file upload (merged before `imetaTags`; deduped by URL). */ mediaImetaTags?: string[][] } = {} @@ -1979,9 +1936,6 @@ export async function createVoiceCommentDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } return setDraftEventCache({ kind: ExtendedKind.VOICE_COMMENT, @@ -2000,8 +1954,6 @@ export async function createPictureDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number mediaImetaTags?: string[][] } = {} ): Promise { @@ -2026,9 +1978,6 @@ export async function createPictureDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } // Kind 20 caption is user text only; the file URL lives in `imeta`. Many indexers and caches // still deliver full tags, but mirroring the URL in `content` matches kind-1-style clients and @@ -2060,8 +2009,6 @@ export async function createVideoDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number mediaImetaTags?: string[][] } = {} ): Promise { @@ -2086,9 +2033,6 @@ export async function createVideoDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } return setDraftEventCache({ kind: videoKind, // NIP-71: 21, 22, or 34235 @@ -2113,8 +2057,6 @@ export async function createLongFormArticleDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number } = {} ): Promise { const { content: transformedEmojisContent, emojiTags } = transformCustomEmojisInContent(content) @@ -2161,9 +2103,6 @@ export async function createLongFormArticleDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } return setDraftEventCache({ kind: kinds.LongFormArticle, @@ -2194,8 +2133,6 @@ export async function createWikiArticleDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number } ): Promise { const { content: transformedEmojisContent, emojiTags } = transformCustomEmojisInContent(content) @@ -2231,9 +2168,6 @@ export async function createWikiArticleDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } return setDraftEventCache({ kind: ExtendedKind.WIKI_ARTICLE, @@ -2256,8 +2190,6 @@ export async function createNostrSpecificationDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number } ): Promise { const { content: transformedEmojisContent, emojiTags } = transformCustomEmojisInContent(content) @@ -2295,9 +2227,6 @@ export async function createNostrSpecificationDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } return setDraftEventCache({ kind: ExtendedKind.NOSTR_SPECIFICATION, @@ -2319,8 +2248,6 @@ export async function createPublicationContentDraftEvent( isNsfw?: boolean addExpirationTag?: boolean expirationMonths?: number - addQuietTag?: boolean - quietDays?: number } ): Promise { const { content: transformedEmojisContent, emojiTags } = transformCustomEmojisInContent(content) @@ -2356,9 +2283,6 @@ export async function createPublicationContentDraftEvent( tags.push(buildExpirationTag(options.expirationMonths)) } - if (options.addQuietTag && options.quietDays) { - tags.push(buildQuietTag(options.quietDays)) - } return setDraftEventCache({ kind: ExtendedKind.PUBLICATION_CONTENT, diff --git a/src/lib/event-filtering.ts b/src/lib/event-filtering.ts index 954d6616..72041113 100644 --- a/src/lib/event-filtering.ts +++ b/src/lib/event-filtering.ts @@ -1,6 +1,5 @@ import { Event } from 'nostr-tools' import dayjs from 'dayjs' -import storage from '@/services/local-storage.service' /** * Check if an event has expired based on its expiration tag @@ -19,41 +18,6 @@ function isEventExpired(event: Event): boolean { return dayjs().unix() > expirationTime } -/** - * Check if an event is in quiet mode based on its quiet tag - */ -function isEventInQuietMode(event: Event): boolean { - const quietTag = event.tags.find(tag => tag[0] === 'quiet') - if (!quietTag || !quietTag[1]) { - return false - } - - const quietEndTime = parseInt(quietTag[1]) - if (isNaN(quietEndTime)) { - return false - } - - return dayjs().unix() < quietEndTime -} - -/** - * Check if interactions should be hidden for an event based on quiet settings - */ -export function shouldHideInteractions(event: Event): boolean { - // Check global quiet mode first - if (storage.getGlobalQuietMode()) { - return true - } - - // Check if we should respect quiet tags - if (!storage.getRespectQuietTags()) { - return false - } - - // Check if the event is in quiet mode - return isEventInQuietMode(event) -} - /** * Check if an event should be filtered out completely (expired) */ diff --git a/src/lib/note-stats-interactors.ts b/src/lib/note-stats-interactors.ts index cd58ef9a..1a12fdd8 100644 --- a/src/lib/note-stats-interactors.ts +++ b/src/lib/note-stats-interactors.ts @@ -3,16 +3,6 @@ import { TEmoji } from '@/types' export const MAX_NOTE_STATS_INTERACTORS_SHOWN = 32 -export function filterStatsInteractors( - items: T[] | undefined, - hideUntrusted: boolean, - isUserTrusted: (pk: string) => boolean -): T[] { - if (!items?.length) return [] - if (!hideUntrusted) return items - return items.filter((item) => isUserTrusted(item.pubkey)) -} - export function emojiStatsKey(emoji: TEmoji | string): string { return typeof emoji === 'string' ? emoji : emoji.shortcode } diff --git a/src/main.tsx b/src/main.tsx index 5edcfe96..4a63ca8b 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,6 +1,7 @@ import './index.css' import './polyfill' import './lib/error-suppression' +import './lib/console-log-buffer' import storage from './services/local-storage.service' import './services/lightning.service' import './lib/debug-utils' diff --git a/src/pages/primary/SpellsPage/index.tsx b/src/pages/primary/SpellsPage/index.tsx index 02ce0da0..8ff686db 100644 --- a/src/pages/primary/SpellsPage/index.tsx +++ b/src/pages/primary/SpellsPage/index.tsx @@ -1,4 +1,3 @@ -import HideUntrustedContentButton from '@/components/HideUntrustedContentButton' import NoteList, { type TNoteListRef } from '@/components/NoteList' import StoredAccountSwitchSelect from '@/components/StoredAccountSwitchSelect' import { RefreshButton } from '@/components/RefreshButton' @@ -29,7 +28,6 @@ import { useBookmarks } from '@/providers/bookmarks-context' import { useNostr } from '@/providers/NostrProvider' import { useNotificationThreadWatchOptional } from '@/providers/NotificationThreadWatchProvider' import { useScreenSize } from '@/providers/ScreenSizeProvider' -import { useUserTrust } from '@/contexts/user-trust-context' import { dedupeFollowSetEventsByD } from '@/lib/follow-set-spell' import client, { queryService } from '@/services/client.service' import indexedDb from '@/services/indexed-db.service' @@ -88,7 +86,6 @@ const SpellsPage = forwardRef(function SpellsPage( followListEvent } = useNostr() const { addBookmark, removeBookmark } = useBookmarks() - const { hideUntrustedNotifications } = useUserTrust() const notificationThreadWatch = useNotificationThreadWatchOptional() const eventsIFollowListEvent = notificationThreadWatch?.eventsIFollowListEvent ?? null const eventsIMutedListEvent = notificationThreadWatch?.eventsIMutedListEvent ?? null @@ -1054,7 +1051,6 @@ const SpellsPage = forwardRef(function SpellsPage( {notificationsFeedPubkey ? ( ) : null} -
) : null}
@@ -1105,9 +1101,6 @@ const SpellsPage = forwardRef(function SpellsPage( ? notificationsMentionExtraHide : undefined } - hideUntrustedNotes={ - selectedFauxSpell === 'notifications' ? hideUntrustedNotifications : false - } showPaymentAttestationAction={selectedFauxSpell === 'notifications'} />
diff --git a/src/pages/secondary/GeneralSettingsPage/index.tsx b/src/pages/secondary/GeneralSettingsPage/index.tsx index 402512c9..8aba8e9d 100644 --- a/src/pages/secondary/GeneralSettingsPage/index.tsx +++ b/src/pages/secondary/GeneralSettingsPage/index.tsx @@ -17,10 +17,8 @@ import { useContentPolicy } from '@/providers/ContentPolicyProvider' import { useFontSize } from '@/providers/FontSizeProvider' import { useTheme } from '@/providers/ThemeProvider' import { useUserPreferences } from '@/providers/UserPreferencesProvider' -import { useUserTrust } from '@/contexts/user-trust-context' import { TMediaAutoLoadPolicy } from '@/types' import { SelectValue } from '@radix-ui/react-select' -import { ExternalLink } from 'lucide-react' import { forwardRef, HTMLProps, useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -42,7 +40,6 @@ const GeneralSettingsPage = forwardRef(({ index, hideTitlebar = false }: { index mediaAutoLoadPolicy, setMediaAutoLoadPolicy } = useContentPolicy() - const { hideUntrustedNotes, updateHideUntrustedNotes } = useUserTrust() const { notificationListStyle, updateNotificationListStyle, @@ -202,16 +199,6 @@ const GeneralSettingsPage = forwardRef(({ index, hideTitlebar = false }: { index onCheckedChange={updateAddRandomRelaysToPublish} /> - - - - {/* DEPRECATED: Double-panel setting removed for technical debt reduction */} - -
- - {t('Custom emoji management')} - - -
- {t('After changing emojis, you may need to refresh the page')} -
-
-
) diff --git a/src/pages/secondary/PostSettingsPage/QuietSettings.tsx b/src/pages/secondary/PostSettingsPage/QuietSettings.tsx deleted file mode 100644 index f67cbb59..00000000 --- a/src/pages/secondary/PostSettingsPage/QuietSettings.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { Label } from '@/components/ui/label' -import { Switch } from '@/components/ui/switch' -import { Input } from '@/components/ui/input' -import storage from '@/services/local-storage.service' -import { useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -export default function QuietSettings() { - const { t } = useTranslation() - const [enabled, setEnabled] = useState(false) - const [days, setDays] = useState(7) - const [respectQuietTags, setRespectQuietTags] = useState(true) - const [globalQuietMode, setGlobalQuietMode] = useState(false) - - useEffect(() => { - setEnabled(storage.getDefaultQuietEnabled()) - setDays(storage.getDefaultQuietDays()) - setRespectQuietTags(storage.getRespectQuietTags()) - setGlobalQuietMode(storage.getGlobalQuietMode()) - }, []) - - const handleEnabledChange = (checked: boolean) => { - setEnabled(checked) - storage.setDefaultQuietEnabled(checked) - } - - const handleDaysChange = (value: string) => { - const num = parseInt(value) - if (!isNaN(num) && num >= 0 && Number.isInteger(num)) { - setDays(num) - storage.setDefaultQuietDays(num) - } - } - - const handleRespectQuietTagsChange = (checked: boolean) => { - setRespectQuietTags(checked) - storage.setRespectQuietTags(checked) - } - - const handleGlobalQuietModeChange = (checked: boolean) => { - setGlobalQuietMode(checked) - storage.setGlobalQuietMode(checked) - } - - return ( -
-
-
- - -
-
- {t('Posts will automatically include quiet tags')} -
-
- - {enabled && ( -
- - handleDaysChange(e.target.value)} - className="w-24" - /> -
- {t('Posts will be quiet for this many days')} -
-
- )} - -
-
- - -
-
- {t('Hide interactions on posts with quiet tags')} -
-
- -
-
- - -
-
- {t('Hide interactions on all posts')} -
-
-
- ) -} diff --git a/src/pages/secondary/PostSettingsPage/index.tsx b/src/pages/secondary/PostSettingsPage/index.tsx index 8b058a34..e411ac9f 100644 --- a/src/pages/secondary/PostSettingsPage/index.tsx +++ b/src/pages/secondary/PostSettingsPage/index.tsx @@ -5,7 +5,6 @@ import { forwardRef, useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import MediaUploadServiceSetting from './MediaUploadServiceSetting' import ExpirationSettings from './ExpirationSettings' -import QuietSettings from './QuietSettings' import PublishSuccessToastSetting from './PublishSuccessToastSetting' const PostSettingsPage = forwardRef(({ index, hideTitlebar = false }: { index?: number; hideTitlebar?: boolean }, ref) => { @@ -40,10 +39,6 @@ const PostSettingsPage = forwardRef(({ index, hideTitlebar = false }: { index?:

{t('Expiration Tags')}

-
-

{t('Quiet Tags')}

- -
) diff --git a/src/providers/UserTrustProvider.tsx b/src/providers/UserTrustProvider.tsx deleted file mode 100644 index 7a4fda8b..00000000 --- a/src/providers/UserTrustProvider.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { getPubkeysFromPTags } from '@/lib/tag' -import storage from '@/services/local-storage.service' -import { replaceableEventService } from '@/services/client.service' -import { UserTrustContext } from '@/contexts/user-trust-context' -import { kinds } from 'nostr-tools' -import { type ReactNode, useCallback, useEffect, useState } from 'react' -import { useNostr } from './NostrProvider' - -const wotSet = new Set() - -export function UserTrustProvider({ children }: { children: ReactNode }) { - const { pubkey: currentPubkey } = useNostr() - const [isTrustLoaded, setIsTrustLoaded] = useState(false) - const [hideUntrustedInteractions, setHideUntrustedInteractions] = useState(() => - storage.getHideUntrustedInteractions() - ) - const [hideUntrustedNotifications, setHideUntrustedNotifications] = useState(() => - storage.getHideUntrustedNotifications() - ) - const [hideUntrustedNotes, setHideUntrustedNotes] = useState(() => - storage.getHideUntrustedNotes() - ) - - useEffect(() => { - if (!currentPubkey) { - setIsTrustLoaded(false) - return - } - - // Clear wotSet when account changes to avoid cross-account contamination - wotSet.clear() - setIsTrustLoaded(false) - - const initWoT = async () => { - try { - const followListEvent = await replaceableEventService.fetchReplaceableEvent(currentPubkey, kinds.Contacts) - const followings = followListEvent ? getPubkeysFromPTags(followListEvent.tags) : [] - followings.forEach((pubkey) => wotSet.add(pubkey.toLowerCase())) - - const batchSize = 20 - for (let i = 0; i < followings.length; i += batchSize) { - const batch = followings.slice(i, i + batchSize) - await Promise.allSettled( - batch.map(async (pubkey) => { - const innerFollow = await replaceableEventService.fetchReplaceableEvent(pubkey, kinds.Contacts) - const _followings = innerFollow ? getPubkeysFromPTags(innerFollow.tags) : [] - _followings.forEach((following) => { - wotSet.add(following.toLowerCase()) - }) - }) - ) - await new Promise((resolve) => setTimeout(resolve, 200)) - } - } finally { - setIsTrustLoaded(true) - } - } - void initWoT() - }, [currentPubkey]) - - const isUserTrusted = useCallback( - (pubkey: string) => { - if (!currentPubkey || pubkey.toLowerCase() === currentPubkey.toLowerCase()) return true - return wotSet.has(pubkey.toLowerCase()) - }, - [currentPubkey] - ) - - const updateHideUntrustedInteractions = (hide: boolean) => { - setHideUntrustedInteractions(hide) - storage.setHideUntrustedInteractions(hide) - } - - const updateHideUntrustedNotifications = (hide: boolean) => { - setHideUntrustedNotifications(hide) - storage.setHideUntrustedNotifications(hide) - } - - const updateHideUntrustedNotes = (hide: boolean) => { - setHideUntrustedNotes(hide) - storage.setHideUntrustedNotes(hide) - } - - return ( - - {children} - - ) -} diff --git a/src/services/local-storage.service.ts b/src/services/local-storage.service.ts index 51bab52b..9a91e5ec 100644 --- a/src/services/local-storage.service.ts +++ b/src/services/local-storage.service.ts @@ -59,9 +59,6 @@ const SETTINGS_KEYS = [ StorageKey.QUICK_ZAP, StorageKey.INCLUDE_PUBLIC_ZAP_RECEIPT, StorageKey.AUTOPLAY, - StorageKey.HIDE_UNTRUSTED_INTERACTIONS, - StorageKey.HIDE_UNTRUSTED_NOTIFICATIONS, - StorageKey.HIDE_UNTRUSTED_NOTES, StorageKey.MEDIA_UPLOAD_SERVICE_CONFIG_MAP, StorageKey.DEFAULT_SHOW_NSFW, StorageKey.DISMISSED_TOO_MANY_RELAYS_ALERT, @@ -81,10 +78,6 @@ const SETTINGS_KEYS = [ StorageKey.SHOW_LIVE_ACTIVITIES_BANNER, StorageKey.DEFAULT_EXPIRATION_ENABLED, StorageKey.DEFAULT_EXPIRATION_MONTHS, - StorageKey.DEFAULT_QUIET_ENABLED, - StorageKey.DEFAULT_QUIET_DAYS, - StorageKey.RESPECT_QUIET_TAGS, - StorageKey.GLOBAL_QUIET_MODE, StorageKey.SHOW_RSS_FEED, StorageKey.PANE_MODE, StorageKey.RESTRICT_RELAYS_TO_METADATA_LISTS @@ -108,9 +101,6 @@ class LocalStorageService { private includePublicZapReceipt: boolean = true private mediaUploadService: string = DEFAULT_NIP_96_SERVICE private autoplay: boolean = true - private hideUntrustedInteractions: boolean = false - private hideUntrustedNotifications: boolean = false - private hideUntrustedNotes: boolean = false private mediaUploadServiceConfigMap: Record = {} private defaultShowNsfw: boolean = false private dismissedTooManyRelaysAlert: boolean = false @@ -127,10 +117,6 @@ class LocalStorageService { private shownCreateWalletGuideToastPubkeys: Set = new Set() private defaultExpirationEnabled: boolean = false private defaultExpirationMonths: number = 6 - private defaultQuietEnabled: boolean = false - private defaultQuietDays: number = 7 - private respectQuietTags: boolean = true - private globalQuietMode: boolean = false private showRssFeed: boolean = true private panelMode: 'single' | 'double' = 'single' private addRandomRelaysToPublish: boolean = false @@ -219,25 +205,6 @@ class LocalStorageService { this.autoplay = window.localStorage.getItem(StorageKey.AUTOPLAY) !== 'false' - const hideUntrustedEvents = - window.localStorage.getItem(StorageKey.HIDE_UNTRUSTED_EVENTS) === 'true' - const storedHideUntrustedInteractions = window.localStorage.getItem( - StorageKey.HIDE_UNTRUSTED_INTERACTIONS - ) - const storedHideUntrustedNotifications = window.localStorage.getItem( - StorageKey.HIDE_UNTRUSTED_NOTIFICATIONS - ) - const storedHideUntrustedNotes = window.localStorage.getItem(StorageKey.HIDE_UNTRUSTED_NOTES) - this.hideUntrustedInteractions = storedHideUntrustedInteractions - ? storedHideUntrustedInteractions === 'true' - : hideUntrustedEvents - this.hideUntrustedNotifications = storedHideUntrustedNotifications - ? storedHideUntrustedNotifications === 'true' - : hideUntrustedEvents - this.hideUntrustedNotes = storedHideUntrustedNotes - ? storedHideUntrustedNotes === 'true' - : hideUntrustedEvents - const mediaUploadServiceConfigMapStr = window.localStorage.getItem( StorageKey.MEDIA_UPLOAD_SERVICE_CONFIG_MAP ) @@ -419,7 +386,7 @@ class LocalStorageService { ? new Set(JSON.parse(shownCreateWalletGuideToastPubkeysStr)) : new Set() - // Initialize expiration and quiet settings + // Initialize expiration settings const defaultExpirationEnabledStr = window.localStorage.getItem(StorageKey.DEFAULT_EXPIRATION_ENABLED) this.defaultExpirationEnabled = defaultExpirationEnabledStr === 'true' @@ -431,23 +398,6 @@ class LocalStorageService { } } - const defaultQuietEnabledStr = window.localStorage.getItem(StorageKey.DEFAULT_QUIET_ENABLED) - this.defaultQuietEnabled = defaultQuietEnabledStr === 'true' - - const defaultQuietDaysStr = window.localStorage.getItem(StorageKey.DEFAULT_QUIET_DAYS) - if (defaultQuietDaysStr) { - const num = parseInt(defaultQuietDaysStr) - if (!isNaN(num) && num >= 0 && Number.isInteger(num)) { - this.defaultQuietDays = num - } - } - - const respectQuietTagsStr = window.localStorage.getItem(StorageKey.RESPECT_QUIET_TAGS) - this.respectQuietTags = respectQuietTagsStr === null ? true : respectQuietTagsStr === 'true' - - const globalQuietModeStr = window.localStorage.getItem(StorageKey.GLOBAL_QUIET_MODE) - this.globalQuietMode = globalQuietModeStr === 'true' - const showRssFeedStr = window.localStorage.getItem(StorageKey.SHOW_RSS_FEED) this.showRssFeed = showRssFeedStr === null ? true : showRssFeedStr === 'true' // Default to true @@ -617,12 +567,6 @@ class LocalStorageService { const includeReceiptStr = get(StorageKey.INCLUDE_PUBLIC_ZAP_RECEIPT) if (includeReceiptStr != null) this.includePublicZapReceipt = includeReceiptStr !== 'false' this.autoplay = get(StorageKey.AUTOPLAY) !== 'false' - const hideInteractions = get(StorageKey.HIDE_UNTRUSTED_INTERACTIONS) - if (hideInteractions != null) this.hideUntrustedInteractions = hideInteractions === 'true' - const hideNotifications = get(StorageKey.HIDE_UNTRUSTED_NOTIFICATIONS) - if (hideNotifications != null) this.hideUntrustedNotifications = hideNotifications === 'true' - const hideNotes = get(StorageKey.HIDE_UNTRUSTED_NOTES) - if (hideNotes != null) this.hideUntrustedNotes = hideNotes === 'true' const mediaConfigStr = get(StorageKey.MEDIA_UPLOAD_SERVICE_CONFIG_MAP) if (mediaConfigStr != null) this.mediaUploadServiceConfigMap = JSON.parse(mediaConfigStr) as Record this.defaultShowNsfw = get(StorageKey.DEFAULT_SHOW_NSFW) === 'true' @@ -658,15 +602,6 @@ class LocalStorageService { const num = parseInt(defaultExpirationMonthsStr) if (!isNaN(num) && num >= 0) this.defaultExpirationMonths = num } - this.defaultQuietEnabled = get(StorageKey.DEFAULT_QUIET_ENABLED) === 'true' - const defaultQuietDaysStr = get(StorageKey.DEFAULT_QUIET_DAYS) - if (defaultQuietDaysStr != null) { - const num = parseInt(defaultQuietDaysStr) - if (!isNaN(num) && num >= 0) this.defaultQuietDays = num - } - const respectQuietStr = get(StorageKey.RESPECT_QUIET_TAGS) - if (respectQuietStr != null) this.respectQuietTags = respectQuietStr === 'true' - this.globalQuietMode = get(StorageKey.GLOBAL_QUIET_MODE) === 'true' const showRssStr = get(StorageKey.SHOW_RSS_FEED) if (showRssStr != null) this.showRssFeed = showRssStr === 'true' const paneStr = get(StorageKey.PANE_MODE) @@ -866,38 +801,6 @@ class LocalStorageService { this.persistSetting(StorageKey.AUTOPLAY, autoplay.toString()) } - getHideUntrustedInteractions() { - return this.hideUntrustedInteractions - } - - setHideUntrustedInteractions(hideUntrustedInteractions: boolean) { - this.hideUntrustedInteractions = hideUntrustedInteractions - this.persistSetting( - StorageKey.HIDE_UNTRUSTED_INTERACTIONS, - hideUntrustedInteractions.toString() - ) - } - - getHideUntrustedNotifications() { - return this.hideUntrustedNotifications - } - - setHideUntrustedNotifications(hideUntrustedNotifications: boolean) { - this.hideUntrustedNotifications = hideUntrustedNotifications - this.persistSetting( - StorageKey.HIDE_UNTRUSTED_NOTIFICATIONS, - hideUntrustedNotifications.toString() - ) - } - - getHideUntrustedNotes() { - return this.hideUntrustedNotes - } - - setHideUntrustedNotes(hideUntrustedNotes: boolean) { - this.hideUntrustedNotes = hideUntrustedNotes - this.persistSetting(StorageKey.HIDE_UNTRUSTED_NOTES, hideUntrustedNotes.toString()) - } getMediaUploadServiceConfig(pubkey?: string | null): TMediaUploadServiceConfig { const defaultConfig = { type: 'nip96', service: this.mediaUploadService } as const @@ -1083,45 +986,6 @@ class LocalStorageService { } } - // Quiet settings - getDefaultQuietEnabled() { - return this.defaultQuietEnabled - } - - setDefaultQuietEnabled(enabled: boolean) { - this.defaultQuietEnabled = enabled - this.persistSetting(StorageKey.DEFAULT_QUIET_ENABLED, enabled.toString()) - } - - getDefaultQuietDays() { - return this.defaultQuietDays - } - - setDefaultQuietDays(days: number) { - if (Number.isInteger(days) && days >= 0) { - this.defaultQuietDays = days - this.persistSetting(StorageKey.DEFAULT_QUIET_DAYS, days.toString()) - } - } - - getRespectQuietTags() { - return this.respectQuietTags - } - - setRespectQuietTags(respect: boolean) { - this.respectQuietTags = respect - this.persistSetting(StorageKey.RESPECT_QUIET_TAGS, respect.toString()) - } - - getGlobalQuietMode() { - return this.globalQuietMode - } - - setGlobalQuietMode(enabled: boolean) { - this.globalQuietMode = enabled - this.persistSetting(StorageKey.GLOBAL_QUIET_MODE, enabled.toString()) - } - getShowRssFeed() { return this.showRssFeed }