commit 8bdc1f6d6a6bd1c9eae215098e4ef12715b579e2
parent 1f8b214d4c66a5f723c54f87c6f0160bf745c332
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Sat,  7 Sep 2024 01:08:52 +0200

feat(bulk_messaging_action): sort and filter by location

Diffstat:
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/action/impl/BulkMessagingAction.kt | 25++++++++++++++++++++++++-
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/BetterLocation.kt | 19+++++++++++++++++--
2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/action/impl/BulkMessagingAction.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/action/impl/BulkMessagingAction.kt @@ -47,6 +47,7 @@ import me.rhunk.snapenhance.common.util.ktx.copyToClipboard import me.rhunk.snapenhance.common.util.snap.BitmojiSelfie import me.rhunk.snapenhance.core.action.AbstractAction import me.rhunk.snapenhance.core.features.impl.experiments.AddFriendSourceSpoof +import me.rhunk.snapenhance.core.features.impl.experiments.BetterLocation import me.rhunk.snapenhance.core.features.impl.messaging.Messaging import me.rhunk.snapenhance.core.ui.ViewAppearanceHelper import me.rhunk.snapenhance.core.util.EvictingMap @@ -66,6 +67,7 @@ class BulkMessagingAction : AbstractAction() { STREAK_LENGTH, MOST_MESSAGES_SENT, MOST_RECENT_MESSAGE, + NEAREST_LOCATION } enum class Filter { @@ -78,9 +80,11 @@ class BulkMessagingAction : AbstractAction() { BUSINESS_ACCOUNTS, STREAKS, NON_STREAKS, + LOCATION_ON_MAP } private val translation by lazy { context.translation.getCategory("bulk_messaging_action") } + private val betterLocation by lazy { context.feature(BetterLocation::class) } private fun removeAction( ctx: Context, @@ -156,6 +160,7 @@ class BulkMessagingAction : AbstractAction() { "b42f1f70-5a8b-4c53-8c25-34e7ec9e6781", // myai "84ee8839-3911-492d-8b94-72dd80f3713a", // teamsnapchat ) + return friends.filter { friend -> friend.userId !in userIdBlacklist && when (filter) { Filter.ALL -> true @@ -167,6 +172,7 @@ class BulkMessagingAction : AbstractAction() { Filter.BUSINESS_ACCOUNTS -> friend.businessCategory > 0 Filter.STREAKS -> friend.friendLinkType == FriendLinkType.MUTUAL.value && friend.addedTimestamp > 0 && friend.streakLength != 0 Filter.NON_STREAKS -> friend.friendLinkType == FriendLinkType.MUTUAL.value&& friend.addedTimestamp > 0 && friend.streakLength == 0 + Filter.LOCATION_ON_MAP -> betterLocation.locationHistory.contains(friend.userId) } && nameFilter.takeIf { it.isNotBlank() }?.let { name -> friend.mutableUsername?.contains( name, @@ -198,6 +204,8 @@ class BulkMessagingAction : AbstractAction() { var nameFilter by remember { mutableStateOf("") } suspend fun refreshList(clearSelected: Boolean = true) { + val myLocation = betterLocation.locationHistory[context.database.myUserId] + withContext(Dispatchers.IO) { val newFriends = context.database.getAllFriends().let { friends -> filterFriends(friends, filter, nameFilter) @@ -214,6 +222,14 @@ class BulkMessagingAction : AbstractAction() { SortBy.MOST_RECENT_MESSAGE -> newFriends.sortByDescending { getDMLastMessage(it.userId)?.creationTimestamp } + SortBy.NEAREST_LOCATION -> { + if (myLocation != null) { + newFriends.sortBy { + betterLocation.locationHistory[it.userId]?.distanceTo(myLocation) + ?: Double.MAX_VALUE + } + } + } } if (sortReverseOrder) newFriends.reverse() withContext(Dispatchers.Main) { @@ -436,7 +452,14 @@ class BulkMessagingAction : AbstractAction() { } lastMessage?.let { append("\nSent messages: ${it.serverMessageId}") - append("\nLast message date: ${DateFormat.getDateTimeInstance().format(Date(it.creationTimestamp))}") + append("\nLast message: ${DateFormat.getDateTimeInstance().format(Date(it.creationTimestamp))}") + } + betterLocation.locationHistory[context.database.myUserId]?.let { myLocation -> + betterLocation.locationHistory[friendInfo.userId]?.let { + append("\n${myLocation.distanceTo(it).let { distance -> + if (distance < 1) "${(distance * 1000).toInt()} m" else "${distance.toInt()} km" + } } away") + } } } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/BetterLocation.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/BetterLocation.kt @@ -36,6 +36,10 @@ import me.rhunk.snapenhance.core.util.ktx.isDarkTheme import me.rhunk.snapenhance.mapper.impl.CallbackMapper import java.nio.ByteBuffer import java.util.UUID +import kotlin.math.atan2 +import kotlin.math.cos +import kotlin.math.sin +import kotlin.math.sqrt data class FriendLocation( val userId: String, @@ -45,10 +49,21 @@ data class FriendLocation( val locality: String?, val localityPieces: List<String>, val batteryLevel: Float, -) +) { + fun distanceTo(other: FriendLocation): Double { + val deltaLat = Math.toRadians(other.latitude - this.latitude) + val deltaLong = Math.toRadians(other.longitude - this.longitude) + + val a = sin(deltaLat / 2) * sin(deltaLat / 2) + + cos(Math.toRadians(this.latitude)) * cos(Math.toRadians(other.latitude)) * + sin(deltaLong / 2) * sin(deltaLong / 2) + + return 6371 * 2 * atan2(sqrt(a), sqrt(1 - a)) + } +} class BetterLocation : Feature("Better Location") { - private val locationHistory = mutableMapOf<String, FriendLocation>() + val locationHistory = mutableMapOf<String, FriendLocation>() private val walkRadius by lazy { context.config.global.betterLocation.walkRadius.getNullable()