diff --git a/src/stores/friend.js b/src/stores/friend.js index 2de5b56a..75480642 100644 --- a/src/stores/friend.js +++ b/src/stores/friend.js @@ -67,6 +67,38 @@ export const useFriendStore = defineStore('Friend', () => { const localFavoriteFriends = reactive(new Set()); + const allFavoriteFriendIds = computed(() => { + const favoriteStore = useFavoriteStore(); + const set = new Set(); + for (const ref of favoriteStore.cachedFavorites.values()) { + if (ref.type === 'friend') { + set.add(ref.favoriteId); + } + } + for (const groupName in favoriteStore.localFriendFavorites) { + const userIds = favoriteStore.localFriendFavorites[groupName]; + if (userIds) { + for (const id of userIds) { + set.add(id); + } + } + } + return set; + }); + + const allFavoriteOnlineFriends = computed(() => { + return Array.from(friends.values()) + .filter( + (f) => + f.state === 'online' && allFavoriteFriendIds.value.has(f.id) + ) + .sort( + getFriendsSortFunction( + appearanceSettingsStore.sidebarSortMethods + ) + ); + }); + const isRefreshFriendsLoading = ref(false); const onlineFriendCount = ref(0); @@ -1663,6 +1695,8 @@ export const useFriendStore = defineStore('Friend', () => { offlineFriends, friendsInSameInstance, + allFavoriteFriendIds, + allFavoriteOnlineFriends, localFavoriteFriends, isRefreshFriendsLoading, onlineFriendCount, diff --git a/src/views/Charts/components/InstanceActivity.vue b/src/views/Charts/components/InstanceActivity.vue index b3b717ee..26655297 100644 --- a/src/views/Charts/components/InstanceActivity.vue +++ b/src/views/Charts/components/InstanceActivity.vue @@ -186,8 +186,8 @@ import BackToTop from '@/components/BackToTop.vue'; import dayjs from 'dayjs'; - import { useAppearanceSettingsStore, useFavoriteStore, useFriendStore, useUserStore } from '../../../stores'; import { Popover, PopoverContent, PopoverTrigger } from '../../../components/ui/popover'; + import { useAppearanceSettingsStore, useFriendStore, useUserStore } from '../../../stores'; import { parseLocation, timeToText } from '../../../shared/utils'; import { Slider } from '../../../components/ui/slider'; import { Switch } from '../../../components/ui/switch'; @@ -204,31 +204,10 @@ const appearanceSettingsStore = useAppearanceSettingsStore(); const friendStore = useFriendStore(); - const favoriteStore = useFavoriteStore(); - const { isDarkMode, dtHour12 } = storeToRefs(appearanceSettingsStore); - const { friends } = storeToRefs(friendStore); - const { cachedFavorites, localFriendFavorites } = storeToRefs(favoriteStore); + const { friends, allFavoriteFriendIds } = storeToRefs(friendStore); const { currentUser } = storeToRefs(useUserStore()); const { t } = useI18n(); - - // All favorite friends (remote + local) - const allFavoriteFriends = computed(() => { - const set = new Set(); - for (const ref of cachedFavorites.value.values()) { - if (ref.type === 'friend') { - set.add(ref.favoriteId); - } - } - for (const group in localFriendFavorites.value) { - const userIds = localFriendFavorites.value[group]; - if (userIds) { - for (const id of userIds) { - set.add(id); - } - } - } - return set; - }); + const { isDarkMode, dtHour12 } = storeToRefs(appearanceSettingsStore); const instanceActivityRef = ref(null); @@ -394,7 +373,7 @@ onMounted(async () => { try { getAllDateOfActivity(); - await getActivityData(selectedDate, currentUser, friends, allFavoriteFriends, () => + await getActivityData(selectedDate, currentUser, friends, allFavoriteFriendIds, () => handleIntersectionObserver(activityDetailChartRef) ); await getWorldNameData(); @@ -419,7 +398,7 @@ reloadData = async function () { isLoading.value = true; try { - await getActivityData(selectedDate, currentUser, friends, allFavoriteFriends, () => + await getActivityData(selectedDate, currentUser, friends, allFavoriteFriendIds, () => handleIntersectionObserver(activityDetailChartRef) ); await getWorldNameData(); diff --git a/src/views/FriendList/FriendList.vue b/src/views/FriendList/FriendList.vue index e18cb753..f2fc0324 100644 --- a/src/views/FriendList/FriendList.vue +++ b/src/views/FriendList/FriendList.vue @@ -142,7 +142,7 @@ const emit = defineEmits(['lookup-user']); - const { friends } = storeToRefs(useFriendStore()); + const { friends, allFavoriteFriendIds } = storeToRefs(useFriendStore()); const modalStore = useModalStore(); const { getAllUserStats, getAllUserMutualCount, confirmDeleteFriend, handleFriendDelete } = useFriendStore(); const { randomUserColours } = storeToRefs(useAppearanceSettingsStore()); @@ -286,7 +286,7 @@ } for (const ctx of friends.value.values()) { if (!ctx.ref) continue; - if (friendsListSearchFilterVIP.value && !ctx.isVIP) continue; + if (friendsListSearchFilterVIP.value && !allFavoriteFriendIds.value.has(ctx.id)) continue; if (query) { let match = false; if (!match && filters.includes('Display Name') && ctx.ref.displayName) { diff --git a/src/views/FriendsLocations/FriendsLocations.vue b/src/views/FriendsLocations/FriendsLocations.vue index d4161e7a..e66e7c6a 100644 --- a/src/views/FriendsLocations/FriendsLocations.vue +++ b/src/views/FriendsLocations/FriendsLocations.vue @@ -146,8 +146,14 @@ const { t } = useI18n(); const friendStore = useFriendStore(); - const { onlineFriends, vipFriends, activeFriends, offlineFriends, friendsInSameInstance } = - storeToRefs(friendStore); + const { + onlineFriends, + allFavoriteOnlineFriends, + allFavoriteFriendIds, + activeFriends, + offlineFriends, + friendsInSameInstance + } = storeToRefs(friendStore); const SEGMENTED_BASE_OPTIONS = [ { label: t('view.friends_locations.online'), value: 'online' }, @@ -322,7 +328,7 @@ const filteredFriends = computed(() => { if (normalizedSearchTerm.value) { const pools = [ - ...toEntries(vipFriends.value), + ...toEntries(allFavoriteOnlineFriends.value), ...toEntries(onlineFriends.value), ...toEntries(activeFriends.value), ...toEntries(offlineFriends.value) @@ -349,7 +355,9 @@ .filter((id) => typeof id === 'string' || typeof id === 'number') ); - const remainingOnline = toEntries(onlineFriends.value) + const remainingOnline = toEntries( + onlineFriends.value.filter((f) => !allFavoriteFriendIds.value.has(f.id)) + ) .filter((entry) => { if (!entry?.id) { return true; @@ -364,10 +372,10 @@ return [...sameEntries, ...remainingOnline]; } - return toEntries(onlineFriends.value); + return toEntries(onlineFriends.value.filter((f) => !allFavoriteFriendIds.value.has(f.id))); } case 'favorite': - return toEntries(vipFriends.value); + return toEntries(allFavoriteOnlineFriends.value); case 'same-instance': return sameInstanceEntries.value; case 'active': diff --git a/src/views/Sidebar/components/FriendsSidebar.vue b/src/views/Sidebar/components/FriendsSidebar.vue index 8759e72f..c5237767 100644 --- a/src/views/Sidebar/components/FriendsSidebar.vue +++ b/src/views/Sidebar/components/FriendsSidebar.vue @@ -108,8 +108,14 @@ const { t } = useI18n(); const friendStore = useFriendStore(); - const { vipFriends, onlineFriends, activeFriends, offlineFriends, friendsInSameInstance } = - storeToRefs(friendStore); + const { + allFavoriteOnlineFriends, + allFavoriteFriendIds, + onlineFriends, + activeFriends, + offlineFriends, + friendsInSameInstance + } = storeToRefs(friendStore); const { isSidebarGroupByInstance, isHideFriendsInSameInstance, @@ -157,13 +163,15 @@ return list.filter((item) => !sameInstanceFriendId.value.has(item.id)); } - const onlineFriendsByGroupStatus = computed(() => excludeSameInstance(onlineFriends.value)); + const onlineFriendsByGroupStatus = computed(() => + excludeSameInstance(onlineFriends.value.filter((f) => !allFavoriteFriendIds.value.has(f.id))) + ); const vipFriendsByGroupStatus = computed(() => { const selectedGroups = sidebarFavoriteGroups.value; const hasFilter = selectedGroups.length > 0; if (!hasFilter) { - return excludeSameInstance(vipFriends.value); + return excludeSameInstance(allFavoriteOnlineFriends.value); } // Filter to only include VIP friends whose group key is in selectedGroups const allowedIds = new Set(); @@ -179,7 +187,7 @@ for (const f of remoteFriendsByGroup[key]) allowedIds.add(f.id); } } - return excludeSameInstance(vipFriends.value.filter((f) => allowedIds.has(f.id))); + return excludeSameInstance(allFavoriteOnlineFriends.value.filter((f) => allowedIds.has(f.id))); }); // VIP friends divide by group @@ -212,7 +220,9 @@ // Filter vipFriends per group, preserving vipFriends sort order const result = []; for (const { key, groupName, memberIds } of groups) { - const filteredFriends = excludeSameInstance(vipFriends.value.filter((friend) => memberIds.has(friend.id))); + const filteredFriends = excludeSameInstance( + allFavoriteOnlineFriends.value.filter((friend) => memberIds.has(friend.id)) + ); if (filteredFriends.length > 0) { result.push(filteredFriends.map((item) => ({ groupName, key, ...item }))); }