mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-04-29 22:24:35 +02:00
fix(core): feed entry table
Signed-off-by: rhunk <101876869+rhunk@users.noreply.github.com>
This commit is contained in:
parent
bf5d57758c
commit
f854b217a2
@ -45,6 +45,7 @@ class AddFriendDialog(
|
||||
id: String,
|
||||
bitmoji: String? = null,
|
||||
name: String,
|
||||
participantsCount: Int? = null,
|
||||
getCurrentState: () -> Boolean,
|
||||
onState: (Boolean) -> Unit = {},
|
||||
) {
|
||||
@ -74,12 +75,24 @@ class AddFriendDialog(
|
||||
size = 32,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = name,
|
||||
fontSize = 15.sp,
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = name,
|
||||
fontSize = 15.sp,
|
||||
)
|
||||
|
||||
participantsCount?.let {
|
||||
Text(
|
||||
text = translation.format("participants_text", "count" to it.toString()),
|
||||
fontSize = 12.sp,
|
||||
lineHeight = 12.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Checkbox(
|
||||
checked = currentState,
|
||||
@ -249,6 +262,7 @@ class AddFriendDialog(
|
||||
ListCardEntry(
|
||||
id = group.conversationId,
|
||||
name = group.name,
|
||||
participantsCount = group.participantsCount,
|
||||
getCurrentState = { actionHandler.getGroupState(group) }
|
||||
) { state ->
|
||||
actionHandler.onGroupState(group, state)
|
||||
|
@ -198,7 +198,8 @@
|
||||
"search_hint": "Search",
|
||||
"fetch_error": "Failed to fetch data",
|
||||
"category_groups": "Groups",
|
||||
"category_friends": "Friends"
|
||||
"category_friends": "Friends",
|
||||
"participants_text": "{count} participants"
|
||||
},
|
||||
"scripting_warning": {
|
||||
"title": "Warning",
|
||||
|
@ -3,13 +3,14 @@ package me.rhunk.snapenhance.common.database.impl
|
||||
import android.annotation.SuppressLint
|
||||
import android.database.Cursor
|
||||
import me.rhunk.snapenhance.common.database.DatabaseObject
|
||||
import me.rhunk.snapenhance.common.util.ktx.getBlobOrNull
|
||||
import me.rhunk.snapenhance.common.util.ktx.getIntOrNull
|
||||
import me.rhunk.snapenhance.common.util.ktx.getInteger
|
||||
import me.rhunk.snapenhance.common.util.ktx.getLong
|
||||
import me.rhunk.snapenhance.common.util.ktx.getLongOrNull
|
||||
import me.rhunk.snapenhance.common.util.ktx.getStringOrNull
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.UUID
|
||||
|
||||
data class FriendFeedEntry(
|
||||
var id: Int = 0,
|
||||
var feedDisplayName: String? = null,
|
||||
var participantsSize: Int = 0,
|
||||
var lastInteractionTimestamp: Long = 0,
|
||||
@ -18,24 +19,28 @@ data class FriendFeedEntry(
|
||||
var lastInteractionUserId: Int? = null,
|
||||
var key: String? = null,
|
||||
var friendUserId: String? = null,
|
||||
var participants: List<String>? = null,
|
||||
var conversationType: Int? = null,
|
||||
var friendDisplayName: String? = null,
|
||||
var friendDisplayUsername: String? = null,
|
||||
var friendLinkType: Int? = null,
|
||||
var bitmojiAvatarId: String? = null,
|
||||
var bitmojiSelfieId: String? = null,
|
||||
) : DatabaseObject {
|
||||
|
||||
@SuppressLint("Range")
|
||||
override fun write(cursor: Cursor) {
|
||||
with(cursor) {
|
||||
id = getInteger("_id")
|
||||
feedDisplayName = getStringOrNull("feedDisplayName")
|
||||
participantsSize = getInteger("participantsSize")
|
||||
lastInteractionTimestamp = getLong("lastInteractionTimestamp")
|
||||
displayTimestamp = getLong("displayTimestamp")
|
||||
key = getStringOrNull("client_conversation_id") ?: getStringOrNull("key")
|
||||
feedDisplayName = (getStringOrNull("conversation_title") ?: getStringOrNull("feedDisplayName"))?.takeIf { it.isNotBlank() }
|
||||
lastInteractionTimestamp = getLongOrNull("last_updated_timestamp") ?: getLongOrNull("lastInteractionTimestamp") ?: 0L
|
||||
|
||||
participants = getBlobOrNull("participants")?.toList()?.chunked(16)?.map { ByteBuffer.wrap(it.toByteArray()).run { UUID(long, long) }.toString() } ?: emptyList()
|
||||
participantsSize = getIntOrNull("participantsSize") ?: participants?.size ?: 0
|
||||
conversationType = getIntOrNull("conversation_type") ?: getIntOrNull("kind")
|
||||
|
||||
displayTimestamp = getLongOrNull("displayTimestamp") ?: 0L
|
||||
displayInteractionType = getStringOrNull("displayInteractionType")
|
||||
lastInteractionUserId = getIntOrNull("lastInteractionUserId")
|
||||
key = getStringOrNull("key")
|
||||
friendUserId = getStringOrNull("friendUserId")
|
||||
friendDisplayName = getStringOrNull("friendDisplayName")
|
||||
friendDisplayUsername = getStringOrNull("friendDisplayUsername")
|
||||
|
@ -330,22 +330,25 @@ class SnapEnhance {
|
||||
event.canceled = true
|
||||
val feedEntries = appContext.database.getFeedEntries(Int.MAX_VALUE)
|
||||
|
||||
val groups = feedEntries.filter { it.friendUserId == null }.map {
|
||||
val groups = feedEntries.filter { it.conversationType == 1 }.map {
|
||||
MessagingGroupInfo(
|
||||
it.key!!,
|
||||
it.feedDisplayName!!,
|
||||
it.feedDisplayName ?: "",
|
||||
it.participantsSize
|
||||
)
|
||||
}
|
||||
|
||||
val friends = feedEntries.filter { it.friendUserId != null }.map {
|
||||
val friends = feedEntries.filter { it.conversationType == 0 }.mapNotNull {
|
||||
val friendUserId = it.friendUserId ?: it.participants?.filter { it != appContext.database.myUserId }?.firstOrNull() ?: return@mapNotNull null
|
||||
val friend = appContext.database.getFriendInfo(friendUserId) ?: return@mapNotNull null
|
||||
|
||||
MessagingFriendInfo(
|
||||
it.friendUserId!!,
|
||||
appContext.database.getConversationLinkFromUserId(it.friendUserId!!)?.clientConversationId,
|
||||
it.friendDisplayName,
|
||||
it.friendDisplayUsername!!.split("|")[1],
|
||||
it.bitmojiAvatarId,
|
||||
it.bitmojiSelfieId,
|
||||
friendUserId,
|
||||
appContext.database.getConversationLinkFromUserId(friendUserId)?.clientConversationId,
|
||||
friend.displayName,
|
||||
friend.mutableUsername ?: friend.usernameForSorting!!,
|
||||
friend.bitmojiAvatarId,
|
||||
friend.bitmojiSelfieId,
|
||||
streaks = null
|
||||
)
|
||||
}
|
||||
@ -379,7 +382,7 @@ class SnapEnhance {
|
||||
return appContext.database.getFeedEntryByConversationId(uuid)?.let {
|
||||
MessagingGroupInfo(
|
||||
it.key!!,
|
||||
it.feedDisplayName!!,
|
||||
it.feedDisplayName ?: "",
|
||||
it.participantsSize
|
||||
).toSerialized()
|
||||
}
|
||||
|
@ -22,10 +22,12 @@ import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import kotlinx.coroutines.*
|
||||
import me.rhunk.snapenhance.common.data.ContentType
|
||||
import me.rhunk.snapenhance.common.database.impl.FriendFeedEntry
|
||||
import me.rhunk.snapenhance.common.ui.createComposeAlertDialog
|
||||
import me.rhunk.snapenhance.common.ui.rememberAsyncMutableState
|
||||
import me.rhunk.snapenhance.core.action.AbstractAction
|
||||
import me.rhunk.snapenhance.core.features.impl.messaging.Messaging
|
||||
import me.rhunk.snapenhance.core.logger.CoreLogger
|
||||
@ -72,6 +74,8 @@ class ExportChatMessages : AbstractAction() {
|
||||
val messageTypeFilter = remember { mutableStateListOf<ContentType>() }
|
||||
var amountOfMessages by remember { mutableIntStateOf(-1) }
|
||||
var downloadMedias by remember { mutableStateOf(false) }
|
||||
val allFriends by rememberAsyncMutableState(null) { context.database.getAllFriends().associateBy { it.userId!! } }
|
||||
val myUserId = context.database.myUserId
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@ -102,7 +106,7 @@ class ExportChatMessages : AbstractAction() {
|
||||
LazyColumn(
|
||||
modifier = Modifier.size(LocalConfiguration.current.screenWidthDp.dp, 300.dp)
|
||||
) {
|
||||
items(feedEntries) { feedEntry ->
|
||||
items(feedEntries, key = { it.key!! }) { feedEntry ->
|
||||
DropdownMenuItem(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = {
|
||||
@ -114,11 +118,26 @@ class ExportChatMessages : AbstractAction() {
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Checkbox(checked = selectedFeedEntries.contains(feedEntry), onCheckedChange = null)
|
||||
Text(
|
||||
text = feedEntry.feedDisplayName ?: feedEntry.friendDisplayName ?: "unknown",
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
text = remember(feedEntry) {
|
||||
(if (feedEntry.conversationType == 1) feedEntry.feedDisplayName else feedEntry.participants?.filter { it != myUserId }?.firstOrNull()?.let { userId ->
|
||||
allFriends?.get(userId)?.let { friend -> friend.displayName?.let { "$it (${friend.mutableUsername})" } ?: friend.mutableUsername }
|
||||
}) ?: "Unknown"
|
||||
},
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
lineHeight = 15.sp,
|
||||
maxLines = 1
|
||||
)
|
||||
if (feedEntry.conversationType == 1) {
|
||||
Text(
|
||||
text = "${feedEntry.participantsSize} participants",
|
||||
fontSize = 10.sp,
|
||||
lineHeight = 15.sp,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -332,12 +351,13 @@ class ExportChatMessages : AbstractAction() {
|
||||
) {
|
||||
//first fetch the first message
|
||||
val conversationId = feedEntry.key!!
|
||||
val conversationName = feedEntry.feedDisplayName ?: feedEntry.friendDisplayName!!.split("|").lastOrNull() ?: "unknown"
|
||||
val conversationParticipants = context.database.getConversationParticipants(feedEntry.key!!, useCache = false)
|
||||
?.mapNotNull {
|
||||
context.database.getFriendInfo(it)
|
||||
}?.associateBy { it.userId!! } ?: emptyMap()
|
||||
|
||||
val conversationName = feedEntry.feedDisplayName ?: conversationParticipants.values.take(3).joinToString("_") { it.mutableUsername ?: "" }
|
||||
|
||||
val publicFolder = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "SnapEnhance").also { if (!it.exists()) it.mkdirs() }
|
||||
val outputFile = publicFolder.resolve("conversation_${conversationName}_${System.currentTimeMillis()}.${exportParams.exportFormat.extension}")
|
||||
|
||||
|
@ -152,17 +152,6 @@ class DatabaseAccess(
|
||||
obj
|
||||
}
|
||||
|
||||
fun getFeedEntryByUserId(userId: String): FriendFeedEntry? {
|
||||
return useDatabase(DatabaseType.MAIN)?.performOperation {
|
||||
readDatabaseObject(
|
||||
FriendFeedEntry(),
|
||||
"FriendsFeedView",
|
||||
"friendUserId = ?",
|
||||
arrayOf(userId)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val myUserId by lazy {
|
||||
context.androidContext.getSharedPreferences("user_session_shared_pref", 0).getString("key_user_id", null) ?:
|
||||
useDatabase(DatabaseType.ARROYO)?.performOperation {
|
||||
@ -178,7 +167,14 @@ class DatabaseAccess(
|
||||
}
|
||||
|
||||
fun getFeedEntryByConversationId(conversationId: String): FriendFeedEntry? {
|
||||
return useDatabase(DatabaseType.MAIN)?.performOperation {
|
||||
return useDatabase(DatabaseType.ARROYO)?.performOperation {
|
||||
readDatabaseObject(
|
||||
FriendFeedEntry(),
|
||||
"feed_entry",
|
||||
"client_conversation_id = ?",
|
||||
arrayOf(conversationId)
|
||||
)
|
||||
} ?: useDatabase(DatabaseType.MAIN)?.performOperation {
|
||||
readDatabaseObject(
|
||||
FriendFeedEntry(),
|
||||
"FriendsFeedView",
|
||||
@ -230,20 +226,34 @@ class DatabaseAccess(
|
||||
}
|
||||
|
||||
fun getFeedEntries(limit: Int): List<FriendFeedEntry> {
|
||||
return useDatabase(DatabaseType.MAIN)?.performOperation {
|
||||
val entries = mutableListOf<FriendFeedEntry>()
|
||||
return useDatabase(DatabaseType.ARROYO)?.performOperation {
|
||||
safeRawQuery(
|
||||
"SELECT * FROM FriendsFeedView ORDER BY _id LIMIT ?",
|
||||
"SELECT * FROM feed_entry ORDER BY last_updated_timestamp DESC LIMIT ?",
|
||||
arrayOf(limit.toString())
|
||||
)?.use { query ->
|
||||
val list = mutableListOf<FriendFeedEntry>()
|
||||
while (query.moveToNext()) {
|
||||
val friendFeedEntry = FriendFeedEntry()
|
||||
try {
|
||||
friendFeedEntry.write(query)
|
||||
} catch (_: Throwable) {}
|
||||
list.add(friendFeedEntry)
|
||||
entries.add(friendFeedEntry)
|
||||
}
|
||||
list
|
||||
entries
|
||||
}
|
||||
}?.takeIf { it.isNotEmpty() } ?: useDatabase(DatabaseType.MAIN)?.performOperation {
|
||||
safeRawQuery(
|
||||
"SELECT * FROM FriendsFeedView ORDER BY _id LIMIT ?",
|
||||
arrayOf(limit.toString())
|
||||
)?.use { query ->
|
||||
while (query.moveToNext()) {
|
||||
val friendFeedEntry = FriendFeedEntry()
|
||||
try {
|
||||
friendFeedEntry.write(query)
|
||||
} catch (_: Throwable) {}
|
||||
entries.add(friendFeedEntry)
|
||||
}
|
||||
entries
|
||||
}
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
@ -91,15 +91,15 @@ class HalfSwipeNotifier : Feature("Half Swipe Notifier") {
|
||||
|
||||
if (minDuration > peekingDuration || maxDuration < peekingDuration) return
|
||||
|
||||
val groupName = context.database.getFeedEntryByConversationId(conversationId)?.feedDisplayName
|
||||
val feedEntry = context.database.getFeedEntryByConversationId(conversationId)
|
||||
val friendInfo = context.database.getFriendInfo(userId) ?: return
|
||||
|
||||
Notification.Builder(context.androidContext, channelId)
|
||||
.setContentTitle(groupName ?: friendInfo.displayName ?: friendInfo.mutableUsername)
|
||||
.setContentText(if (groupName != null) {
|
||||
.setContentTitle(feedEntry?.feedDisplayName ?: friendInfo.displayName ?: friendInfo.mutableUsername)
|
||||
.setContentText(if (feedEntry?.conversationType == 1) {
|
||||
translation.format("notification_content_group",
|
||||
"friend" to (friendInfo.displayName ?: friendInfo.mutableUsername).toString(),
|
||||
"group" to groupName,
|
||||
"group" to (feedEntry.feedDisplayName ?: "Group"),
|
||||
"duration" to peekingDuration.toString()
|
||||
)
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user