From b7cb2cd42d473bdfcdd8990a0cea28ce32a022c0 Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sun, 12 Apr 2026 08:20:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E4=BC=9A=E8=AF=9D=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/SettingsPage.tsx | 226 ++++++++++++++++++++++++------------- 1 file changed, 149 insertions(+), 77 deletions(-) diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index 6b05c7a..770d0f8 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -72,6 +72,25 @@ interface WxidOption { avatarUrl?: string } +type SessionFilterType = configService.MessagePushSessionType +type SessionFilterTypeValue = 'all' | SessionFilterType +type SessionFilterMode = 'all' | 'whitelist' | 'blacklist' + +interface SessionFilterOption { + username: string + displayName: string + avatarUrl?: string + type: SessionFilterType +} + +const sessionFilterTypeOptions: Array<{ value: SessionFilterTypeValue; label: string }> = [ + { value: 'all', label: '全部' }, + { value: 'private', label: '私聊' }, + { value: 'group', label: '群聊' }, + { value: 'official', label: '订阅号/服务号' }, + { value: 'other', label: '其他/非好友' } +] + interface SettingsPageProps { onClose?: () => void } @@ -171,6 +190,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { const [quoteLayout, setQuoteLayout] = useState('quote-top') const [updateChannel, setUpdateChannel] = useState('stable') const [filterSearchKeyword, setFilterSearchKeyword] = useState('') + const [notificationTypeFilter, setNotificationTypeFilter] = useState('all') const [filterModeDropdownOpen, setFilterModeDropdownOpen] = useState(false) const [positionDropdownOpen, setPositionDropdownOpen] = useState(false) const [closeBehaviorDropdownOpen, setCloseBehaviorDropdownOpen] = useState(false) @@ -230,7 +250,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { const [messagePushFilterList, setMessagePushFilterList] = useState([]) const [messagePushFilterDropdownOpen, setMessagePushFilterDropdownOpen] = useState(false) const [messagePushFilterSearchKeyword, setMessagePushFilterSearchKeyword] = useState('') - const [messagePushTypeFilter, setMessagePushTypeFilter] = useState<'all' | configService.MessagePushSessionType>('all') + const [messagePushTypeFilter, setMessagePushTypeFilter] = useState('all') const [messagePushContactOptions, setMessagePushContactOptions] = useState([]) const [antiRevokeSearchKeyword, setAntiRevokeSearchKeyword] = useState('') const [antiRevokeSelectedIds, setAntiRevokeSelectedIds] = useState>(new Set()) @@ -1658,15 +1678,6 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { ) const renderNotificationTab = () => { - // 获取已过滤会话的信息 - const getSessionInfo = (username: string) => { - const session = chatSessions.find(s => s.username === username) - return { - displayName: session?.displayName || username, - avatarUrl: session?.avatarUrl || '' - } - } - // 添加会话到过滤列表 const handleAddToFilterList = async (username: string) => { if (notificationFilterList.includes(username)) return @@ -1684,18 +1695,6 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { showMessage('已从过滤列表移除', true) } - // 过滤掉已在列表中的会话,并根据搜索关键字过滤 - const availableSessions = chatSessions.filter(s => { - if (notificationFilterList.includes(s.username)) return false - if (filterSearchKeyword) { - const keyword = filterSearchKeyword.toLowerCase() - const displayName = (s.displayName || '').toLowerCase() - const username = s.username.toLowerCase() - return displayName.includes(keyword) || username.includes(keyword) - } - return true - }) - return (
@@ -1787,17 +1786,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
{ - const val = option.value as 'all' | 'whitelist' | 'blacklist' - setNotificationFilterMode(val) - setFilterModeDropdownOpen(false) - await configService.setNotificationFilterMode(val) - showMessage( - val === 'all' ? '已设为接收所有通知' : - val === 'whitelist' ? '已设为仅接收白名单通知' : '已设为屏蔽黑名单通知', - true - ) - }} + onClick={() => { void handleSetNotificationFilterMode(option.value as SessionFilterMode) }} > {option.label} {notificationFilterMode === option.value && } @@ -1816,11 +1805,33 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { : '点击左侧会话添加到黑名单,点击右侧会话从黑名单移除'} +
+ {sessionFilterTypeOptions.map(option => ( + + ))} +
+
{/* 可选会话列表 */}
可选会话 + {notificationAvailableSessions.length > 0 && ( + + )}
- {availableSessions.length > 0 ? ( - availableSessions.map(session => ( + {notificationAvailableSessions.length > 0 ? ( + notificationAvailableSessions.map(session => (
{session.displayName || session.username} + {getSessionFilterTypeLabel(session.type)} +
)) ) : (
- {filterSearchKeyword ? '没有匹配的会话' : '暂无可添加的会话'} + {filterSearchKeyword || notificationTypeFilter !== 'all' ? '没有匹配的会话' : '暂无可添加的会话'}
)}
@@ -1863,11 +1875,20 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { {notificationFilterList.length > 0 && ( {notificationFilterList.length} )} + {notificationFilterList.length > 0 && ( + + )}
{notificationFilterList.length > 0 ? ( notificationFilterList.map(username => { - const info = getSessionInfo(username) + const info = getSessionFilterOptionInfo(username) return (
{info.displayName} + {getSessionFilterTypeLabel(info.type)} ×
) @@ -2533,7 +2555,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { showMessage(enabled ? '已开启主动推送' : '已关闭主动推送', true) } - const getMessagePushSessionType = (session: { username: string; type?: ContactInfo['type'] | number }): configService.MessagePushSessionType => { + const getSessionFilterType = (session: { username: string; type?: ContactInfo['type'] | number }): SessionFilterType => { const username = String(session.username || '').trim() if (username.endsWith('@chatroom')) return 'group' if (username.startsWith('gh_') || session.type === 'official') return 'official' @@ -2542,7 +2564,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { return 'private' } - const getMessagePushTypeLabel = (type: configService.MessagePushSessionType) => { + const getSessionFilterTypeLabel = (type: SessionFilterType) => { switch (type) { case 'private': return '私聊' case 'group': return '群聊' @@ -2586,36 +2608,38 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { showMessage(`已添加 ${usernames.length} 个会话`, true) } - const messagePushOptionMap = new Map() + const handleRemoveAllMessagePushFilterSessions = async () => { + if (messagePushFilterList.length === 0) return + setMessagePushFilterList([]) + await configService.setMessagePushFilterList([]) + showMessage('已清空主动推送过滤列表', true) + } + + const sessionFilterOptionMap = new Map() for (const session of chatSessions) { if (session.username.toLowerCase().includes('placeholder_foldgroup')) continue - messagePushOptionMap.set(session.username, { + sessionFilterOptionMap.set(session.username, { username: session.username, displayName: session.displayName || session.username, avatarUrl: session.avatarUrl, - type: getMessagePushSessionType(session) + type: getSessionFilterType(session) }) } for (const contact of messagePushContactOptions) { if (!contact.username) continue if (contact.type !== 'friend' && contact.type !== 'group' && contact.type !== 'official' && contact.type !== 'former_friend') continue - const existing = messagePushOptionMap.get(contact.username) - messagePushOptionMap.set(contact.username, { + const existing = sessionFilterOptionMap.get(contact.username) + sessionFilterOptionMap.set(contact.username, { username: contact.username, displayName: existing?.displayName || contact.displayName || contact.remark || contact.nickname || contact.username, avatarUrl: existing?.avatarUrl || contact.avatarUrl, - type: getMessagePushSessionType(contact) + type: getSessionFilterType(contact) }) } - const messagePushOptions = Array.from(messagePushOptionMap.values()) + const sessionFilterOptions = Array.from(sessionFilterOptionMap.values()) .sort((a, b) => { const aSession = chatSessions.find(session => session.username === a.username) const bSession = chatSessions.find(session => session.username === b.username) @@ -2623,26 +2647,71 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { Number(aSession?.sortTimestamp || aSession?.lastTimestamp || 0) }) - const messagePushAvailableSessions = messagePushOptions.filter(session => { - if (messagePushFilterList.includes(session.username)) return false - if (messagePushTypeFilter !== 'all' && session.type !== messagePushTypeFilter) return false - if (messagePushFilterSearchKeyword.trim()) { - const keyword = messagePushFilterSearchKeyword.trim().toLowerCase() - return String(session.displayName || '').toLowerCase().includes(keyword) || - session.username.toLowerCase().includes(keyword) - } - return true - }) - - const getMessagePushOptionInfo = (username: string) => { - return messagePushOptionMap.get(username) || { + const getSessionFilterOptionInfo = (username: string) => { + return sessionFilterOptionMap.get(username) || { username, displayName: username, avatarUrl: undefined, - type: 'other' as configService.MessagePushSessionType + type: 'other' as SessionFilterType } } + const getAvailableSessionFilterOptions = ( + selectedList: string[], + typeFilter: SessionFilterTypeValue, + searchKeyword: string + ) => { + const keyword = searchKeyword.trim().toLowerCase() + return sessionFilterOptions.filter(session => { + if (selectedList.includes(session.username)) return false + if (typeFilter !== 'all' && session.type !== typeFilter) return false + if (keyword) { + return String(session.displayName || '').toLowerCase().includes(keyword) || + session.username.toLowerCase().includes(keyword) + } + return true + }) + } + + const notificationAvailableSessions = getAvailableSessionFilterOptions( + notificationFilterList, + notificationTypeFilter, + filterSearchKeyword + ) + + const messagePushAvailableSessions = getAvailableSessionFilterOptions( + messagePushFilterList, + messagePushTypeFilter, + messagePushFilterSearchKeyword + ) + + const handleAddAllNotificationFilterSessions = async () => { + const usernames = notificationAvailableSessions.map(session => session.username) + if (usernames.length === 0) return + const next = Array.from(new Set([...notificationFilterList, ...usernames])) + setNotificationFilterList(next) + await configService.setNotificationFilterList(next) + showMessage(`已添加 ${usernames.length} 个会话`, true) + } + + const handleRemoveAllNotificationFilterSessions = async () => { + if (notificationFilterList.length === 0) return + setNotificationFilterList([]) + await configService.setNotificationFilterList([]) + showMessage('已清空通知过滤列表', true) + } + + const handleSetNotificationFilterMode = async (mode: SessionFilterMode) => { + setNotificationFilterMode(mode) + setFilterModeDropdownOpen(false) + await configService.setNotificationFilterMode(mode) + showMessage( + mode === 'all' ? '已设为接收所有通知' : + mode === 'whitelist' ? '已设为仅接收白名单通知' : '已设为屏蔽黑名单通知', + true + ) + } + const handleTestInsightConnection = async () => { setIsTestingInsight(true) setInsightTestResult(null) @@ -3518,18 +3587,12 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { : '点击左侧会话添加到黑名单,黑名单会话不会推送'}
- {[ - { value: 'all', label: '全部' }, - { value: 'private', label: '私聊' }, - { value: 'group', label: '群聊' }, - { value: 'official', label: '订阅号/服务号' }, - { value: 'other', label: '其他/非好友' } - ].map(option => ( + {sessionFilterTypeOptions.map(option => ( @@ -3572,13 +3635,13 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { size={28} /> {session.displayName || session.username} - {getMessagePushTypeLabel(session.type)} + {getSessionFilterTypeLabel(session.type)} +
)) ) : (
- {messagePushFilterSearchKeyword ? '没有匹配的会话' : '暂无可添加的会话'} + {messagePushFilterSearchKeyword || messagePushTypeFilter !== 'all' ? '没有匹配的会话' : '暂无可添加的会话'}
)}
@@ -3590,11 +3653,20 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { {messagePushFilterList.length > 0 && ( {messagePushFilterList.length} )} + {messagePushFilterList.length > 0 && ( + + )}
{messagePushFilterList.length > 0 ? ( messagePushFilterList.map(username => { - const session = getMessagePushOptionInfo(username) + const session = getSessionFilterOptionInfo(username) return (
{session.displayName || username} - {getMessagePushTypeLabel(session.type)} + {getSessionFilterTypeLabel(session.type)} ×
)