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