add feature

This commit is contained in:
Javalsta
2026-04-17 23:35:10 +01:00
parent e201d7046c
commit 0aa1317950
8 changed files with 58 additions and 11 deletions

View File

@@ -166,6 +166,9 @@ android {
val releaseKeyAlias = gradleOrEnv("PS_RELEASE_KEY_ALIAS", providers) val releaseKeyAlias = gradleOrEnv("PS_RELEASE_KEY_ALIAS", providers)
if (releaseStore.exists() && !releaseStorePass.isNullOrBlank() && !releaseKeyAlias.isNullOrBlank()) { if (releaseStore.exists() && !releaseStorePass.isNullOrBlank() && !releaseKeyAlias.isNullOrBlank()) {
signingConfig = signingConfigs.getByName("release") signingConfig = signingConfigs.getByName("release")
} else {
// Keep local release builds installable when private release credentials are unavailable.
signingConfig = signingConfigs.getByName("debug")
} }
} }
debug { debug {

View File

@@ -223,13 +223,7 @@ class AddFriendDialog(
friends: List<MessagingFriendInfo>, friends: List<MessagingFriendInfo>,
groups: List<MessagingGroupInfo> groups: List<MessagingGroupInfo>
) { ) {
cachedFriends = friends.run { cachedFriends = context.sortSocialFriends(friends, pinnedIds = pinnedIds)
if (pinnedIds != null) {
sortedBy { -pinnedIds.indexOf(it.userId) }
} else {
this
}
}
cachedGroups = groups.run { cachedGroups = groups.run {
if (pinnedIds != null) { if (pinnedIds != null) {
sortedBy { -pinnedIds.indexOf(it.conversationId) } sortedBy { -pinnedIds.indexOf(it.conversationId) }

View File

@@ -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<MessagingFriendInfo>,
pinnedIds: List<String>? = null
): List<MessagingFriendInfo> {
if (config.root.userInterface.sortSocialTabByStreakLength.get()) {
return friends.sortedWith(
compareByDescending<MessagingFriendInfo> { (it.streaks?.length ?: 0) > 0 }
.thenByDescending { it.streaks?.length ?: 0 }
)
}
return if (pinnedIds != null) {
friends.sortedBy { -pinnedIds.indexOf(it.userId) }
} else {
friends
}
}

View File

@@ -39,10 +39,12 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.navigation.NavBackStackEntry import androidx.navigation.NavBackStackEntry
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.eternal.purrfectsnap.R import me.eternal.purrfectsnap.R
import me.eternal.purrfectsnap.common.data.SocialScope import me.eternal.purrfectsnap.common.data.SocialScope
import me.eternal.purrfectsnap.ui.manager.pages.social.SocialRootSection 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 import me.eternal.purrfectsnap.ui.manager.theme.PurrfectPalette
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@@ -68,9 +70,15 @@ fun SocialRootSection.AphelionSocialScreen(nav: NavBackStackEntry) {
context.database.receiveMessagingDataCallback = { _, _ -> } 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 normalizedQuery = remember(searchQuery) { searchQuery.trim() }
val filteredFriends = remember(friendList, normalizedQuery) { val filteredFriends = remember(friendList, normalizedQuery, sortByStreakLength) {
if (normalizedQuery.isBlank()) { val matchingFriends = if (normalizedQuery.isBlank()) {
friendList friendList
} else { } else {
friendList.filter { friendList.filter {
@@ -78,6 +86,8 @@ fun SocialRootSection.AphelionSocialScreen(nav: NavBackStackEntry) {
it.displayName?.contains(normalizedQuery, ignoreCase = true) == true it.displayName?.contains(normalizedQuery, ignoreCase = true) == true
} }
} }
context.sortSocialFriends(matchingFriends)
} }
val filteredGroups = remember(groupList, normalizedQuery) { val filteredGroups = remember(groupList, normalizedQuery) {
if (normalizedQuery.isBlank()) { if (normalizedQuery.isBlank()) {

View File

@@ -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.home.QuickActionsDialog
import me.eternal.purrfectsnap.ui.manager.pages.scripting.ScriptingRootSection 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.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.pages.tracker.FriendTrackerManagerRoot
import me.eternal.purrfectsnap.ui.manager.theme.PurrfectPalette import me.eternal.purrfectsnap.ui.manager.theme.PurrfectPalette
import me.eternal.purrfectsnap.ui.setup.Requirements import me.eternal.purrfectsnap.ui.setup.Requirements
@@ -1316,9 +1317,15 @@ object LegacyTheme : ThemeContract {
context.database.receiveMessagingDataCallback = { _, _ -> } 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 normalizedQuery = remember(searchQuery) { searchQuery.trim() }
val filteredFriends = remember(friendList, normalizedQuery) { val filteredFriends = remember(friendList, normalizedQuery, sortByStreakLength) {
if (normalizedQuery.isBlank()) { val matchingFriends = if (normalizedQuery.isBlank()) {
friendList friendList
} else { } else {
friendList.filter { friendList.filter {
@@ -1326,6 +1333,8 @@ object LegacyTheme : ThemeContract {
it.displayName?.contains(normalizedQuery, ignoreCase = true) == true it.displayName?.contains(normalizedQuery, ignoreCase = true) == true
} }
} }
context.sortSocialFriends(matchingFriends)
} }
val filteredGroups = remember(groupList, normalizedQuery) { val filteredGroups = remember(groupList, normalizedQuery) {
if (normalizedQuery.isBlank()) { if (normalizedQuery.isBlank()) {

View File

@@ -1105,6 +1105,10 @@
"name": "Show Streak Expiration Info", "name": "Show Streak Expiration Info",
"description": "Shows a Streak Expiration timer next to the Streaks counter" "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": { "hide_friend_feed_entry": {
"name": "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" "description": "Hides a specific friend from the Friend Feed\nUse the social tab to manage this feature"

View File

@@ -1156,6 +1156,10 @@
"name": "Show Streak Expiration Info", "name": "Show Streak Expiration Info",
"description": "Shows a Streak Expiration timer next to the Streaks counter" "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": { "hide_friend_feed_entry": {
"name": "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" "description": "Hides a specific friend from the Friend Feed\nUse the social tab to manage this feature"

View File

@@ -33,6 +33,7 @@ class UserInterfaceTweaks : ConfigContainer() {
val mapFriendNameTags = boolean("map_friend_nametags") { requireRestart() } val mapFriendNameTags = boolean("map_friend_nametags") { requireRestart() }
val preventMessageListAutoScroll = boolean("prevent_message_list_auto_scroll") { requireRestart(); addNotices(FeatureNotice.UNSTABLE) } val preventMessageListAutoScroll = boolean("prevent_message_list_auto_scroll") { requireRestart(); addNotices(FeatureNotice.UNSTABLE) }
val streakExpirationInfo = boolean("streak_expiration_info") { requireRestart() } 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 hideFriendFeedEntry = boolean("hide_friend_feed_entry") { requireRestart() }
val hideStreakRestore = boolean("hide_streak_restore") { requireRestart() } val hideStreakRestore = boolean("hide_streak_restore") { requireRestart() }
val hideQuickAddSuggestions = boolean("hide_quick_add_suggestions") { requireRestart() } val hideQuickAddSuggestions = boolean("hide_quick_add_suggestions") { requireRestart() }