From c431c6eed5e344a737d19bf4f67fa2b6792150b7 Mon Sep 17 00:00:00 2001 From: Silberengel Date: Sun, 31 May 2026 11:08:00 +0200 Subject: [PATCH] change defaults and fix toasts --- src/components/NoteList/index.tsx | 11 ++-- src/constants.ts | 4 +- src/i18n/locales/de.ts | 11 +++- src/i18n/locales/en.ts | 11 +++- src/lib/publishing-feedback.tsx | 15 ++++- .../PublishSuccessToastSetting.tsx | 33 ---------- .../PublishingFeedbackSettings.tsx | 64 +++++++++++++++++++ .../secondary/PostSettingsPage/index.tsx | 4 +- src/services/local-storage.service.ts | 28 ++++++-- 9 files changed, 125 insertions(+), 56 deletions(-) delete mode 100644 src/pages/secondary/PostSettingsPage/PublishSuccessToastSetting.tsx create mode 100644 src/pages/secondary/PostSettingsPage/PublishingFeedbackSettings.tsx diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx index c39f43f6..a60c4088 100644 --- a/src/components/NoteList/index.tsx +++ b/src/components/NoteList/index.tsx @@ -52,6 +52,7 @@ import dayjs from 'dayjs' import { type Event, type Filter, kinds } from 'nostr-tools' import { decode } from 'nostr-tools/nip19' import RelayStatusDisplay from '@/components/RelayStatusDisplay' +import { detailedPublishToastsEnabled } from '@/lib/publishing-feedback' import { relayOpTerminalRowsToTimelineRelayUiStatuses, type RelayOpTerminalRow @@ -69,7 +70,6 @@ import { type ReactNode, type SetStateAction } from 'react' -import { CircleAlert } from 'lucide-react' import { useLongPressAction } from '@/hooks/use-long-press-action' import { useTranslation } from 'react-i18next' import PullToRefresh from 'react-simple-pull-to-refresh' @@ -3926,15 +3926,12 @@ const NoteList = forwardRef( const title = t( 'Relays returned no events for this feed. They may be offline, slow, or not indexing these notes.' ) - if (uiStatuses.length === 0) { + if (uiStatuses.length === 0 || !detailedPublishToastsEnabled()) { toast.error(title, { duration: 8000 }) } else { toast.error(
-
- -
{title}
-
+
{title}
{t('Per-relay timeline results ({{count}} connections)', { count: uiStatuses.length @@ -3947,7 +3944,7 @@ const NoteList = forwardRef( aggregateSummary={false} />
, - { duration: 12_000, className: 'max-w-lg w-full' } + { duration: 12_000, className: 'max-w-lg w-full', icon: null } ) } }, debounceMs) diff --git a/src/constants.ts b/src/constants.ts index fe66a791..a29e05f6 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -390,8 +390,10 @@ export const StorageKey = { ADD_RANDOM_RELAYS_TO_PUBLISH: 'addRandomRelaysToPublish', /** When `'true'`, only connect to relays on the viewer's NIP-65 / favorites / cache / HTTP lists. */ RESTRICT_RELAYS_TO_METADATA_LISTS: 'restrictRelaysToMetadataLists', - /** When not `'false'`, show green Sonner toasts after successful publishes (default on). */ + /** When `'true'`, show Sonner toasts after successful publishes (default off). */ SHOW_PUBLISH_SUCCESS_TOASTS: 'showPublishSuccessToasts', + /** When not `'false'`, publish/feed toasts include per-relay breakdown when success toasts are on (default on). */ + SHOW_DETAILED_PUBLISH_TOASTS: 'showDetailedPublishToasts', /** When not `'false'`, show NIP-53 live activity banner (default on). */ SHOW_LIVE_ACTIVITIES_BANNER: 'showLiveActivitiesBanner', /** Max approximate archive size (MB). `0` in UI means “use platform default”. */ diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts index 37b9ea0d..8ec3f8f2 100644 --- a/src/i18n/locales/de.ts +++ b/src/i18n/locales/de.ts @@ -757,9 +757,14 @@ export default { 'Favorited by': 'Favorisiert von', 'Post settings': 'Beitragseinstellungen', 'Publishing feedback': 'Rückmeldungen beim Veröffentlichen', - 'Publish success toasts': 'Erfolgs-Benachrichtigungen beim Veröffentlichen', - 'Show green notifications when posts, replies, reactions, and other publishes succeed. When off, a small checkmark appears briefly at the bottom-right instead. Errors and failures still use a toast.': - 'Grüne Hinweise anzeigen, wenn Beiträge, Antworten, Reaktionen und andere Veröffentlichungen gelingen. Wenn aus, erscheint kurz ein kleines Häkchen unten rechts. Fehler weiterhin als Hinweis.', + 'Publish success toasts': 'Erfolg beim Veröffentlichen anzeigen', + 'Publish success toasts hint': + 'Wenn an, bestätigt ein Hinweis gelungene Beiträge, Antworten, Reaktionen und ähnliche Aktionen. Wenn aus, erscheint kurz ein kleines Häkchen unten rechts.', + 'Publish toast per-relay details': 'Pro-Relay-Aufschlüsselung in Hinweisen', + 'Publish toast per-relay details hint': + 'Wenn an, listet der Hinweis jedes Relay (angenommen, fehlgeschlagen, Fehlertext). Wenn aus, nur eine kurze Zusammenfassung.', + 'Publishing feedback errors note': + 'Fehlgeschlagene Veröffentlichungen und andere Fehler zeigen immer einen Hinweis — mit Kurzfassung oder Pro-Relay-Aufschlüsselung wie oben.', 'Publish successful': 'Veröffentlichung erfolgreich', 'Media upload service': 'Medien-Upload-Service', BlossomUploadYourListOption: 'Blossom (eigene Liste)', diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index 7089d626..5c0e03b0 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -756,9 +756,14 @@ export default { 'Favorited by': 'Favorited by', 'Post settings': 'Post settings', 'Publishing feedback': 'Publishing feedback', - 'Publish success toasts': 'Publish success toasts', - 'Show green notifications when posts, replies, reactions, and other publishes succeed. When off, a small checkmark appears briefly at the bottom-right instead. Errors and failures still use a toast.': - 'Show green notifications when posts, replies, reactions, and other publishes succeed. When off, a small checkmark appears briefly at the bottom-right instead. Errors and failures still use a toast.', + 'Publish success toasts': 'Success notifications when publishing', + 'Publish success toasts hint': + 'When on, a toast confirms successful posts, replies, reactions, and similar actions. When off, a small checkmark appears briefly at the bottom-right instead.', + 'Publish toast per-relay details': 'Per-relay breakdown in toasts', + 'Publish toast per-relay details hint': + 'When on, those toasts list each relay (accepted, failed, errors). When off, only a short summary line.', + 'Publishing feedback errors note': + 'Failed publishes and other errors always show a toast, using the same summary or per-relay style as above.', 'Publish successful': 'Publish successful', 'Media upload service': 'Media upload service', BlossomUploadYourListOption: 'Blossom (your list)', diff --git a/src/lib/publishing-feedback.tsx b/src/lib/publishing-feedback.tsx index ba4e098b..85186d7b 100644 --- a/src/lib/publishing-feedback.tsx +++ b/src/lib/publishing-feedback.tsx @@ -23,6 +23,11 @@ function publishSuccessToastsEnabled(): boolean { return storage.getShowPublishSuccessToasts() } +/** Per-relay toast panels only when success toasts are on and the nested setting is enabled. */ +export function detailedPublishToastsEnabled(): boolean { + return publishSuccessToastsEnabled() && storage.getShowDetailedPublishToasts() +} + function resolvePromiseSuccessLabel(success: string | (() => ReactNode)): string | undefined { if (typeof success === 'string') return success try { @@ -123,10 +128,16 @@ export function showPublishingFeedback( } const toastFunction = isSuccess ? toast.success : toast.error - + + if (!detailedPublishToastsEnabled()) { + toastFunction(message, { duration: isSuccess ? 2000 : duration }) + return + } + toastFunction(, { duration, - className: 'max-w-lg w-full' + className: 'max-w-lg w-full', + icon: null }) } diff --git a/src/pages/secondary/PostSettingsPage/PublishSuccessToastSetting.tsx b/src/pages/secondary/PostSettingsPage/PublishSuccessToastSetting.tsx deleted file mode 100644 index ba0703d5..00000000 --- a/src/pages/secondary/PostSettingsPage/PublishSuccessToastSetting.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Label } from '@/components/ui/label' -import { Switch } from '@/components/ui/switch' -import storage from '@/services/local-storage.service' -import { useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -export default function PublishSuccessToastSetting() { - const { t } = useTranslation() - const [enabled, setEnabled] = useState(true) - - useEffect(() => { - setEnabled(storage.getShowPublishSuccessToasts()) - }, []) - - const onChange = (checked: boolean) => { - setEnabled(checked) - storage.setShowPublishSuccessToasts(checked) - } - - return ( -
-
- - -
-
- {t( - 'Show green notifications when posts, replies, reactions, and other publishes succeed. When off, a small checkmark appears briefly at the bottom-right instead. Errors and failures still use a toast.' - )} -
-
- ) -} diff --git a/src/pages/secondary/PostSettingsPage/PublishingFeedbackSettings.tsx b/src/pages/secondary/PostSettingsPage/PublishingFeedbackSettings.tsx new file mode 100644 index 00000000..5f9f3ffe --- /dev/null +++ b/src/pages/secondary/PostSettingsPage/PublishingFeedbackSettings.tsx @@ -0,0 +1,64 @@ +import { Label } from '@/components/ui/label' +import { Switch } from '@/components/ui/switch' +import storage from '@/services/local-storage.service' +import { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' + +export default function PublishingFeedbackSettings() { + const { t } = useTranslation() + const [successToasts, setSuccessToasts] = useState(false) + const [detailedToasts, setDetailedToasts] = useState(true) + + useEffect(() => { + setSuccessToasts(storage.getShowPublishSuccessToasts()) + setDetailedToasts(storage.getShowDetailedPublishToasts()) + }, []) + + const onSuccessChange = (checked: boolean) => { + setSuccessToasts(checked) + storage.setShowPublishSuccessToasts(checked) + } + + const onDetailedChange = (checked: boolean) => { + setDetailedToasts(checked) + storage.setShowDetailedPublishToasts(checked) + } + + return ( +
+
+
+ + +
+

+ {t('Publish success toasts hint')} +

+
+ + {successToasts ? ( +
+
+ + +
+

+ {t('Publish toast per-relay details hint')} +

+
+ ) : null} + +

+ {t('Publishing feedback errors note')} +

+
+ ) +} diff --git a/src/pages/secondary/PostSettingsPage/index.tsx b/src/pages/secondary/PostSettingsPage/index.tsx index e411ac9f..d84a75e0 100644 --- a/src/pages/secondary/PostSettingsPage/index.tsx +++ b/src/pages/secondary/PostSettingsPage/index.tsx @@ -5,7 +5,7 @@ import { forwardRef, useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import MediaUploadServiceSetting from './MediaUploadServiceSetting' import ExpirationSettings from './ExpirationSettings' -import PublishSuccessToastSetting from './PublishSuccessToastSetting' +import PublishingFeedbackSettings from './PublishingFeedbackSettings' const PostSettingsPage = forwardRef(({ index, hideTitlebar = false }: { index?: number; hideTitlebar?: boolean }, ref) => { const { t } = useTranslation() @@ -33,7 +33,7 @@ const PostSettingsPage = forwardRef(({ index, hideTitlebar = false }: { index?:

{t('Publishing feedback')}

- +

{t('Expiration Tags')}

diff --git a/src/services/local-storage.service.ts b/src/services/local-storage.service.ts index 9a91e5ec..2fdaa479 100644 --- a/src/services/local-storage.service.ts +++ b/src/services/local-storage.service.ts @@ -75,6 +75,7 @@ const SETTINGS_KEYS = [ StorageKey.SHOW_RECOMMENDED_RELAYS_PANEL, StorageKey.ADD_RANDOM_RELAYS_TO_PUBLISH, StorageKey.SHOW_PUBLISH_SUCCESS_TOASTS, + StorageKey.SHOW_DETAILED_PUBLISH_TOASTS, StorageKey.SHOW_LIVE_ACTIVITIES_BANNER, StorageKey.DEFAULT_EXPIRATION_ENABLED, StorageKey.DEFAULT_EXPIRATION_MONTHS, @@ -119,8 +120,9 @@ class LocalStorageService { private defaultExpirationMonths: number = 6 private showRssFeed: boolean = true private panelMode: 'single' | 'double' = 'single' - private addRandomRelaysToPublish: boolean = false - private showPublishSuccessToasts: boolean = true + private addRandomRelaysToPublish: boolean = true + private showPublishSuccessToasts: boolean = false + private showDetailedPublishToasts: boolean = true private showLiveActivitiesBanner: boolean = true private restrictRelaysToMetadataLists: boolean = false @@ -405,10 +407,14 @@ class LocalStorageService { this.panelMode = panelModeStr === 'double' ? 'double' : 'single' // Default to 'single' const addRandomRelaysStr = window.localStorage.getItem(StorageKey.ADD_RANDOM_RELAYS_TO_PUBLISH) - this.addRandomRelaysToPublish = addRandomRelaysStr === null ? false : addRandomRelaysStr === 'true' + this.addRandomRelaysToPublish = addRandomRelaysStr === null ? true : addRandomRelaysStr === 'true' const showPublishSuccessStr = window.localStorage.getItem(StorageKey.SHOW_PUBLISH_SUCCESS_TOASTS) - this.showPublishSuccessToasts = showPublishSuccessStr !== 'false' + this.showPublishSuccessToasts = showPublishSuccessStr === 'true' + + const showDetailedPublishStr = window.localStorage.getItem(StorageKey.SHOW_DETAILED_PUBLISH_TOASTS) + this.showDetailedPublishToasts = + showDetailedPublishStr === null ? true : showDetailedPublishStr === 'true' const showLiveActivitiesStr = window.localStorage.getItem(StorageKey.SHOW_LIVE_ACTIVITIES_BANNER) this.showLiveActivitiesBanner = showLiveActivitiesStr !== 'false' @@ -572,9 +578,12 @@ class LocalStorageService { this.defaultShowNsfw = get(StorageKey.DEFAULT_SHOW_NSFW) === 'true' this.dismissedTooManyRelaysAlert = get(StorageKey.DISMISSED_TOO_MANY_RELAYS_ALERT) === 'true' this.showRecommendedRelaysPanel = get(StorageKey.SHOW_RECOMMENDED_RELAYS_PANEL) === 'true' - this.addRandomRelaysToPublish = get(StorageKey.ADD_RANDOM_RELAYS_TO_PUBLISH) === 'true' + const addRandomRelaysStr = get(StorageKey.ADD_RANDOM_RELAYS_TO_PUBLISH) + if (addRandomRelaysStr != null) this.addRandomRelaysToPublish = addRandomRelaysStr === 'true' const showPublishSuccessStr = get(StorageKey.SHOW_PUBLISH_SUCCESS_TOASTS) if (showPublishSuccessStr != null) this.showPublishSuccessToasts = showPublishSuccessStr !== 'false' + const showDetailedPublishStr = get(StorageKey.SHOW_DETAILED_PUBLISH_TOASTS) + if (showDetailedPublishStr != null) this.showDetailedPublishToasts = showDetailedPublishStr === 'true' const showLiveActivitiesStr = get(StorageKey.SHOW_LIVE_ACTIVITIES_BANNER) if (showLiveActivitiesStr != null) this.showLiveActivitiesBanner = showLiveActivitiesStr !== 'false' const showKindsStr = get(StorageKey.SHOW_KINDS) @@ -1004,6 +1013,15 @@ class LocalStorageService { this.persistSetting(StorageKey.SHOW_PUBLISH_SUCCESS_TOASTS, show.toString()) } + getShowDetailedPublishToasts(): boolean { + return this.showDetailedPublishToasts + } + + setShowDetailedPublishToasts(show: boolean) { + this.showDetailedPublishToasts = show + this.persistSetting(StorageKey.SHOW_DETAILED_PUBLISH_TOASTS, show.toString()) + } + getPanelMode(): 'single' | 'double' { return this.panelMode }