From 860ec07dfd18b72f13a8ad4795e479df3abf7a22 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Tue, 2 Jun 2026 18:20:31 +0200 Subject: [PATCH] feat(friends): group chip-filter row over online/offline list + manager wiring --- .../FriendsListGroupChipsView.tsx | 38 +++++++++++++++++++ .../views/friends-list/FriendsListView.tsx | 36 +++++++++++++----- 2 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 src/components/friends/views/friends-list/FriendsListGroupChipsView.tsx diff --git a/src/components/friends/views/friends-list/FriendsListGroupChipsView.tsx b/src/components/friends/views/friends-list/FriendsListGroupChipsView.tsx new file mode 100644 index 0000000..2d61efc --- /dev/null +++ b/src/components/friends/views/friends-list/FriendsListGroupChipsView.tsx @@ -0,0 +1,38 @@ +import { FriendCategoryData } from '@nitrots/nitro-renderer'; +import { FC } from 'react'; +import { LocalizeText, MessengerFriend, countFriendsByCategory } from '../../../../api'; +import { Flex } from '../../../../common'; + +interface FriendsListGroupChipsViewProps +{ + categories: FriendCategoryData[]; + friends: MessengerFriend[]; + selectedCategoryId: number; + setSelectedCategoryId: (id: number) => void; + onManageClick: () => void; +} + +export const FriendsListGroupChipsView: FC = props => +{ + const { categories = [], friends = [], selectedCategoryId = 0, setSelectedCategoryId = null, onManageClick = null } = props; + + const counts = countFriendsByCategory(friends); + + return ( + + +
setSelectedCategoryId(0) }> + { LocalizeText('friendlist.friends') } ({ friends.length }) +
+ { categories.map(category => ( +
setSelectedCategoryId(category.id) }> + { category.name } ({ counts.get(category.id) ?? 0 }) +
+ )) } +
+
+ { '⚙' } +
+
+ ); +}; diff --git a/src/components/friends/views/friends-list/FriendsListView.tsx b/src/components/friends/views/friends-list/FriendsListView.tsx index 957aaf2..7c1c3dc 100644 --- a/src/components/friends/views/friends-list/FriendsListView.tsx +++ b/src/components/friends/views/friends-list/FriendsListView.tsx @@ -1,11 +1,13 @@ import { AddLinkEventTracker, ILinkEventTracker, RemoveFriendComposer, RemoveLinkEventTracker, SendRoomInviteComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { LocalizeText, MessengerFriend, SendMessageComposer } from '../../../../api'; +import { LocalizeText, MessengerFriend, SendMessageComposer, filterFriendsByCategory } from '../../../../api'; import { Button, Flex, NitroCardAccordionSetView, NitroCardAccordionView, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common'; import { useFriends } from '../../../../hooks'; +import { FriendsCategoryManagerView } from './FriendsCategoryManagerView'; import { FriendsRemoveConfirmationView } from './FriendsListRemoveConfirmationView'; import { FriendsRoomInviteView } from './FriendsListRoomInviteView'; import { FriendsSearchView } from './FriendsListSearchView'; +import { FriendsListGroupChipsView } from './FriendsListGroupChipsView'; import { FriendsListGroupView } from './friends-list-group/FriendsListGroupView'; import { FriendsListRequestView } from './friends-list-request/FriendsListRequestView'; @@ -15,7 +17,13 @@ export const FriendsListView: FC<{}> = props => const [ selectedFriendsIds, setSelectedFriendsIds ] = useState([]); const [ showRoomInvite, setShowRoomInvite ] = useState(false); const [ showRemoveFriendsConfirmation, setShowRemoveFriendsConfirmation ] = useState(false); - const { onlineFriends = [], offlineFriends = [], requests = [], requestFriend = null } = useFriends(); + const [ selectedCategoryId, setSelectedCategoryId ] = useState(0); + const [ showCategoryManager, setShowCategoryManager ] = useState(false); + const { friends = [], onlineFriends = [], offlineFriends = [], requests = [], requestFriend = null, settings = null } = useFriends(); + + const categories = settings?.categories ?? []; + const filteredOnlineFriends = filterFriendsByCategory(onlineFriends, selectedCategoryId); + const filteredOfflineFriends = filterFriendsByCategory(offlineFriends, selectedCategoryId); const removeFriendsText = useMemo(() => { @@ -145,32 +153,38 @@ export const FriendsListView: FC<{}> = props => setIsVisible(false) } /> + setShowCategoryManager(true) } /> - + { - event.stopPropagation(); toggleSelectFriends(onlineFriends.map(friend => friend.id)); + event.stopPropagation(); toggleSelectFriends(filteredOnlineFriends.map(friend => friend.id)); } }> - { onlineFriends.length && onlineFriends.every(friend => (selectedFriendsIds.indexOf(friend.id) >= 0)) + { filteredOnlineFriends.length && filteredOnlineFriends.every(friend => (selectedFriendsIds.indexOf(friend.id) >= 0)) ? LocalizeText('friendlist.unselect_all') : LocalizeText('friendlist.select_all') } - + - + { - event.stopPropagation(); toggleSelectFriends(offlineFriends.map(friend => friend.id)); + event.stopPropagation(); toggleSelectFriends(filteredOfflineFriends.map(friend => friend.id)); } }> - { offlineFriends.length && offlineFriends.every(friend => (selectedFriendsIds.indexOf(friend.id) >= 0)) + { filteredOfflineFriends.length && filteredOfflineFriends.every(friend => (selectedFriendsIds.indexOf(friend.id) >= 0)) ? LocalizeText('friendlist.unselect_all') : LocalizeText('friendlist.select_all') } - + @@ -186,6 +200,8 @@ export const FriendsListView: FC<{}> = props => setShowRoomInvite(false) } /> } { showRemoveFriendsConfirmation && setShowRemoveFriendsConfirmation(false) } /> } + { showCategoryManager && + setShowCategoryManager(false) } /> } ); };