From 0aa1317950b9f037841bba6f1f3c46713453c424 Mon Sep 17 00:00:00 2001 From: Javalsta <1thomasnewman2010@gmail.com> Date: Fri, 17 Apr 2026 23:35:10 +0100 Subject: [PATCH] add feature --- app/build.gradle.kts | 3 +++ .../manager/pages/social/AddFriendDialog.kt | 8 +------ .../pages/social/SocialFriendSorting.kt | 22 +++++++++++++++++++ .../themes/aphelion/AphelionSocialView.kt | 14 ++++++++++-- .../pages/themes/legacy/LegacyTheme.kt | 13 +++++++++-- common/src/main/assets/lang/en_UK.json | 4 ++++ common/src/main/assets/lang/en_US.json | 4 ++++ .../common/config/impl/UserInterfaceTweaks.kt | 1 + 8 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/social/SocialFriendSorting.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1824cb64..901ff4a8 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -166,6 +166,9 @@ android { val releaseKeyAlias = gradleOrEnv("PS_RELEASE_KEY_ALIAS", providers) if (releaseStore.exists() && !releaseStorePass.isNullOrBlank() && !releaseKeyAlias.isNullOrBlank()) { signingConfig = signingConfigs.getByName("release") + } else { + // Keep local release builds installable when private release credentials are unavailable. + signingConfig = signingConfigs.getByName("debug") } } debug { diff --git a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/social/AddFriendDialog.kt b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/social/AddFriendDialog.kt index 678d3047..9d8b0a36 100644 --- a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/social/AddFriendDialog.kt +++ b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/social/AddFriendDialog.kt @@ -223,13 +223,7 @@ class AddFriendDialog( friends: List, groups: List ) { - cachedFriends = friends.run { - if (pinnedIds != null) { - sortedBy { -pinnedIds.indexOf(it.userId) } - } else { - this - } - } + cachedFriends = context.sortSocialFriends(friends, pinnedIds = pinnedIds) cachedGroups = groups.run { if (pinnedIds != null) { sortedBy { -pinnedIds.indexOf(it.conversationId) } diff --git a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/social/SocialFriendSorting.kt b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/social/SocialFriendSorting.kt new file mode 100644 index 00000000..1b2f8eaa --- /dev/null +++ b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/social/SocialFriendSorting.kt @@ -0,0 +1,22 @@ +package me.eternal.purrfectsnap.ui.manager.pages.social + +import me.eternal.purrfectsnap.RemoteSideContext +import me.eternal.purrfectsnap.common.data.MessagingFriendInfo + +internal fun RemoteSideContext.sortSocialFriends( + friends: List, + pinnedIds: List? = null +): List { + if (config.root.userInterface.sortSocialTabByStreakLength.get()) { + return friends.sortedWith( + compareByDescending { (it.streaks?.length ?: 0) > 0 } + .thenByDescending { it.streaks?.length ?: 0 } + ) + } + + return if (pinnedIds != null) { + friends.sortedBy { -pinnedIds.indexOf(it.userId) } + } else { + friends + } +} diff --git a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/themes/aphelion/AphelionSocialView.kt b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/themes/aphelion/AphelionSocialView.kt index 8bbb679e..20ad2ba2 100644 --- a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/themes/aphelion/AphelionSocialView.kt +++ b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/themes/aphelion/AphelionSocialView.kt @@ -39,10 +39,12 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavBackStackEntry +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import me.eternal.purrfectsnap.R import me.eternal.purrfectsnap.common.data.SocialScope import me.eternal.purrfectsnap.ui.manager.pages.social.SocialRootSection +import me.eternal.purrfectsnap.ui.manager.pages.social.sortSocialFriends import me.eternal.purrfectsnap.ui.manager.theme.PurrfectPalette @OptIn(ExperimentalFoundationApi::class) @@ -68,9 +70,15 @@ fun SocialRootSection.AphelionSocialScreen(nav: NavBackStackEntry) { context.database.receiveMessagingDataCallback = { _, _ -> } } } + val sortByStreakLength by produceState(initialValue = context.config.root.userInterface.sortSocialTabByStreakLength.get()) { + while (true) { + delay(300) + value = context.config.root.userInterface.sortSocialTabByStreakLength.get() + } + } val normalizedQuery = remember(searchQuery) { searchQuery.trim() } - val filteredFriends = remember(friendList, normalizedQuery) { - if (normalizedQuery.isBlank()) { + val filteredFriends = remember(friendList, normalizedQuery, sortByStreakLength) { + val matchingFriends = if (normalizedQuery.isBlank()) { friendList } else { friendList.filter { @@ -78,6 +86,8 @@ fun SocialRootSection.AphelionSocialScreen(nav: NavBackStackEntry) { it.displayName?.contains(normalizedQuery, ignoreCase = true) == true } } + + context.sortSocialFriends(matchingFriends) } val filteredGroups = remember(groupList, normalizedQuery) { if (normalizedQuery.isBlank()) { diff --git a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/themes/legacy/LegacyTheme.kt b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/themes/legacy/LegacyTheme.kt index dff2aca6..0b67c066 100644 --- a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/themes/legacy/LegacyTheme.kt +++ b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/themes/legacy/LegacyTheme.kt @@ -113,6 +113,7 @@ import me.eternal.purrfectsnap.ui.manager.pages.home.HomeSettings import me.eternal.purrfectsnap.ui.manager.pages.home.QuickActionsDialog import me.eternal.purrfectsnap.ui.manager.pages.scripting.ScriptingRootSection import me.eternal.purrfectsnap.ui.manager.pages.social.SocialRootSection +import me.eternal.purrfectsnap.ui.manager.pages.social.sortSocialFriends import me.eternal.purrfectsnap.ui.manager.pages.tracker.FriendTrackerManagerRoot import me.eternal.purrfectsnap.ui.manager.theme.PurrfectPalette import me.eternal.purrfectsnap.ui.setup.Requirements @@ -1316,9 +1317,15 @@ object LegacyTheme : ThemeContract { context.database.receiveMessagingDataCallback = { _, _ -> } } } + val sortByStreakLength by produceState(initialValue = context.config.root.userInterface.sortSocialTabByStreakLength.get()) { + while (true) { + delay(300) + value = context.config.root.userInterface.sortSocialTabByStreakLength.get() + } + } val normalizedQuery = remember(searchQuery) { searchQuery.trim() } - val filteredFriends = remember(friendList, normalizedQuery) { - if (normalizedQuery.isBlank()) { + val filteredFriends = remember(friendList, normalizedQuery, sortByStreakLength) { + val matchingFriends = if (normalizedQuery.isBlank()) { friendList } else { friendList.filter { @@ -1326,6 +1333,8 @@ object LegacyTheme : ThemeContract { it.displayName?.contains(normalizedQuery, ignoreCase = true) == true } } + + context.sortSocialFriends(matchingFriends) } val filteredGroups = remember(groupList, normalizedQuery) { if (normalizedQuery.isBlank()) { diff --git a/common/src/main/assets/lang/en_UK.json b/common/src/main/assets/lang/en_UK.json index c1f595a7..d56b5f81 100644 --- a/common/src/main/assets/lang/en_UK.json +++ b/common/src/main/assets/lang/en_UK.json @@ -1105,6 +1105,10 @@ "name": "Show Streak Expiration Info", "description": "Shows a Streak Expiration timer next to the Streaks counter" }, + "sort_social_tab_by_streak_length": { + "name": "Sort Social Tab by Streak Length", + "description": "Shows friends with streaks first, ordered from the longest streak to the shortest in the social tab and friend picker" + }, "hide_friend_feed_entry": { "name": "Hide Friend Feed Entry", "description": "Hides a specific friend from the Friend Feed\nUse the social tab to manage this feature" diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json index 7369cf61..0062aa93 100644 --- a/common/src/main/assets/lang/en_US.json +++ b/common/src/main/assets/lang/en_US.json @@ -1156,6 +1156,10 @@ "name": "Show Streak Expiration Info", "description": "Shows a Streak Expiration timer next to the Streaks counter" }, + "sort_social_tab_by_streak_length": { + "name": "Sort Social Tab by Streak Length", + "description": "Shows friends with streaks first, ordered from the longest streak to the shortest in the social tab and friend picker" + }, "hide_friend_feed_entry": { "name": "Hide Friend Feed Entry", "description": "Hides a specific friend from the Friend Feed\nUse the social tab to manage this feature" diff --git a/common/src/main/kotlin/me/eternal/purrfectsnap/common/config/impl/UserInterfaceTweaks.kt b/common/src/main/kotlin/me/eternal/purrfectsnap/common/config/impl/UserInterfaceTweaks.kt index a07ec875..d2004be2 100644 --- a/common/src/main/kotlin/me/eternal/purrfectsnap/common/config/impl/UserInterfaceTweaks.kt +++ b/common/src/main/kotlin/me/eternal/purrfectsnap/common/config/impl/UserInterfaceTweaks.kt @@ -33,6 +33,7 @@ class UserInterfaceTweaks : ConfigContainer() { val mapFriendNameTags = boolean("map_friend_nametags") { requireRestart() } val preventMessageListAutoScroll = boolean("prevent_message_list_auto_scroll") { requireRestart(); addNotices(FeatureNotice.UNSTABLE) } val streakExpirationInfo = boolean("streak_expiration_info") { requireRestart() } + val sortSocialTabByStreakLength = boolean("sort_social_tab_by_streak_length").apply { set(true) } val hideFriendFeedEntry = boolean("hide_friend_feed_entry") { requireRestart() } val hideStreakRestore = boolean("hide_streak_restore") { requireRestart() } val hideQuickAddSuggestions = boolean("hide_quick_add_suggestions") { requireRestart() }