import { MarkMentionsReadComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useMemo, useState } from 'react'; import { IMentionEntry, LocalizeText, MentionType, SendMessageComposer } from '../../api'; import { Button, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common'; import { useMentionsSnapshot } from '../../hooks'; import { markAllRead } from '../../hooks/mentions/mentionsStore'; import { useUserDataSnapshot } from '../../hooks/session/useSessionSnapshots'; import { MentionRowView } from './MentionRowView'; import { getMentionDateGroup, MentionDateGroup } from './mentionsFormat'; import { useMentionActions } from './useMentionActions'; interface MentionsViewProps { onClose: () => void; } type MentionFilter = 'all' | 'unread' | 'direct' | 'room'; const FILTERS: ReadonlyArray<{ key: MentionFilter; label: string }> = [ { key: 'all', label: 'mentions.filter.all' }, { key: 'unread', label: 'mentions.filter.unread' }, { key: 'direct', label: 'mentions.filter.direct' }, { key: 'room', label: 'mentions.filter.room' } ]; const GROUP_ORDER: ReadonlyArray = [ 'today', 'yesterday', 'older' ]; const GROUP_LABEL: Record = { today: 'mentions.group.today', yesterday: 'mentions.group.yesterday', older: 'mentions.group.older' }; const matchesFilter = (mention: IMentionEntry, filter: MentionFilter): boolean => { switch(filter) { case 'unread': return !mention.read; case 'direct': return mention.mentionType === MentionType.DIRECT; case 'room': return mention.mentionType === MentionType.ROOM; default: return true; } }; export const MentionsView: FC = props => { const { onClose } = props; const { mentions, unreadCount } = useMentionsSnapshot(); const { userName: ownUsername = '' } = useUserDataSnapshot(); const { open, goto, remove } = useMentionActions(); const [ filter, setFilter ] = useState('all'); const onMarkAll = useCallback(() => { markAllRead(); SendMessageComposer(new MarkMentionsReadComposer(0, 0)); }, []); const groups = useMemo(() => { const buckets: Record = { today: [], yesterday: [], older: [] }; for(const mention of mentions) { if(!matchesFilter(mention, filter)) continue; buckets[getMentionDateGroup(mention.timestamp)].push(mention); } return GROUP_ORDER .map(key => ({ key, items: buckets[key] })) .filter(group => group.items.length > 0); }, [ mentions, filter ]); const hasAny = groups.length > 0; return ( { FILTERS.map(({ key, label }) => { const active = (filter === key); const showCount = ((key === 'unread') && (unreadCount > 0)); return ( ); }) } { !hasAny && @ { LocalizeText('mentions.window.empty') } } { hasAny && groups.map(group => ( { LocalizeText(GROUP_LABEL[group.key]) } { group.items.map(mention => ( )) } )) } { (unreadCount > 0) && } ); };