Browse Source

change defaults and fix toasts

imwald
Silberengel 2 weeks ago
parent
commit
c431c6eed5
  1. 11
      src/components/NoteList/index.tsx
  2. 4
      src/constants.ts
  3. 11
      src/i18n/locales/de.ts
  4. 11
      src/i18n/locales/en.ts
  5. 13
      src/lib/publishing-feedback.tsx
  6. 33
      src/pages/secondary/PostSettingsPage/PublishSuccessToastSetting.tsx
  7. 64
      src/pages/secondary/PostSettingsPage/PublishingFeedbackSettings.tsx
  8. 4
      src/pages/secondary/PostSettingsPage/index.tsx
  9. 28
      src/services/local-storage.service.ts

11
src/components/NoteList/index.tsx

@ -52,6 +52,7 @@ import dayjs from 'dayjs' @@ -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 { @@ -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( @@ -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(
<div className="w-full min-w-0">
<div className="flex items-center gap-2 mb-3">
<CircleAlert className="w-5 h-5 text-red-500 shrink-0" />
<div className="font-semibold">{title}</div>
</div>
<div className="font-semibold mb-3">{title}</div>
<div className="text-xs text-muted-foreground mb-2">
{t('Per-relay timeline results ({{count}} connections)', {
count: uiStatuses.length
@ -3947,7 +3944,7 @@ const NoteList = forwardRef( @@ -3947,7 +3944,7 @@ const NoteList = forwardRef(
aggregateSummary={false}
/>
</div>,
{ duration: 12_000, className: 'max-w-lg w-full' }
{ duration: 12_000, className: 'max-w-lg w-full', icon: null }
)
}
}, debounceMs)

4
src/constants.ts

@ -390,8 +390,10 @@ export const StorageKey = { @@ -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”. */

11
src/i18n/locales/de.ts

@ -757,9 +757,14 @@ export default { @@ -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)',

11
src/i18n/locales/en.ts

@ -756,9 +756,14 @@ export default { @@ -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)',

13
src/lib/publishing-feedback.tsx

@ -23,6 +23,11 @@ function publishSuccessToastsEnabled(): boolean { @@ -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 {
@ -124,9 +129,15 @@ export function showPublishingFeedback( @@ -124,9 +129,15 @@ export function showPublishingFeedback(
const toastFunction = isSuccess ? toast.success : toast.error
if (!detailedPublishToastsEnabled()) {
toastFunction(message, { duration: isSuccess ? 2000 : duration })
return
}
toastFunction(<PublishToastRelayPanel message={message} result={result} />, {
duration,
className: 'max-w-lg w-full'
className: 'max-w-lg w-full',
icon: null
})
}

33
src/pages/secondary/PostSettingsPage/PublishSuccessToastSetting.tsx

@ -1,33 +0,0 @@ @@ -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 (
<div className="space-y-2">
<div className="flex items-center space-x-2">
<Label htmlFor="publish-success-toasts">{t('Publish success toasts')}</Label>
<Switch id="publish-success-toasts" checked={enabled} onCheckedChange={onChange} />
</div>
<div className="text-muted-foreground text-xs max-w-xl">
{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.'
)}
</div>
</div>
)
}

64
src/pages/secondary/PostSettingsPage/PublishingFeedbackSettings.tsx

@ -0,0 +1,64 @@ @@ -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 (
<div className="space-y-4">
<div className="space-y-2">
<div className="flex items-center space-x-2">
<Label htmlFor="publish-success-toasts" className="text-base font-normal">
{t('Publish success toasts')}
</Label>
<Switch id="publish-success-toasts" checked={successToasts} onCheckedChange={onSuccessChange} />
</div>
<p className="text-muted-foreground text-xs max-w-xl">
{t('Publish success toasts hint')}
</p>
</div>
{successToasts ? (
<div className="space-y-2 pl-4 border-l-2 border-border">
<div className="flex items-center space-x-2">
<Label htmlFor="detailed-publish-toasts" className="text-base font-normal">
{t('Publish toast per-relay details')}
</Label>
<Switch
id="detailed-publish-toasts"
checked={detailedToasts}
onCheckedChange={onDetailedChange}
/>
</div>
<p className="text-muted-foreground text-xs max-w-xl">
{t('Publish toast per-relay details hint')}
</p>
</div>
) : null}
<p className="text-muted-foreground text-xs max-w-xl border-t border-border pt-3">
{t('Publishing feedback errors note')}
</p>
</div>
)
}

4
src/pages/secondary/PostSettingsPage/index.tsx

@ -5,7 +5,7 @@ import { forwardRef, useCallback, useEffect, useState } from 'react' @@ -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?: @@ -33,7 +33,7 @@ const PostSettingsPage = forwardRef(({ index, hideTitlebar = false }: { index?:
<MediaUploadServiceSetting />
<div className="space-y-4">
<h3 className="text-lg font-medium">{t('Publishing feedback')}</h3>
<PublishSuccessToastSetting />
<PublishingFeedbackSettings />
</div>
<div className="space-y-4">
<h3 className="text-lg font-medium">{t('Expiration Tags')}</h3>

28
src/services/local-storage.service.ts

@ -75,6 +75,7 @@ const SETTINGS_KEYS = [ @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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
}

Loading…
Cancel
Save