feat: add setting for notification list style
This commit is contained in:
@@ -16,6 +16,7 @@ import { ReplyProvider } from '@/providers/ReplyProvider'
|
||||
import { ScreenSizeProvider } from '@/providers/ScreenSizeProvider'
|
||||
import { ThemeProvider } from '@/providers/ThemeProvider'
|
||||
import { TranslationServiceProvider } from '@/providers/TranslationServiceProvider'
|
||||
import { UserPreferencesProvider } from '@/providers/UserPreferencesProvider'
|
||||
import { UserTrustProvider } from '@/providers/UserTrustProvider'
|
||||
import { ZapProvider } from '@/providers/ZapProvider'
|
||||
import { PageManager } from './PageManager'
|
||||
@@ -38,8 +39,10 @@ export default function App(): JSX.Element {
|
||||
<ReplyProvider>
|
||||
<MediaUploadServiceProvider>
|
||||
<KindFilterProvider>
|
||||
<PageManager />
|
||||
<Toaster />
|
||||
<UserPreferencesProvider>
|
||||
<PageManager />
|
||||
<Toaster />
|
||||
</UserPreferencesProvider>
|
||||
</KindFilterProvider>
|
||||
</MediaUploadServiceProvider>
|
||||
</ReplyProvider>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import ParentNotePreview from '@/components/ParentNotePreview'
|
||||
import { NOTIFICATION_LIST_STYLE } from '@/constants'
|
||||
import { getEmbeddedPubkeys, getParentBech32Id } from '@/lib/event'
|
||||
import { toNote } from '@/lib/link'
|
||||
import { useSecondaryPage } from '@/PageManager'
|
||||
import { useNostr } from '@/providers/NostrProvider'
|
||||
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
|
||||
import { AtSign, MessageCircle, Quote } from 'lucide-react'
|
||||
import { Event } from 'nostr-tools'
|
||||
import { useMemo } from 'react'
|
||||
@@ -19,6 +21,7 @@ export function MentionNotification({
|
||||
const { t } = useTranslation()
|
||||
const { push } = useSecondaryPage()
|
||||
const { pubkey } = useNostr()
|
||||
const { notificationListStyle } = useUserPreferences()
|
||||
const isMention = useMemo(() => {
|
||||
if (!pubkey) return false
|
||||
const mentions = getEmbeddedPubkeys(notification)
|
||||
@@ -42,6 +45,7 @@ export function MentionNotification({
|
||||
sentAt={notification.created_at}
|
||||
targetEvent={notification}
|
||||
middle={
|
||||
notificationListStyle === NOTIFICATION_LIST_STYLE.DETAILED &&
|
||||
parentEventId && (
|
||||
<ParentNotePreview
|
||||
eventId={parentEventId}
|
||||
|
||||
@@ -4,11 +4,13 @@ import NoteStats from '@/components/NoteStats'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import UserAvatar from '@/components/UserAvatar'
|
||||
import Username from '@/components/Username'
|
||||
import { NOTIFICATION_LIST_STYLE } from '@/constants'
|
||||
import { toNote, toProfile } from '@/lib/link'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useSecondaryPage } from '@/PageManager'
|
||||
import { useNostr } from '@/providers/NostrProvider'
|
||||
import { useNotification } from '@/providers/NotificationProvider'
|
||||
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
|
||||
import { NostrEvent } from 'nostr-tools'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@@ -38,22 +40,52 @@ export default function Notification({
|
||||
const { push } = useSecondaryPage()
|
||||
const { pubkey } = useNostr()
|
||||
const { isNotificationRead, markNotificationAsRead } = useNotification()
|
||||
const { notificationListStyle } = useUserPreferences()
|
||||
const unread = useMemo(
|
||||
() => isNew && !isNotificationRead(notificationId),
|
||||
[isNew, isNotificationRead, notificationId]
|
||||
)
|
||||
|
||||
const handleClick = () => {
|
||||
markNotificationAsRead(notificationId)
|
||||
if (targetEvent) {
|
||||
push(toNote(targetEvent.id))
|
||||
} else if (pubkey) {
|
||||
push(toProfile(pubkey))
|
||||
}
|
||||
}
|
||||
|
||||
if (notificationListStyle === NOTIFICATION_LIST_STYLE.COMPACT) {
|
||||
return (
|
||||
<div
|
||||
className="flex items-center justify-between cursor-pointer py-2 px-4"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div className="flex gap-2 items-center flex-1 w-0">
|
||||
<UserAvatar userId={sender} size="small" />
|
||||
{icon}
|
||||
{middle}
|
||||
{targetEvent && (
|
||||
<ContentPreview
|
||||
className={cn(
|
||||
'truncate flex-1 w-0',
|
||||
unread ? 'font-semibold' : 'text-muted-foreground'
|
||||
)}
|
||||
event={targetEvent}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-muted-foreground shrink-0">
|
||||
<FormattedTimestamp timestamp={sentAt} short />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="clickable flex items-start gap-2 cursor-pointer py-2 px-4 border-b"
|
||||
onClick={() => {
|
||||
markNotificationAsRead(notificationId)
|
||||
if (targetEvent) {
|
||||
push(toNote(targetEvent.id))
|
||||
} else if (pubkey) {
|
||||
push(toProfile(pubkey))
|
||||
}
|
||||
}}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div className="flex gap-2 items-center mt-1.5">
|
||||
{icon}
|
||||
@@ -95,6 +127,17 @@ export default function Notification({
|
||||
}
|
||||
|
||||
export function NotificationSkeleton() {
|
||||
const { notificationListStyle } = useUserPreferences()
|
||||
|
||||
if (notificationListStyle === NOTIFICATION_LIST_STYLE.COMPACT) {
|
||||
return (
|
||||
<div className="flex gap-2 items-center h-11 py-2 px-4">
|
||||
<Skeleton className="w-7 h-7 rounded-full" />
|
||||
<Skeleton className="h-6 flex-1 w-0" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex items-start gap-2 cursor-pointer py-2 px-4">
|
||||
<div className="flex gap-2 items-center mt-1.5">
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { BIG_RELAY_URLS, ExtendedKind } from '@/constants'
|
||||
import { BIG_RELAY_URLS, ExtendedKind, NOTIFICATION_LIST_STYLE } from '@/constants'
|
||||
import { compareEvents } from '@/lib/event'
|
||||
import { usePrimaryPage } from '@/PageManager'
|
||||
import { useNostr } from '@/providers/NostrProvider'
|
||||
import { useNotification } from '@/providers/NotificationProvider'
|
||||
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
|
||||
import { useUserTrust } from '@/providers/UserTrustProvider'
|
||||
import client from '@/services/client.service'
|
||||
import noteStatsService from '@/services/note-stats.service'
|
||||
@@ -34,6 +35,7 @@ const NotificationList = forwardRef((_, ref) => {
|
||||
const { pubkey } = useNostr()
|
||||
const { hideUntrustedNotifications, isUserTrusted } = useUserTrust()
|
||||
const { getNotificationsSeenAt } = useNotification()
|
||||
const { notificationListStyle } = useUserPreferences()
|
||||
const [notificationType, setNotificationType] = useState<TNotificationType>('all')
|
||||
const [lastReadTime, setLastReadTime] = useState(0)
|
||||
const [refreshCount, setRefreshCount] = useState(0)
|
||||
@@ -262,7 +264,7 @@ const NotificationList = forwardRef((_, ref) => {
|
||||
}}
|
||||
pullingContent=""
|
||||
>
|
||||
<div>
|
||||
<div className={notificationListStyle === NOTIFICATION_LIST_STYLE.COMPACT ? 'pt-2' : ''}>
|
||||
{visibleNotifications.map((notification) => (
|
||||
<NotificationItem
|
||||
key={notification.id}
|
||||
|
||||
@@ -41,6 +41,7 @@ export const StorageKey = {
|
||||
SHOW_KINDS: 'showKinds',
|
||||
SHOW_KINDS_VERSION: 'showKindsVersion',
|
||||
HIDE_CONTENT_MENTIONING_MUTED_USERS: 'hideContentMentioningMutedUsers',
|
||||
NOTIFICATION_LIST_STYLE: 'notificationListStyle',
|
||||
MEDIA_UPLOAD_SERVICE: 'mediaUploadService', // deprecated
|
||||
HIDE_UNTRUSTED_EVENTS: 'hideUntrustedEvents', // deprecated
|
||||
ACCOUNT_RELAY_LIST_EVENT_MAP: 'accountRelayListEventMap', // deprecated
|
||||
@@ -136,3 +137,8 @@ export const POLL_TYPE = {
|
||||
MULTIPLE_CHOICE: 'multiplechoice',
|
||||
SINGLE_CHOICE: 'singlechoice'
|
||||
} as const
|
||||
|
||||
export const NOTIFICATION_LIST_STYLE = {
|
||||
COMPACT: 'compact',
|
||||
DETAILED: 'detailed'
|
||||
} as const
|
||||
|
||||
@@ -392,6 +392,11 @@ export default {
|
||||
profanity: 'ألفاظ نابية',
|
||||
illegal: 'محتوى غير قانوني',
|
||||
spam: 'رسائل مزعجة',
|
||||
other: 'أخرى'
|
||||
other: 'أخرى',
|
||||
'Notification list style': 'نمط قائمة الإشعارات',
|
||||
'See extra info for each notification': 'عرض معلومات إضافية لكل إشعار',
|
||||
'See more notifications at a glance': 'رؤية المزيد من الإشعارات بنظرة سريعة',
|
||||
Detailed: 'تفصيلي',
|
||||
Compact: 'مضغوط'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,6 +401,12 @@ export default {
|
||||
profanity: 'Obszönität',
|
||||
illegal: 'Illegaler Inhalt',
|
||||
spam: 'Spam',
|
||||
other: 'Sonstiges'
|
||||
other: 'Sonstiges',
|
||||
'Notification list style': 'Benachrichtigungslistenstil',
|
||||
'See extra info for each notification':
|
||||
'Zusätzliche Informationen für jede Benachrichtigung anzeigen',
|
||||
'See more notifications at a glance': 'Mehr Benachrichtigungen auf einen Blick sehen',
|
||||
Detailed: 'Detailliert',
|
||||
Compact: 'Kompakt'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,6 +391,11 @@ export default {
|
||||
profanity: 'Profanity',
|
||||
illegal: 'Illegal content',
|
||||
spam: 'Spam',
|
||||
other: 'Other'
|
||||
other: 'Other',
|
||||
'Notification list style': 'Notification list style',
|
||||
'See extra info for each notification': 'See extra info for each notification',
|
||||
'See more notifications at a glance': 'See more notifications at a glance',
|
||||
Detailed: 'Detailed',
|
||||
Compact: 'Compact'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,6 +397,11 @@ export default {
|
||||
profanity: 'Blasfemia',
|
||||
illegal: 'Contenido ilegal',
|
||||
spam: 'Spam',
|
||||
other: 'Otro'
|
||||
other: 'Otro',
|
||||
'Notification list style': 'Estilo de lista de notificaciones',
|
||||
'See extra info for each notification': 'Ver información adicional para cada notificación',
|
||||
'See more notifications at a glance': 'Ver más notificaciones de un vistazo',
|
||||
Detailed: 'Detallado',
|
||||
Compact: 'Compacto'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,6 +393,11 @@ export default {
|
||||
profanity: 'فحاشی',
|
||||
illegal: 'محتوای غیرقانونی',
|
||||
spam: 'اسپم',
|
||||
other: 'سایر'
|
||||
other: 'سایر',
|
||||
'Notification list style': 'سبک فهرست اعلانها',
|
||||
'See extra info for each notification': 'مشاهده اطلاعات اضافی برای هر اعلان',
|
||||
'See more notifications at a glance': 'مشاهده اعلانهای بیشتر در یک نگاه',
|
||||
Detailed: 'تفصیلی',
|
||||
Compact: 'فشرده'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,6 +401,12 @@ export default {
|
||||
profanity: 'Blasphème',
|
||||
illegal: 'Contenu illégal',
|
||||
spam: 'Spam',
|
||||
other: 'Autre'
|
||||
other: 'Autre',
|
||||
'Notification list style': 'Style de liste de notifications',
|
||||
'See extra info for each notification':
|
||||
'Voir des infos supplémentaires pour chaque notification',
|
||||
'See more notifications at a glance': "Voir plus de notifications en un coup d'œil",
|
||||
Detailed: 'Détaillé',
|
||||
Compact: 'Compact'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,6 +397,11 @@ export default {
|
||||
profanity: 'Blasfemia',
|
||||
illegal: 'Contenuto illegale',
|
||||
spam: 'Spam',
|
||||
other: 'Altro'
|
||||
other: 'Altro',
|
||||
'Notification list style': 'Stile elenco notifiche',
|
||||
'See extra info for each notification': 'Visualizza informazioni extra per ogni notifica',
|
||||
'See more notifications at a glance': "Visualizza più notifiche a colpo d'occhio",
|
||||
Detailed: 'Dettagliato',
|
||||
Compact: 'Compatto'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,6 +394,11 @@ export default {
|
||||
profanity: '冒涜的な内容',
|
||||
illegal: '違法コンテンツ',
|
||||
spam: 'スパム',
|
||||
other: 'その他'
|
||||
other: 'その他',
|
||||
'Notification list style': '通知リストスタイル',
|
||||
'See extra info for each notification': '各通知の詳細情報を表示',
|
||||
'See more notifications at a glance': '一目でより多くの通知を確認',
|
||||
Detailed: '詳細',
|
||||
Compact: 'コンパクト'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,6 +394,11 @@ export default {
|
||||
profanity: '욕설',
|
||||
illegal: '불법 콘텐츠',
|
||||
spam: '스팸',
|
||||
other: '기타'
|
||||
other: '기타',
|
||||
'Notification list style': '알림 목록 스타일',
|
||||
'See extra info for each notification': '각 알림의 추가 정보 보기',
|
||||
'See more notifications at a glance': '한눈에 더 많은 알림 보기',
|
||||
Detailed: '상세',
|
||||
Compact: '간단'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,6 +398,11 @@ export default {
|
||||
profanity: 'Wulgaryzmy',
|
||||
illegal: 'Nielegalna treść',
|
||||
spam: 'Spam',
|
||||
other: 'Inne'
|
||||
other: 'Inne',
|
||||
'Notification list style': 'Styl listy powiadomień',
|
||||
'See extra info for each notification': 'Zobacz dodatkowe informacje dla każdego powiadomienia',
|
||||
'See more notifications at a glance': 'Zobacz więcej powiadomień na pierwszy rzut oka',
|
||||
Detailed: 'Szczegółowy',
|
||||
Compact: 'Zwięzły'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,6 +394,11 @@ export default {
|
||||
profanity: 'Blasfêmia',
|
||||
illegal: 'Conteúdo ilegal',
|
||||
spam: 'Spam',
|
||||
other: 'Outro'
|
||||
other: 'Outro',
|
||||
'Notification list style': 'Estilo da lista de notificações',
|
||||
'See extra info for each notification': 'Ver informações extras para cada notificação',
|
||||
'See more notifications at a glance': 'Ver mais notificações rapidamente',
|
||||
Detailed: 'Detalhado',
|
||||
Compact: 'Compacto'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,6 +397,11 @@ export default {
|
||||
profanity: 'Blasfémia',
|
||||
illegal: 'Conteúdo ilegal',
|
||||
spam: 'Spam',
|
||||
other: 'Outro'
|
||||
other: 'Outro',
|
||||
'Notification list style': 'Estilo da lista de notificações',
|
||||
'See extra info for each notification': 'Ver informações extra para cada notificação',
|
||||
'See more notifications at a glance': 'Ver mais notificações rapidamente',
|
||||
Detailed: 'Detalhado',
|
||||
Compact: 'Compacto'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,6 +398,12 @@ export default {
|
||||
profanity: 'Ненормативная лексика',
|
||||
illegal: 'Незаконный контент',
|
||||
spam: 'Спам',
|
||||
other: 'Другое'
|
||||
other: 'Другое',
|
||||
'Notification list style': 'Стиль списка уведомлений',
|
||||
'See extra info for each notification':
|
||||
'Просмотреть дополнительную информацию для каждого уведомления',
|
||||
'See more notifications at a glance': 'Увидеть больше уведомлений с первого взгляда',
|
||||
Detailed: 'Подробный',
|
||||
Compact: 'Компактный'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,6 +389,11 @@ export default {
|
||||
profanity: 'คำหยาบคาย',
|
||||
illegal: 'เนื้อหาผิดกฎหมาย',
|
||||
spam: 'สแปม',
|
||||
other: 'อื่นๆ'
|
||||
other: 'อื่นๆ',
|
||||
'Notification list style': 'รูปแบบรายการการแจ้งเตือน',
|
||||
'See extra info for each notification': 'ดูข้อมูลเพิ่มเติมสำหรับการแจ้งเตือนแต่ละรายการ',
|
||||
'See more notifications at a glance': 'ดูการแจ้งเตือนเพิ่มเติมในแวบเดียว',
|
||||
Detailed: 'รายละเอียด',
|
||||
Compact: 'กะทัดรัด'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,6 +387,11 @@ export default {
|
||||
profanity: '亵渎言论',
|
||||
illegal: '违法内容',
|
||||
spam: '垃圾信息',
|
||||
other: '其他'
|
||||
other: '其他',
|
||||
'Notification list style': '通知列表样式',
|
||||
'See extra info for each notification': '查看每条通知的详细信息',
|
||||
'See more notifications at a glance': '一目了然地查看更多通知',
|
||||
Detailed: '详细',
|
||||
Compact: '紧凑'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'
|
||||
import { Switch } from '@/components/ui/switch'
|
||||
import { NOTIFICATION_LIST_STYLE } from '@/constants'
|
||||
import { LocalizedLanguageNames, TLanguage } from '@/i18n'
|
||||
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useContentPolicy } from '@/providers/ContentPolicyProvider'
|
||||
import { useTheme } from '@/providers/ThemeProvider'
|
||||
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
|
||||
import { useUserTrust } from '@/providers/UserTrustProvider'
|
||||
import { SelectValue } from '@radix-ui/react-select'
|
||||
import { ExternalLink } from 'lucide-react'
|
||||
@@ -25,6 +27,7 @@ const GeneralSettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
|
||||
setHideContentMentioningMutedUsers
|
||||
} = useContentPolicy()
|
||||
const { hideUntrustedNotes, updateHideUntrustedNotes } = useUserTrust()
|
||||
const { notificationListStyle, updateNotificationListStyle } = useUserPreferences()
|
||||
|
||||
const handleLanguageChange = (value: TLanguage) => {
|
||||
i18n.changeLanguage(value)
|
||||
@@ -66,6 +69,29 @@ const GeneralSettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<Label htmlFor="notification-list-style" className="text-base font-normal">
|
||||
<div>{t('Notification list style')}</div>
|
||||
<div className="text-muted-foreground">
|
||||
{notificationListStyle === NOTIFICATION_LIST_STYLE.DETAILED
|
||||
? t('See extra info for each notification')
|
||||
: t('See more notifications at a glance')}
|
||||
</div>
|
||||
</Label>
|
||||
<Select
|
||||
defaultValue={NOTIFICATION_LIST_STYLE.DETAILED}
|
||||
value={notificationListStyle}
|
||||
onValueChange={updateNotificationListStyle}
|
||||
>
|
||||
<SelectTrigger id="notification-list-style" className="w-48">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={NOTIFICATION_LIST_STYLE.DETAILED}>{t('Detailed')}</SelectItem>
|
||||
<SelectItem value={NOTIFICATION_LIST_STYLE.COMPACT}>{t('Compact')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<Label htmlFor="autoplay" className="text-base font-normal">
|
||||
<div>{t('Autoplay')}</div>
|
||||
|
||||
40
src/providers/UserPreferencesProvider.tsx
Normal file
40
src/providers/UserPreferencesProvider.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import storage from '@/services/local-storage.service'
|
||||
import { TNotificationStyle } from '@/types'
|
||||
import { createContext, useContext, useState } from 'react'
|
||||
|
||||
type TUserPreferencesContext = {
|
||||
notificationListStyle: TNotificationStyle
|
||||
updateNotificationListStyle: (style: TNotificationStyle) => void
|
||||
}
|
||||
|
||||
const UserPreferencesContext = createContext<TUserPreferencesContext | undefined>(undefined)
|
||||
|
||||
export const useUserPreferences = () => {
|
||||
const context = useContext(UserPreferencesContext)
|
||||
if (!context) {
|
||||
throw new Error('useUserPreferences must be used within a UserPreferencesProvider')
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
export function UserPreferencesProvider({ children }: { children: React.ReactNode }) {
|
||||
const [notificationListStyle, setNotificationListStyle] = useState(
|
||||
storage.getNotificationListStyle()
|
||||
)
|
||||
|
||||
const updateNotificationListStyle = (style: TNotificationStyle) => {
|
||||
setNotificationListStyle(style)
|
||||
storage.setNotificationListStyle(style)
|
||||
}
|
||||
|
||||
return (
|
||||
<UserPreferencesContext.Provider
|
||||
value={{
|
||||
notificationListStyle,
|
||||
updateNotificationListStyle
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</UserPreferencesContext.Provider>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,10 @@
|
||||
import { DEFAULT_NIP_96_SERVICE, ExtendedKind, SUPPORTED_KINDS, StorageKey } from '@/constants'
|
||||
import {
|
||||
DEFAULT_NIP_96_SERVICE,
|
||||
ExtendedKind,
|
||||
NOTIFICATION_LIST_STYLE,
|
||||
SUPPORTED_KINDS,
|
||||
StorageKey
|
||||
} from '@/constants'
|
||||
import { isSameAccount } from '@/lib/account'
|
||||
import { randomString } from '@/lib/random'
|
||||
import {
|
||||
@@ -7,6 +13,7 @@ import {
|
||||
TFeedInfo,
|
||||
TMediaUploadServiceConfig,
|
||||
TNoteListMode,
|
||||
TNotificationStyle,
|
||||
TRelaySet,
|
||||
TThemeSetting,
|
||||
TTranslationServiceConfig
|
||||
@@ -36,6 +43,7 @@ class LocalStorageService {
|
||||
private dismissedTooManyRelaysAlert: boolean = false
|
||||
private showKinds: number[] = []
|
||||
private hideContentMentioningMutedUsers: boolean = false
|
||||
private notificationListStyle: TNotificationStyle = NOTIFICATION_LIST_STYLE.DETAILED
|
||||
|
||||
constructor() {
|
||||
if (!LocalStorageService.instance) {
|
||||
@@ -160,6 +168,12 @@ class LocalStorageService {
|
||||
this.hideContentMentioningMutedUsers =
|
||||
window.localStorage.getItem(StorageKey.HIDE_CONTENT_MENTIONING_MUTED_USERS) === 'true'
|
||||
|
||||
this.notificationListStyle =
|
||||
window.localStorage.getItem(StorageKey.NOTIFICATION_LIST_STYLE) ===
|
||||
NOTIFICATION_LIST_STYLE.COMPACT
|
||||
? NOTIFICATION_LIST_STYLE.COMPACT
|
||||
: NOTIFICATION_LIST_STYLE.DETAILED
|
||||
|
||||
// Clean up deprecated data
|
||||
window.localStorage.removeItem(StorageKey.ACCOUNT_PROFILE_EVENT_MAP)
|
||||
window.localStorage.removeItem(StorageKey.ACCOUNT_FOLLOW_LIST_EVENT_MAP)
|
||||
@@ -410,6 +424,15 @@ class LocalStorageService {
|
||||
this.hideContentMentioningMutedUsers = hide
|
||||
window.localStorage.setItem(StorageKey.HIDE_CONTENT_MENTIONING_MUTED_USERS, hide.toString())
|
||||
}
|
||||
|
||||
getNotificationListStyle() {
|
||||
return this.notificationListStyle
|
||||
}
|
||||
|
||||
setNotificationListStyle(style: TNotificationStyle) {
|
||||
this.notificationListStyle = style
|
||||
window.localStorage.setItem(StorageKey.NOTIFICATION_LIST_STYLE, style)
|
||||
}
|
||||
}
|
||||
|
||||
const instance = new LocalStorageService()
|
||||
|
||||
5
src/types/index.d.ts
vendored
5
src/types/index.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { Event, VerifiedEvent, Filter } from 'nostr-tools'
|
||||
import { POLL_TYPE } from './constants'
|
||||
import { NOTIFICATION_LIST_STYLE, POLL_TYPE } from '../constants'
|
||||
|
||||
export type TSubRequestFilter = Omit<Filter, 'since' | 'until'> & { limit: number }
|
||||
|
||||
@@ -182,3 +182,6 @@ export type TSearchParams = {
|
||||
search: string
|
||||
input?: string
|
||||
}
|
||||
|
||||
export type TNotificationStyle =
|
||||
(typeof NOTIFICATION_LIST_STYLE)[keyof typeof NOTIFICATION_LIST_STYLE]
|
||||
|
||||
Reference in New Issue
Block a user