diff --git a/apps/app-frontend/src/components/ui/friends/FriendsList.vue b/apps/app-frontend/src/components/ui/friends/FriendsList.vue
index 71c8c1c8fe..1b954325ac 100644
--- a/apps/app-frontend/src/components/ui/friends/FriendsList.vue
+++ b/apps/app-frontend/src/components/ui/friends/FriendsList.vue
@@ -17,17 +17,40 @@ import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { useFriends } from '@/composables/use-friends'
import type { FriendWithUserData } from '@/helpers/friends.ts'
import type { ModrinthCredentials } from '@/helpers/mr_auth'
+import { get as getSettings, set as setSettings } from '@/helpers/settings.ts'
+import { useTheming } from '@/store/state'
const { formatMessage } = useVIntl()
const { handleError } = injectNotificationManager()
const formatRelativeTime = useRelativeTime()
+const themeStore = useTheming()
const props = defineProps<{
credentials: ModrinthCredentials | null
signIn: () => void
}>()
+type FriendsSectionCollapsedFlag =
+ | 'friends_active_collapsed'
+ | 'friends_online_collapsed'
+ | 'friends_offline_collapsed'
+ | 'friends_pending_collapsed'
+
+function isFriendsSectionCollapsed(flag: FriendsSectionCollapsedFlag) {
+ return themeStore.getFeatureFlag(flag)
+}
+
+function setFriendsSectionCollapsed(flag: FriendsSectionCollapsedFlag, collapsed: boolean) {
+ themeStore.featureFlags[flag] = collapsed
+ getSettings()
+ .then((settings) => {
+ settings.feature_flags[flag] = collapsed
+ return setSettings(settings)
+ })
+ .catch(handleError)
+}
+
const userCredentials = computed(() => props.credentials)
const {
friends: userFriends,
@@ -331,33 +354,42 @@ const messages = defineMessages({
{{ formatMessage(messages.noFriendsMatch, { query: search }) }}
diff --git a/apps/app-frontend/src/components/ui/friends/FriendsSection.vue b/apps/app-frontend/src/components/ui/friends/FriendsSection.vue
index f9efeb79e6..ec453e6c38 100644
--- a/apps/app-frontend/src/components/ui/friends/FriendsSection.vue
+++ b/apps/app-frontend/src/components/ui/friends/FriendsSection.vue
@@ -31,6 +31,11 @@ const props = withDefaults(
},
)
+const emit = defineEmits<{
+ onOpen: []
+ onClose: []
+}>()
+
function createContextMenuOptions(friend: FriendWithUserData) {
if (friend.accepted) {
return [
@@ -112,6 +117,8 @@ const messages = defineMessages({
? ''
: ' cursor-pointer hover:brightness-[--hover-brightness] active:scale-[0.98] transition-all')
"
+ @on-open="emit('onOpen')"
+ @on-close="emit('onClose')"
>
diff --git a/apps/app-frontend/src/store/theme.ts b/apps/app-frontend/src/store/theme.ts
index 4b61ebff78..00d47dc5f3 100644
--- a/apps/app-frontend/src/store/theme.ts
+++ b/apps/app-frontend/src/store/theme.ts
@@ -18,6 +18,10 @@ export const DEFAULT_FEATURE_FLAGS = {
advanced_filters_collapsed: true,
always_show_copy_details: false,
hide_installed_modpacks: false,
+ friends_active_collapsed: false,
+ friends_online_collapsed: false,
+ friends_offline_collapsed: true,
+ friends_pending_collapsed: true,
}
export const THEME_OPTIONS = ['dark', 'light', 'oled', 'retro', 'system'] as const
diff --git a/packages/app-lib/src/state/settings.rs b/packages/app-lib/src/state/settings.rs
index 304cc43e4d..2e831754a5 100644
--- a/packages/app-lib/src/state/settings.rs
+++ b/packages/app-lib/src/state/settings.rs
@@ -66,6 +66,10 @@ pub enum FeatureFlag {
AdvancedFiltersCollapsed,
AlwaysShowCopyDetails,
HideInstalledModpacks,
+ FriendsActiveCollapsed,
+ FriendsOnlineCollapsed,
+ FriendsOfflineCollapsed,
+ FriendsPendingCollapsed,
}
impl Settings {