Add jetpack compose

This commit is contained in:
andrew 2023-06-28 10:34:48 +09:30
parent b9f24bc4bd
commit ab8b2c42b9
15 changed files with 72 additions and 76 deletions

View File

@ -22,6 +22,7 @@ apply plugin: 'com.google.gms.google-services'
apply plugin: 'kotlinx-serialization' apply plugin: 'kotlinx-serialization'
apply plugin: 'dagger.hilt.android.plugin' apply plugin: 'dagger.hilt.android.plugin'
configurations.all { configurations.all {
exclude module: "commons-logging" exclude module: "commons-logging"
} }
@ -158,6 +159,10 @@ dependencies {
testImplementation 'org.robolectric:robolectric:4.4' testImplementation 'org.robolectric:robolectric:4.4'
testImplementation 'org.robolectric:shadows-multidex:4.4' testImplementation 'org.robolectric:shadows-multidex:4.4'
implementation 'androidx.compose.ui:ui:1.4.3'
implementation 'androidx.compose.material:material:1.4.3'
implementation 'androidx.compose.ui:ui-tooling:1.4.3'
} }
def canonicalVersionCode = 338 def canonicalVersionCode = 338
@ -203,6 +208,13 @@ android {
} }
} }
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.4.7'
}
defaultConfig { defaultConfig {
versionCode canonicalVersionCode * postFixSize versionCode canonicalVersionCode * postFixSize
versionName canonicalVersionName versionName canonicalVersionName

View File

@ -249,17 +249,12 @@ class WebRtcCallActivity : PassphraseRequiredActionBarActivity() {
viewModel.callState.collect { state -> viewModel.callState.collect { state ->
Log.d("Loki", "Consuming view model state $state") Log.d("Loki", "Consuming view model state $state")
when (state) { when (state) {
CALL_RINGING -> { CALL_RINGING -> if (wantsToAnswer) {
if (wantsToAnswer) { answerCall()
answerCall()
wantsToAnswer = false
}
}
CALL_OUTGOING -> {
}
CALL_CONNECTED -> {
wantsToAnswer = false wantsToAnswer = false
} }
CALL_CONNECTED -> wantsToAnswer = false
else -> {}
} }
updateControls(state) updateControls(state)
} }

View File

@ -68,7 +68,7 @@ object ConversationMenuHelper {
if (thread.expireMessages > 0) { if (thread.expireMessages > 0) {
inflater.inflate(R.menu.menu_conversation_expiration_on, menu) inflater.inflate(R.menu.menu_conversation_expiration_on, menu)
val item = menu.findItem(R.id.menu_expiring_messages) val item = menu.findItem(R.id.menu_expiring_messages)
val actionView = item.actionView val actionView = item.actionView!!
val iconView = actionView.findViewById<ImageView>(R.id.menu_badge_icon) val iconView = actionView.findViewById<ImageView>(R.id.menu_badge_icon)
val badgeView = actionView.findViewById<TextView>(R.id.expiration_badge) val badgeView = actionView.findViewById<TextView>(R.id.expiration_badge)
@ColorInt val color = context.getColorFromAttr(android.R.attr.textColorPrimary) @ColorInt val color = context.getColorFromAttr(android.R.attr.textColorPrimary)

View File

@ -98,7 +98,7 @@ class NewMessageFragment : Fragment() {
private fun hideLoader() { private fun hideLoader() {
binding.loader.animate().setDuration(150).alpha(0.0f).setListener(object : AnimatorListenerAdapter() { binding.loader.animate().setDuration(150).alpha(0.0f).setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) { override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation) super.onAnimationEnd(animation)
binding.loader.visibility = View.GONE binding.loader.visibility = View.GONE
} }

View File

@ -55,7 +55,7 @@ class JoinCommunityFragment : Fragment() {
fun hideLoader() { fun hideLoader() {
binding.loader.animate().setDuration(150).alpha(0.0f).setListener(object : AnimatorListenerAdapter() { binding.loader.animate().setDuration(150).alpha(0.0f).setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) { override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation) super.onAnimationEnd(animation)
binding.loader.visibility = View.GONE binding.loader.visibility = View.GONE
} }

View File

@ -76,6 +76,7 @@ fun ContentView.bindQuery(query: String, model: GlobalSearchAdapter.Model) {
} }
binding.searchResultSubtitle.text = getHighlight(query, membersString) binding.searchResultSubtitle.text = getHighlight(query, membersString)
} }
else -> {}
} }
} }

View File

@ -154,7 +154,7 @@ class KeyboardPageSearchView @JvmOverloads constructor(
.setDuration(REVEAL_DURATION) .setDuration(REVEAL_DURATION)
.alpha(0f) .alpha(0f)
.setListener(object : AnimationCompleteListener() { .setListener(object : AnimationCompleteListener() {
override fun onAnimationEnd(animation: Animator?) { override fun onAnimationEnd(animation: Animator) {
visibility = INVISIBLE visibility = INVISIBLE
} }
}) })

View File

@ -58,7 +58,7 @@ fun View.fadeIn(duration: Long = 150) {
fun View.fadeOut(duration: Long = 150) { fun View.fadeOut(duration: Long = 150) {
animate().setDuration(duration).alpha(0.0f).setListener(object : AnimatorListenerAdapter() { animate().setDuration(duration).alpha(0.0f).setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) { override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation) super.onAnimationEnd(animation)
visibility = View.GONE visibility = View.GONE
} }

View File

@ -8,6 +8,7 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "com.google.gms:google-services:$googleServicesVersion" classpath "com.google.gms:google-services:$googleServicesVersion"
classpath files('libs/gradle-witness.jar') classpath files('libs/gradle-witness.jar')
classpath "com.squareup:javapoet:1.13.0"
} }
} }
@ -52,6 +53,6 @@ allprojects {
project.ext { project.ext {
androidMinimumSdkVersion = 23 androidMinimumSdkVersion = 23
androidTargetSdkVersion = 31 androidTargetSdkVersion = 31
androidCompileSdkVersion = 32 androidCompileSdkVersion = 33
} }
} }

View File

@ -4,11 +4,11 @@ org.gradle.jvmargs=-Xmx8g
gradlePluginVersion=7.3.1 gradlePluginVersion=7.3.1
googleServicesVersion=4.3.12 googleServicesVersion=4.3.12
kotlinVersion=1.6.21 kotlinVersion=1.8.21
coroutinesVersion=1.6.4 coroutinesVersion=1.6.4
kotlinxJsonVersion=1.3.3 kotlinxJsonVersion=1.3.3
lifecycleVersion=2.5.1 lifecycleVersion=2.5.1
daggerVersion=2.40.1 daggerVersion=2.46.1
glideVersion=4.11.0 glideVersion=4.11.0
kovenantVersion=3.3.0 kovenantVersion=3.3.0
curve25519Version=0.6.0 curve25519Version=0.6.0

View File

@ -235,10 +235,9 @@ class BatchMessageReceiveJob(
val openGroupID = data.getStringOrDefault(OPEN_GROUP_ID_KEY, null) val openGroupID = data.getStringOrDefault(OPEN_GROUP_ID_KEY, null)
val parameters = (0 until numMessages).map { index -> val parameters = (0 until numMessages).map { index ->
val data = contents[index]
val serverHash = serverHashes[index].let { if (it.isEmpty()) null else it } val serverHash = serverHashes[index].let { if (it.isEmpty()) null else it }
val serverId = openGroupMessageServerIDs[index].let { if (it == -1L) null else it } val serverId = openGroupMessageServerIDs[index].let { if (it == -1L) null else it }
MessageReceiveParameters(data, serverHash, serverId) MessageReceiveParameters(contents[index], serverHash, serverId)
} }
return BatchMessageReceiveJob(parameters, openGroupID) return BatchMessageReceiveJob(parameters, openGroupID)

View File

@ -32,7 +32,6 @@ class MessageReceiveJob(val data: ByteArray, val serverHash: String? = null, val
fun executeAsync(dispatcherName: String): Promise<Unit, Exception> { fun executeAsync(dispatcherName: String): Promise<Unit, Exception> {
val deferred = deferred<Unit, Exception>() val deferred = deferred<Unit, Exception>()
try { try {
val isRetry: Boolean = failureCount != 0
val serverPublicKey = openGroupID?.let { val serverPublicKey = openGroupID?.let {
MessagingModuleConfiguration.shared.storage.getOpenGroupPublicKey(it.split(".").dropLast(1).joinToString(".")) MessagingModuleConfiguration.shared.storage.getOpenGroupPublicKey(it.split(".").dropLast(1).joinToString("."))
} }

View File

@ -2,6 +2,7 @@ package org.session.libsession.messaging.mentions
import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.contacts.Contact
import java.util.*
object MentionsManager { object MentionsManager {
var userPublicKeyCache = mutableMapOf<Long, Set<String>>() // Thread ID to set of user hex encoded public keys var userPublicKeyCache = mutableMapOf<Long, Set<String>>() // Thread ID to set of user hex encoded public keys
@ -32,9 +33,9 @@ object MentionsManager {
candidates.sortedBy { it.displayName } candidates.sortedBy { it.displayName }
if (query.length >= 2) { if (query.length >= 2) {
// Filter out any non-matching candidates // Filter out any non-matching candidates
candidates = candidates.filter { it.displayName.toLowerCase().contains(query.toLowerCase()) } candidates = candidates.filter { it.displayName.lowercase(Locale.getDefault()).contains(query.lowercase(Locale.getDefault())) }
// Sort based on where in the candidate the query occurs // Sort based on where in the candidate the query occurs
candidates.sortedBy { it.displayName.toLowerCase().indexOf(query.toLowerCase()) } candidates.sortedBy { it.displayName.lowercase(Locale.getDefault()).indexOf(query.lowercase(Locale.getDefault())) }
} }
// Return // Return
return candidates return candidates

View File

@ -169,6 +169,7 @@ class OpenGroupPoller(private val server: String, private val executorService: S
is Endpoint.Outbox, is Endpoint.OutboxSince -> { is Endpoint.Outbox, is Endpoint.OutboxSince -> {
handleDirectMessages(server, true, response.body as List<OpenGroupApi.DirectMessage>) handleDirectMessages(server, true, response.body as List<OpenGroupApi.DirectMessage>)
} }
else -> {}
} }
if (secondToLastJob == null && !isCaughtUp) { if (secondToLastJob == null && !isCaughtUp) {
isCaughtUp = true isCaughtUp = true

View File

@ -4,52 +4,51 @@ import android.content.Context
import org.session.libsession.R import org.session.libsession.R
import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.calls.CallMessageType import org.session.libsession.messaging.calls.CallMessageType
import org.session.libsession.messaging.calls.CallMessageType.CALL_FIRST_MISSED
import org.session.libsession.messaging.calls.CallMessageType.CALL_INCOMING
import org.session.libsession.messaging.calls.CallMessageType.CALL_MISSED
import org.session.libsession.messaging.calls.CallMessageType.CALL_OUTGOING
import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage
import org.session.libsession.utilities.ExpirationUtil import org.session.libsession.utilities.ExpirationUtil
import org.session.libsession.utilities.truncateIdForDisplay import org.session.libsession.utilities.truncateIdForDisplay
object UpdateMessageBuilder { object UpdateMessageBuilder {
val storage = MessagingModuleConfiguration.shared.storage
fun getSenderName(senderId: String) = storage.getContactWithSessionID(senderId)
?.displayName(Contact.ContactContext.REGULAR)
?: truncateIdForDisplay(senderId)
fun buildGroupUpdateMessage(context: Context, updateMessageData: UpdateMessageData, senderId: String? = null, isOutgoing: Boolean = false): String { fun buildGroupUpdateMessage(context: Context, updateMessageData: UpdateMessageData, senderId: String? = null, isOutgoing: Boolean = false): String {
var message = "" val updateData = updateMessageData.kind
val updateData = updateMessageData.kind ?: return message if (updateData == null || !isOutgoing && senderId == null) return ""
if (!isOutgoing && senderId == null) return message val senderName: String = if (isOutgoing) context.getString(R.string.MessageRecord_you)
val storage = MessagingModuleConfiguration.shared.storage else getSenderName(senderId!!)
val senderName: String = if (!isOutgoing) {
storage.getContactWithSessionID(senderId!!)?.displayName(Contact.ContactContext.REGULAR) ?: truncateIdForDisplay(senderId)
} else { context.getString(R.string.MessageRecord_you) }
when (updateData) { return when (updateData) {
is UpdateMessageData.Kind.GroupCreation -> { is UpdateMessageData.Kind.GroupCreation -> if (isOutgoing) {
message = if (isOutgoing) { context.getString(R.string.MessageRecord_you_created_a_new_group)
context.getString(R.string.MessageRecord_you_created_a_new_group) } else {
} else { context.getString(R.string.MessageRecord_s_added_you_to_the_group, senderName)
context.getString(R.string.MessageRecord_s_added_you_to_the_group, senderName)
}
} }
is UpdateMessageData.Kind.GroupNameChange -> { is UpdateMessageData.Kind.GroupNameChange -> if (isOutgoing) {
message = if (isOutgoing) { context.getString(R.string.MessageRecord_you_renamed_the_group_to_s, updateData.name)
context.getString(R.string.MessageRecord_you_renamed_the_group_to_s, updateData.name) } else {
} else { context.getString(R.string.MessageRecord_s_renamed_the_group_to_s, senderName, updateData.name)
context.getString(R.string.MessageRecord_s_renamed_the_group_to_s, senderName, updateData.name)
}
} }
is UpdateMessageData.Kind.GroupMemberAdded -> { is UpdateMessageData.Kind.GroupMemberAdded -> {
val members = updateData.updatedMembers.joinToString(", ") { val members = updateData.updatedMembers.joinToString(", ", transform = ::getSenderName)
storage.getContactWithSessionID(it)?.displayName(Contact.ContactContext.REGULAR) ?: it if (isOutgoing) {
}
message = if (isOutgoing) {
context.getString(R.string.MessageRecord_you_added_s_to_the_group, members) context.getString(R.string.MessageRecord_you_added_s_to_the_group, members)
} else { } else {
context.getString(R.string.MessageRecord_s_added_s_to_the_group, senderName, members) context.getString(R.string.MessageRecord_s_added_s_to_the_group, senderName, members)
} }
} }
is UpdateMessageData.Kind.GroupMemberRemoved -> { is UpdateMessageData.Kind.GroupMemberRemoved -> {
val storage = MessagingModuleConfiguration.shared.storage
val userPublicKey = storage.getUserPublicKey()!! val userPublicKey = storage.getUserPublicKey()!!
// 1st case: you are part of the removed members // 1st case: you are part of the removed members
message = if (userPublicKey in updateData.updatedMembers) { return if (userPublicKey in updateData.updatedMembers) {
if (isOutgoing) { if (isOutgoing) {
context.getString(R.string.MessageRecord_left_group) context.getString(R.string.MessageRecord_left_group)
} else { } else {
@ -57,9 +56,7 @@ object UpdateMessageBuilder {
} }
} else { } else {
// 2nd case: you are not part of the removed members // 2nd case: you are not part of the removed members
val members = updateData.updatedMembers.joinToString(", ") { val members = updateData.updatedMembers.joinToString(", ", transform = ::getSenderName)
storage.getContactWithSessionID(it)?.displayName(Contact.ContactContext.REGULAR) ?: it
}
if (isOutgoing) { if (isOutgoing) {
context.getString(R.string.MessageRecord_you_removed_s_from_the_group, members) context.getString(R.string.MessageRecord_you_removed_s_from_the_group, members)
} else { } else {
@ -67,22 +64,19 @@ object UpdateMessageBuilder {
} }
} }
} }
is UpdateMessageData.Kind.GroupMemberLeft -> { is UpdateMessageData.Kind.GroupMemberLeft -> if (isOutgoing) {
message = if (isOutgoing) { context.getString(R.string.MessageRecord_left_group)
context.getString(R.string.MessageRecord_left_group) } else {
} else { context.getString(R.string.ConversationItem_group_action_left, senderName)
context.getString(R.string.ConversationItem_group_action_left, senderName)
}
} }
else -> return ""
} }
return message
} }
fun buildExpirationTimerMessage(context: Context, duration: Long, senderId: String? = null, isOutgoing: Boolean = false): String { fun buildExpirationTimerMessage(context: Context, duration: Long, senderId: String? = null, isOutgoing: Boolean = false): String {
if (!isOutgoing && senderId == null) return "" if (!isOutgoing && senderId == null) return ""
val storage = MessagingModuleConfiguration.shared.storage val senderName: String = if (!isOutgoing) {
val senderName: String? = if (!isOutgoing) { getSenderName(senderId!!)
storage.getContactWithSessionID(senderId!!)?.displayName(Contact.ContactContext.REGULAR) ?: truncateIdForDisplay(senderId)
} else { context.getString(R.string.MessageRecord_you) } } else { context.getString(R.string.MessageRecord_you) }
return if (duration <= 0) { return if (duration <= 0) {
if (isOutgoing) context.getString(R.string.MessageRecord_you_disabled_disappearing_messages) if (isOutgoing) context.getString(R.string.MessageRecord_you_disabled_disappearing_messages)
@ -95,8 +89,7 @@ object UpdateMessageBuilder {
} }
fun buildDataExtractionMessage(context: Context, kind: DataExtractionNotificationInfoMessage.Kind, senderId: String? = null): String { fun buildDataExtractionMessage(context: Context, kind: DataExtractionNotificationInfoMessage.Kind, senderId: String? = null): String {
val storage = MessagingModuleConfiguration.shared.storage val senderName = getSenderName(senderId!!)
val senderName = storage.getContactWithSessionID(senderId!!)?.displayName(Contact.ContactContext.REGULAR) ?: truncateIdForDisplay(senderId)
return when (kind) { return when (kind) {
DataExtractionNotificationInfoMessage.Kind.SCREENSHOT -> DataExtractionNotificationInfoMessage.Kind.SCREENSHOT ->
context.getString(R.string.MessageRecord_s_took_a_screenshot, senderName) context.getString(R.string.MessageRecord_s_took_a_screenshot, senderName)
@ -105,18 +98,12 @@ object UpdateMessageBuilder {
} }
} }
fun buildCallMessage(context: Context, type: CallMessageType, sender: String): String { fun buildCallMessage(context: Context, type: CallMessageType, sender: String): String =
val storage = MessagingModuleConfiguration.shared.storage when (type) {
val senderName = storage.getContactWithSessionID(sender)?.displayName(Contact.ContactContext.REGULAR) ?: sender CALL_INCOMING -> R.string.MessageRecord_s_called_you
return when (type) { CALL_OUTGOING -> R.string.MessageRecord_called_s
CallMessageType.CALL_MISSED -> CALL_MISSED, CALL_FIRST_MISSED -> R.string.MessageRecord_missed_call_from
context.getString(R.string.MessageRecord_missed_call_from, senderName) }.let {
CallMessageType.CALL_INCOMING -> context.getString(it, storage.getContactWithSessionID(sender)?.displayName(Contact.ContactContext.REGULAR) ?: sender)
context.getString(R.string.MessageRecord_s_called_you, senderName)
CallMessageType.CALL_OUTGOING ->
context.getString(R.string.MessageRecord_called_s, senderName)
CallMessageType.CALL_FIRST_MISSED ->
context.getString(R.string.MessageRecord_missed_call_from, senderName)
} }
}
} }