diff --git a/apps/android/app/build.gradle b/apps/android/app/build.gradle index 30811d9b05..1a91671c05 100644 --- a/apps/android/app/build.gradle +++ b/apps/android/app/build.gradle @@ -40,6 +40,11 @@ android { } kotlinOptions { jvmTarget = '1.8' + freeCompilerArgs += "-opt-in=kotlinx.coroutines.DelicateCoroutinesApi" + freeCompilerArgs += "-opt-in=androidx.compose.ui.text.ExperimentalTextApi" + freeCompilerArgs += "-opt-in=androidx.compose.material.ExperimentalMaterialApi" + freeCompilerArgs += "-opt-in=com.google.accompanist.insets.ExperimentalAnimatedInsets" + freeCompilerArgs += "-opt-in=com.google.accompanist.permissions.ExperimentalPermissionsApi" } externalNativeBuild { cmake { @@ -73,6 +78,10 @@ dependencies { implementation "androidx.navigation:navigation-compose:2.4.1" implementation "com.google.accompanist:accompanist-insets:0.23.0" + def work_version = "2.7.1" + implementation "androidx.work:work-runtime-ktx:$work_version" + implementation "androidx.work:work-multiprocess:$work_version" + def camerax_version = "1.1.0-beta01" implementation "androidx.camera:camera-core:${camerax_version}" implementation "androidx.camera:camera-camera2:${camerax_version}" diff --git a/apps/android/app/src/main/java/chat/simplex/app/MainActivity.kt b/apps/android/app/src/main/java/chat/simplex/app/MainActivity.kt index a935883631..30ee947668 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/MainActivity.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/MainActivity.kt @@ -2,15 +2,14 @@ package chat.simplex.app import android.app.Application import android.content.Intent +import android.net.Uri import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.foundation.layout.Box -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.runtime.Composable -import androidx.compose.ui.text.ExperimentalTextApi +import androidx.compose.runtime.* import androidx.lifecycle.AndroidViewModel import androidx.navigation.* import androidx.navigation.compose.* @@ -20,26 +19,20 @@ import chat.simplex.app.views.* import chat.simplex.app.views.chat.ChatInfoView import chat.simplex.app.views.chat.ChatView import chat.simplex.app.views.chatlist.ChatListView +import chat.simplex.app.views.chatlist.openChat import chat.simplex.app.views.helpers.withApi import chat.simplex.app.views.newchat.* import chat.simplex.app.views.usersettings.* -import com.google.accompanist.insets.ExperimentalAnimatedInsets -import com.google.accompanist.permissions.ExperimentalPermissionsApi -import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.serialization.decodeFromString -@ExperimentalTextApi -@DelicateCoroutinesApi -@ExperimentalAnimatedInsets -@ExperimentalPermissionsApi -@ExperimentalMaterialApi class MainActivity: ComponentActivity() { private val vm by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // testJson() - connectIfOpenedViaUri(intent, vm.chatModel) + processIntent(intent, vm.chatModel) +// vm.app.initiateBackgroundWork() setContent { SimpleXTheme { Navigation(vm.chatModel) @@ -48,50 +41,37 @@ class MainActivity: ComponentActivity() { } } -@DelicateCoroutinesApi class SimplexViewModel(application: Application): AndroidViewModel(application) { - val chatModel = getApplication().chatModel + val app = getApplication() + val chatModel = app.chatModel } -@ExperimentalTextApi -@DelicateCoroutinesApi -@ExperimentalPermissionsApi -@ExperimentalMaterialApi @Composable fun MainPage(chatModel: ChatModel, nav: NavController) { when (chatModel.userCreated.value) { null -> SplashView() - false -> WelcomeView(chatModel) { nav.navigate(Pages.ChatList.route) } - true -> ChatListView(chatModel, nav) + false -> WelcomeView(chatModel) // { nav.navigate(Pages.ChatList.route) } + true -> if (chatModel.chatId.value == null) { + ChatListView(chatModel, nav) + } else { + ChatView(chatModel, nav) + } } } -@ExperimentalTextApi -@ExperimentalAnimatedInsets -@DelicateCoroutinesApi -@ExperimentalPermissionsApi -@ExperimentalMaterialApi @Composable fun Navigation(chatModel: ChatModel) { + println("*** in Navigation") val nav = rememberNavController() - + val scope = rememberCoroutineScope() Box { NavHost(navController = nav, startDestination = Pages.Home.route) { composable(route = Pages.Home.route) { + println("*** composable MainPage") MainPage(chatModel, nav) } composable(route = Pages.Welcome.route) { - WelcomeView(chatModel) { - nav.navigate(Pages.Home.route) { - popUpTo(Pages.Home.route) { inclusive = true } - } - } - } - composable(route = Pages.ChatList.route) { - ChatListView(chatModel, nav) - } - composable(route = Pages.Chat.route) { - ChatView(chatModel, nav) + WelcomeView(chatModel) } composable(route = Pages.AddContact.route) { AddContactView(chatModel, nav) @@ -136,8 +116,6 @@ sealed class Pages(val route: String) { object Terminal: Pages("terminal") object Welcome: Pages("welcome") object TerminalItemDetails: Pages("details") - object ChatList: Pages("chats") - object Chat: Pages("chat") object AddContact: Pages("add_contact") object Connect: Pages("connect") object ChatInfo: Pages("chat_info") @@ -147,28 +125,42 @@ sealed class Pages(val route: String) { object Markdown: Pages("markdown") } -@DelicateCoroutinesApi -fun connectIfOpenedViaUri(intent: Intent?, chatModel: ChatModel) { - val uri = intent?.data - if (intent?.action == "android.intent.action.VIEW" && uri != null) { - Log.d("SIMPLEX", "connectIfOpenedViaUri: opened via link") - if (chatModel.currentUser.value == null) { - chatModel.appOpenUrl.value = uri - } else { - withUriAction(chatModel, uri) { action -> - chatModel.alertManager.showAlertMsg( - title = "Connect via $action link?", - text = "Your profile will be sent to the contact that you received this link from.", - confirmText = "Connect", - onConfirm = { - withApi { - Log.d("SIMPLEX", "connectIfOpenedViaUri: connecting") - connectViaUri(chatModel, action, uri) - } - } - ) +fun processIntent(intent: Intent?, chatModel: ChatModel) { + when (intent?.action) { + NtfManager.OpenChatAction -> { + val chatId = intent.getStringExtra("chatId") + Log.d("SIMPLEX", "processIntent: OpenChatAction $chatId") + if (chatId != null) { + val cInfo = chatModel.getChat(chatId)?.chatInfo + if (cInfo != null) withApi { openChat(chatModel, cInfo) } } } + "android.intent.action.VIEW" -> { + val uri = intent.data + if (uri != null) connectIfOpenedViaUri(uri, chatModel) + } + } +} + +fun connectIfOpenedViaUri(uri: Uri, chatModel: ChatModel) { + Log.d("SIMPLEX", "connectIfOpenedViaUri: opened via link") + if (chatModel.currentUser.value == null) { + // TODO open from chat list view + chatModel.appOpenUrl.value = uri + } else { + withUriAction(chatModel, uri) { action -> + chatModel.alertManager.showAlertMsg( + title = "Connect via $action link?", + text = "Your profile will be sent to the contact that you received this link from.", + confirmText = "Connect", + onConfirm = { + withApi { + Log.d("SIMPLEX", "connectIfOpenedViaUri: connecting") + connectViaUri(chatModel, action, uri) + } + } + ) + } } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/SimplexApp.kt b/apps/android/app/src/main/java/chat/simplex/app/SimplexApp.kt index cb8fa644fe..aa04839b3f 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/SimplexApp.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/SimplexApp.kt @@ -6,14 +6,14 @@ import android.util.Log import androidx.compose.material.* import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf -import chat.simplex.app.model.ChatController -import chat.simplex.app.model.ChatModel +import androidx.work.* +import chat.simplex.app.model.* import chat.simplex.app.views.helpers.withApi -import kotlinx.coroutines.DelicateCoroutinesApi import java.io.BufferedReader import java.io.InputStreamReader import java.util.* import java.util.concurrent.Semaphore +import java.util.concurrent.TimeUnit import kotlin.concurrent.thread // ghc's rts @@ -27,15 +27,28 @@ external fun chatInit(path: String): ChatCtrl external fun chatSendCmd(ctrl: ChatCtrl, msg: String) : String external fun chatRecvMsg(ctrl: ChatCtrl) : String -@DelicateCoroutinesApi class SimplexApp: Application() { private lateinit var controller: ChatController lateinit var chatModel: ChatModel + private lateinit var ntfManager: NtfManager + + fun initiateBackgroundWork() { + val backgroundConstraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build() + val request = OneTimeWorkRequestBuilder() + .setInitialDelay(5, TimeUnit.MINUTES) + .setConstraints(backgroundConstraints) + .build() + WorkManager.getInstance(applicationContext) + .enqueue(request) + } override fun onCreate() { super.onCreate() + ntfManager = NtfManager(applicationContext) val ctrl = chatInit(applicationContext.filesDir.toString()) - controller = ChatController(ctrl, AlertManager()) + controller = ChatController(ctrl, AlertManager(), ntfManager, applicationContext) chatModel = controller.chatModel withApi { val user = controller.apiGetActiveUser() diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/BGManager.kt b/apps/android/app/src/main/java/chat/simplex/app/model/BGManager.kt new file mode 100644 index 0000000000..a511bf06fe --- /dev/null +++ b/apps/android/app/src/main/java/chat/simplex/app/model/BGManager.kt @@ -0,0 +1,39 @@ +package chat.simplex.app.model + +import android.content.Context +import android.util.Log +import androidx.work.* +import chat.simplex.app.chatRecvMsg +import java.util.concurrent.TimeUnit + +class BackgroundAPIWorker(appContext: Context, workerParams: WorkerParameters, ctrl: ChatCtrl): + Worker(appContext, workerParams) { + val controller = ctrl + override fun doWork(): Result { + Log.d("BackgroundAPIWorker", "running") + getNewItems() + + // Enqueue another request for later to make this periodic + val request = buildRequest() + WorkManager.getInstance(applicationContext) + .enqueue(request) + + return Result.success() + } + + private fun getNewItems() { + val json = chatRecvMsg(controller) + val r = APIResponse.decodeStr(json).resp + Log.d("SIMPLEX", "chatRecvMsg: ${r.responseType}") + } + + private fun buildRequest(): OneTimeWorkRequest { + val backgroundConstraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build() + return OneTimeWorkRequestBuilder() + .setInitialDelay(5, TimeUnit.MINUTES) + .setConstraints(backgroundConstraints) + .build() + } +} diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt index 82b1dbf827..726b2fb5d4 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt @@ -8,18 +8,15 @@ import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.font.* import androidx.compose.ui.text.style.TextDecoration import chat.simplex.app.SimplexApp -import chat.simplex.app.ui.theme.* -import kotlinx.coroutines.DelicateCoroutinesApi +import chat.simplex.app.ui.theme.SecretColor import kotlinx.datetime.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -@DelicateCoroutinesApi class ChatModel(val controller: ChatController, val alertManager: SimplexApp.AlertManager) { var currentUser = mutableStateOf(null) var userCreated = mutableStateOf(null) var chats = mutableStateListOf() - var chatsLoaded = mutableStateOf(null) var chatId = mutableStateOf(null) var chatItems = mutableStateListOf() diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/NtfManager.kt b/apps/android/app/src/main/java/chat/simplex/app/model/NtfManager.kt new file mode 100644 index 0000000000..114cf22bf6 --- /dev/null +++ b/apps/android/app/src/main/java/chat/simplex/app/model/NtfManager.kt @@ -0,0 +1,78 @@ +package chat.simplex.app.model + +import android.app.* +import android.content.Context +import android.content.Intent +import android.util.Log +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import chat.simplex.app.MainActivity +import chat.simplex.app.R +import kotlinx.datetime.Clock + +class NtfManager(val context: Context) { + companion object { + const val MessageChannel: String = "chat.simplex.app.MESSAGE_NOTIFICATION" + const val MessageGroup: String = "chat.simplex.app.MESSAGE_NOTIFICATION" + const val OpenChatAction: String = "chat.simplex.app.OPEN_CHAT" + } + + private val manager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + private var prevNtfTime = mutableMapOf() + private val msgNtfTimeoutMs = 30000L + + init { + manager.createNotificationChannel(NotificationChannel( + MessageChannel, + "SimpleX Chat messages", + NotificationManager.IMPORTANCE_HIGH + )) + } + + fun notifyMessageReceived(cInfo: ChatInfo, cItem: ChatItem) { + Log.d("SIMPLEX", "notifyMessageReceived ${cInfo.id}") + val now = Clock.System.now().toEpochMilliseconds() + val recentNotification = (now - prevNtfTime.getOrDefault(cInfo.id, 0) < msgNtfTimeoutMs) + prevNtfTime[cInfo.id] = now + + val notification = NotificationCompat.Builder(context, MessageChannel) + .setContentTitle(cInfo.displayName) + .setContentText(cItem.content.text) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setGroup(MessageGroup) + .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN) + .setSmallIcon(R.drawable.ntf_icon) + .setColor(0x88FFFF) + .setAutoCancel(true) + .setContentIntent(getMsgPendingIntent(cInfo)) + .setSilent(recentNotification) + .build() + + val summary = NotificationCompat.Builder(context, MessageChannel) + .setSmallIcon(R.drawable.ntf_icon) + .setColor(0x88FFFF) + .setGroup(MessageGroup) + .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN) + .setGroupSummary(true) + .build() + + with(NotificationManagerCompat.from(context)) { + // using cInfo.id only shows one notification per chat and updates it when the message arrives + notify(cInfo.id.hashCode(), notification) + notify(0, summary) + } + } + + private fun getMsgPendingIntent(cInfo: ChatInfo) : PendingIntent{ + Log.d("SIMPLEX", "getMsgPendingIntent ${cInfo.id}") + val uniqueInt = (System.currentTimeMillis() and 0xfffffff).toInt() + val intent = Intent(context, MainActivity::class.java) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) + .putExtra("chatId", cInfo.id) + .setAction(OpenChatAction) + return TaskStackBuilder.create(context).run { + addNextIntentWithParentStack(intent) + getPendingIntent(uniqueInt, PendingIntent.FLAG_IMMUTABLE) + } + } +} diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt index 613003c036..875b90b1e2 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt @@ -1,10 +1,14 @@ package chat.simplex.app.model +import android.app.ActivityManager +import android.app.ActivityManager.RunningAppProcessInfo +import android.content.Context import android.util.Log import androidx.compose.runtime.mutableStateOf import chat.simplex.app.* import chat.simplex.app.views.helpers.withApi -import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.* @@ -14,19 +18,17 @@ import kotlin.concurrent.thread typealias ChatCtrl = Long -@DelicateCoroutinesApi -open class ChatController(val ctrl: ChatCtrl, val alertManager: SimplexApp.AlertManager) { +open class ChatController(val ctrl: ChatCtrl, val alertManager: SimplexApp.AlertManager, val ntfManager: NtfManager, val appContext: Context) { var chatModel = ChatModel(this, alertManager) suspend fun startChat(u: User) { - chatModel.currentUser = mutableStateOf(u) - chatModel.userCreated.value = true Log.d("SIMPLEX (user)", u.toString()) try { apiStartChat() chatModel.userAddress.value = apiGetUserAddress() chatModel.chats.addAll(apiGetChats()) - chatModel.chatsLoaded.value = true + chatModel.currentUser = mutableStateOf(u) + chatModel.userCreated.value = true startReceiver() Log.d("SIMPLEX", "started chat") } catch(e: Error) { @@ -41,6 +43,18 @@ open class ChatController(val ctrl: ChatCtrl, val alertManager: SimplexApp.Alert } } + open fun isAppOnForeground(context: Context): Boolean { + val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + val appProcesses = activityManager.runningAppProcesses ?: return false + val packageName = context.packageName + for (appProcess in appProcesses) { + if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName == packageName) { + return true + } + } + return false + } + suspend fun sendCmd(cmd: CC): CR { return withContext(Dispatchers.IO) { val c = cmd.cmdString @@ -146,9 +160,9 @@ open class ChatController(val ctrl: ChatCtrl, val alertManager: SimplexApp.Alert suspend fun apiDeleteChat(type: ChatType, id: Long): Boolean { val r = sendCmd(CC.ApiDeleteChat(type, id)) - when { - r is CR.ContactDeleted -> return true // TODO groups - r is CR.ChatCmdError -> { + when (r) { + is CR.ContactDeleted -> return true // TODO groups + is CR.ChatCmdError -> { val e = r.chatError if (e is ChatError.ChatErrorChat && e.errorType is ChatErrorType.ContactGroups) { alertManager.showAlertMsg( @@ -260,7 +274,9 @@ open class ChatController(val ctrl: ChatCtrl, val alertManager: SimplexApp.Alert val cInfo = r.chatItem.chatInfo val cItem = r.chatItem.chatItem chatModel.addChatItem(cInfo, cItem) -// NtfManager.shared.notifyMessageReceived(cInfo, cItem) + if (!isAppOnForeground(appContext) || chatModel.chatId.value != cInfo.id) { + ntfManager.notifyMessageReceived(cInfo, cItem) + } } // case let .chatItemUpdated(aChatItem): // let cInfo = aChatItem.chatInfo @@ -432,7 +448,7 @@ sealed class CR { is ChatStarted -> "chatStarted" is ChatRunning -> "chatRunning" is ApiChats -> "apiChats" - is ApiChat -> "apiChats" + is ApiChat -> "apiChat" is Invitation -> "invitation" is SentConfirmation -> "sentConfirmation" is SentInvitation -> "sentInvitation" diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/SplashView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/SplashView.kt index 503a50e211..4fa4b311d3 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/SplashView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/SplashView.kt @@ -1,16 +1,11 @@ package chat.simplex.app.views -import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material.MaterialTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp -import chat.simplex.app.R @Composable fun SplashView() { diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/TerminalView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/TerminalView.kt index 4d83b38b1d..d12a4a62d9 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/TerminalView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/TerminalView.kt @@ -23,10 +23,8 @@ import chat.simplex.app.views.helpers.CloseSheetBar import chat.simplex.app.views.helpers.withApi import com.google.accompanist.insets.ProvideWindowInsets import com.google.accompanist.insets.navigationBarsWithImePadding -import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.launch -@DelicateCoroutinesApi @Composable fun TerminalView(chatModel: ChatModel, nav: NavController) { TerminalLayout(chatModel.terminalItems, nav::popBackStack, nav::navigate) { cmd -> diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/WelcomeView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/WelcomeView.kt index fcfafb82d0..bacd1dad29 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/WelcomeView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/WelcomeView.kt @@ -19,11 +19,9 @@ import chat.simplex.app.model.Profile import chat.simplex.app.views.helpers.withApi import com.google.accompanist.insets.ProvideWindowInsets import com.google.accompanist.insets.navigationBarsWithImePadding -import kotlinx.coroutines.DelicateCoroutinesApi -@DelicateCoroutinesApi @Composable -fun WelcomeView(chatModel: ChatModel, routeHome: () -> Unit) { +fun WelcomeView(chatModel: ChatModel) { ProvideWindowInsets(windowInsetsAnimationsEnabled = true) { Box( modifier = Modifier @@ -60,7 +58,7 @@ fun WelcomeView(chatModel: ChatModel, routeHome: () -> Unit) { color = MaterialTheme.colors.onBackground ) Spacer(Modifier.height(24.dp)) - CreateProfilePanel(chatModel, routeHome) + CreateProfilePanel(chatModel) } } } @@ -71,9 +69,8 @@ fun isValidDisplayName(name: String) : Boolean { return (name.firstOrNull { it.isWhitespace() }) == null } -@DelicateCoroutinesApi @Composable -fun CreateProfilePanel(chatModel: ChatModel, routeHome: () -> Unit) { +fun CreateProfilePanel(chatModel: ChatModel) { var displayName by remember { mutableStateOf("") } var fullName by remember { mutableStateOf("") } @@ -154,10 +151,9 @@ fun CreateProfilePanel(chatModel: ChatModel, routeHome: () -> Unit) { Profile(displayName, fullName) ) chatModel.controller.startChat(user) - routeHome() } }, enabled = displayName.isNotEmpty() - ) { Text("Create")} + ) { Text("Create") } } -} \ No newline at end of file +} diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt index 4f1dc1b823..061fab5e3b 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt @@ -15,19 +15,16 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import chat.simplex.app.Pages import chat.simplex.app.model.* import chat.simplex.app.ui.theme.* import chat.simplex.app.views.helpers.* -import kotlinx.coroutines.DelicateCoroutinesApi -@DelicateCoroutinesApi @Composable fun ChatInfoView(chatModel: ChatModel, nav: NavController) { val chat = chatModel.chats.firstOrNull { it.id == chatModel.chatId.value } if (chat != null) { ChatInfoLayout(chat, - close = { nav.popBackStack() }, + close = nav::popBackStack, deleteContact = { chatModel.alertManager.showAlertMsg( title = "Delete contact?", @@ -39,7 +36,8 @@ fun ChatInfoView(chatModel: ChatModel, nav: NavController) { val r = chatModel.controller.apiDeleteChat(cInfo.chatType, cInfo.apiId) if (r) { chatModel.removeChat(cInfo.id) - nav.navigate(Pages.ChatList.route) + chatModel.chatId.value = null + nav.popBackStack() } } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatView.kt index 5b6e3044f5..7270720ebf 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatView.kt @@ -1,6 +1,8 @@ package chat.simplex.app.views.chat import android.content.res.Configuration +import android.util.Log +import androidx.activity.compose.BackHandler import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* @@ -12,7 +14,6 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.text.ExperimentalTextApi import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview @@ -24,56 +25,54 @@ import chat.simplex.app.ui.theme.SimpleXTheme import chat.simplex.app.views.chat.item.ChatItemView import chat.simplex.app.views.helpers.ChatInfoImage import chat.simplex.app.views.helpers.withApi -import com.google.accompanist.insets.* -import kotlinx.coroutines.* +import com.google.accompanist.insets.ProvideWindowInsets +import com.google.accompanist.insets.navigationBarsWithImePadding +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import kotlinx.datetime.Clock -@ExperimentalTextApi -@ExperimentalAnimatedInsets -@DelicateCoroutinesApi @Composable fun ChatView(chatModel: ChatModel, nav: NavController) { - if (chatModel.chatId.value != null && chatModel.chats.count() > 0) { - val chat: Chat? = chatModel.chats.firstOrNull { chat -> chat.chatInfo.id == chatModel.chatId.value } - if (chat != null) { - // TODO a more advanced version would mark as read only if in view - LaunchedEffect(chat.chatItems) { - delay(1000L) - if (chat.chatItems.count() > 0) { - chatModel.markChatItemsRead(chat.chatInfo) - withApi { - chatModel.controller.apiChatRead( - chat.chatInfo.chatType, - chat.chatInfo.apiId, - CC.ItemRange(chat.chatStats.minUnreadItemId, chat.chatItems.last().id) - ) - } + val chat: Chat? = chatModel.chats.firstOrNull { chat -> chat.chatInfo.id == chatModel.chatId.value } + if (chat == null) { + chatModel.chatId.value = null + } else { + BackHandler { chatModel.chatId.value = null } + // TODO a more advanced version would mark as read only if in view + LaunchedEffect(chat.chatItems) { + Log.d("SIMPLEX", "ChatView ${chatModel.chatId.value}: LaunchedEffect") + delay(1000L) + if (chat.chatItems.count() > 0) { + chatModel.markChatItemsRead(chat.chatInfo) + withApi { + chatModel.controller.apiChatRead( + chat.chatInfo.chatType, + chat.chatInfo.apiId, + CC.ItemRange(chat.chatStats.minUnreadItemId, chat.chatItems.last().id) + ) } } - ChatLayout(chat, chatModel.chatItems, - back = { nav.popBackStack() }, - info = { nav.navigate(Pages.ChatInfo.route) }, - sendMessage = { msg -> - withApi { - // show "in progress" - val cInfo = chat.chatInfo - val newItem = chatModel.controller.apiSendMessage( - type = cInfo.chatType, - id = cInfo.apiId, - mc = MsgContent.MCText(msg) - ) - // hide "in progress" - if (newItem != null) chatModel.addChatItem(cInfo, newItem.chatItem) - } - } - ) } + ChatLayout(chat, chatModel.chatItems, + back = { chatModel.chatId.value = null }, + info = { nav.navigate(Pages.ChatInfo.route) }, + sendMessage = { msg -> + withApi { + // show "in progress" + val cInfo = chat.chatInfo + val newItem = chatModel.controller.apiSendMessage( + type = cInfo.chatType, + id = cInfo.apiId, + mc = MsgContent.MCText(msg) + ) + // hide "in progress" + if (newItem != null) chatModel.addChatItem(cInfo, newItem.chatItem) + } + } + ) } } -@ExperimentalTextApi -@DelicateCoroutinesApi -@ExperimentalAnimatedInsets @Composable fun ChatLayout( chat: Chat, chatItems: List, @@ -101,7 +100,10 @@ fun ChatLayout( @Composable fun ChatInfoToolbar(chat: Chat, back: () -> Unit, info: () -> Unit) { - Box(Modifier.height(60.dp).padding(horizontal = 8.dp), + Box( + Modifier + .height(60.dp) + .padding(horizontal = 8.dp), contentAlignment = Alignment.CenterStart ) { IconButton(onClick = back) { @@ -136,9 +138,6 @@ fun ChatInfoToolbar(chat: Chat, back: () -> Unit, info: () -> Unit) { } } -@ExperimentalTextApi -@DelicateCoroutinesApi -@ExperimentalAnimatedInsets @Composable fun ChatItemsList(chatItems: List) { val listState = rememberLazyListState() @@ -157,8 +156,6 @@ fun ChatItemsList(chatItems: List) { } } -@ExperimentalTextApi -@ExperimentalAnimatedInsets @Preview(showBackground = true) @Preview( uiMode = Configuration.UI_MODE_NIGHT_YES, diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIMetaView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIMetaView.kt index fcbd726a6d..aafcb7d041 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIMetaView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIMetaView.kt @@ -1,6 +1,5 @@ package chat.simplex.app.views.chat.item -import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt index 8a252f714b..ddcbbdc1a5 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt @@ -5,7 +5,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.UriHandler -import androidx.compose.ui.text.ExperimentalTextApi import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import chat.simplex.app.model.CIDirection @@ -13,7 +12,6 @@ import chat.simplex.app.model.ChatItem import chat.simplex.app.ui.theme.SimpleXTheme import kotlinx.datetime.Clock -@ExperimentalTextApi @Composable fun ChatItemView(chatItem: ChatItem, uriHandler: UriHandler? = null) { val sent = chatItem.chatDir.sent @@ -33,7 +31,6 @@ fun ChatItemView(chatItem: ChatItem, uriHandler: UriHandler? = null) { } } -@ExperimentalTextApi @Preview @Composable fun PreviewChatItemView() { diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/TextItemView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/TextItemView.kt index 5be27d0e57..949648138e 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/TextItemView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/TextItemView.kt @@ -1,6 +1,7 @@ package chat.simplex.app.views.chat.item -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.text.selection.SelectionContainer @@ -15,8 +16,8 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import chat.simplex.app.model.* -import chat.simplex.app.ui.theme.LightGray +import chat.simplex.app.model.CIDirection +import chat.simplex.app.model.ChatItem import chat.simplex.app.ui.theme.SimpleXTheme import kotlinx.datetime.Clock @@ -24,7 +25,6 @@ import kotlinx.datetime.Clock val SentColorLight = Color(0x1E45B8FF) val ReceivedColorLight = Color(0x1EB1B0B5) -@ExperimentalTextApi @Composable fun TextItemView(chatItem: ChatItem, uriHandler: UriHandler? = null) { val sent = chatItem.chatDir.sent @@ -55,7 +55,6 @@ fun appendGroupMember(b: AnnotatedString.Builder, chatItem: ChatItem, groupMembe } } -@ExperimentalTextApi @Composable fun MarkdownText ( chatItem: ChatItem, @@ -110,7 +109,6 @@ fun MarkdownText ( } } -@ExperimentalTextApi @Preview @Composable fun PreviewTextItemViewSnd() { @@ -123,7 +121,6 @@ fun PreviewTextItemViewSnd() { } } -@ExperimentalTextApi @Preview @Composable fun PreviewTextItemViewRcv() { @@ -136,7 +133,6 @@ fun PreviewTextItemViewRcv() { } } -@ExperimentalTextApi @Preview @Composable fun PreviewTextItemViewLong() { diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt index d13f2863ad..9efbb1183a 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt @@ -9,7 +9,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.toMutableStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.text.ExperimentalTextApi import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavController @@ -17,41 +16,31 @@ import chat.simplex.app.Pages import chat.simplex.app.model.* import chat.simplex.app.ui.theme.SimpleXTheme import chat.simplex.app.views.helpers.withApi -import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.datetime.Clock -@ExperimentalTextApi @Composable fun ChatListNavLinkView(chat: Chat, chatModel: ChatModel, nav: NavController) { - ChatListNavLink( + ChatListNavLinkLayout( chat = chat, - action = { - when (chat.chatInfo) { - is ChatInfo.Direct -> chatNavLink(chat, chatModel, nav) - is ChatInfo.Group -> chatNavLink(chat, chatModel, nav) - is ChatInfo.ContactRequest -> contactRequestNavLink(chat.chatInfo, chatModel, nav) + click = { + if (chat.chatInfo is ChatInfo.ContactRequest) { + contactRequestAlertDialog(chat.chatInfo, chatModel, nav) + } else { + withApi { openChat(chatModel, chat.chatInfo) } } } ) } -@DelicateCoroutinesApi -fun chatNavLink(chatPreview: Chat, chatModel: ChatModel, navController: NavController) { - withApi { - val chatInfo = chatPreview.chatInfo - val chat = chatModel.controller.apiGetChat(chatInfo.chatType, chatInfo.apiId) - if (chat != null) { - chatModel.chatId.value = chatInfo.id - chatModel.chatItems = chat.chatItems.toMutableStateList() - navController.navigate(Pages.Chat.route) - } else { - // TODO show error? or will apiGetChat show it - } +suspend fun openChat(chatModel: ChatModel, cInfo: ChatInfo) { + val chat = chatModel.controller.apiGetChat(cInfo.chatType, cInfo.apiId) + if (chat != null) { + chatModel.chatItems = chat.chatItems.toMutableStateList() + chatModel.chatId.value = cInfo.id } } -@DelicateCoroutinesApi -fun contactRequestNavLink(contactRequest: ChatInfo.ContactRequest, chatModel: ChatModel, navController: NavController) { +fun contactRequestAlertDialog(contactRequest: ChatInfo.ContactRequest, chatModel: ChatModel, navController: NavController) { chatModel.alertManager.showAlertDialog( title = "Accept connection request?", text = "If you choose to reject sender will NOT be notified", @@ -75,27 +64,12 @@ fun contactRequestNavLink(contactRequest: ChatInfo.ContactRequest, chatModel: Ch ) } -@ExperimentalTextApi @Composable -fun ChatListNavLink(chat: Chat, action: () -> Unit) { - ChatListNavLinkLayout( - content = { - when (chat.chatInfo) { - is ChatInfo.Direct -> ChatPreviewView(chat) - is ChatInfo.Group -> ChatPreviewView(chat) - is ChatInfo.ContactRequest -> ContactRequestView(chat) - } - }, - action = action - ) -} - -@Composable -fun ChatListNavLinkLayout(content: (@Composable () -> Unit), action: () -> Unit) { +fun ChatListNavLinkLayout(chat: Chat, click: () -> Unit) { Surface( modifier = Modifier .fillMaxWidth() - .clickable(onClick = action) + .clickable(onClick = click) .height(88.dp) ) { Row( @@ -104,18 +78,18 @@ fun ChatListNavLinkLayout(content: (@Composable () -> Unit), action: () -> Unit) .padding(vertical = 8.dp) .padding(start = 8.dp) .padding(end = 12.dp), - verticalAlignment = Alignment.Top, -// TODO? -// verticalAlignment = Alignment.CenterVertically, -// horizontalArrangement = Arrangement.SpaceEvenly + verticalAlignment = Alignment.Top ) { - content.invoke() + if (chat.chatInfo is ChatInfo.ContactRequest) { + ContactRequestView(chat) + } else { + ChatPreviewView(chat) + } } } Divider(Modifier.padding(horizontal = 8.dp)) } -@ExperimentalTextApi @Preview @Preview( uiMode = Configuration.UI_MODE_NIGHT_YES, @@ -125,7 +99,7 @@ fun ChatListNavLinkLayout(content: (@Composable () -> Unit), action: () -> Unit) @Composable fun PreviewChatListNavLinkDirect() { SimpleXTheme { - ChatListNavLink( + ChatListNavLinkLayout( chat = Chat( chatInfo = ChatInfo.Direct.sampleData, chatItems = listOf( @@ -138,12 +112,11 @@ fun PreviewChatListNavLinkDirect() { ), chatStats = Chat.ChatStats() ), - action = {} + click = {} ) } } -@ExperimentalTextApi @Preview @Preview( uiMode = Configuration.UI_MODE_NIGHT_YES, @@ -153,7 +126,7 @@ fun PreviewChatListNavLinkDirect() { @Composable fun PreviewChatListNavLinkGroup() { SimpleXTheme { - ChatListNavLink( + ChatListNavLinkLayout( chat = Chat( chatInfo = ChatInfo.Group.sampleData, chatItems = listOf( @@ -166,12 +139,11 @@ fun PreviewChatListNavLinkGroup() { ), chatStats = Chat.ChatStats() ), - action = {} + click = {} ) } } -@ExperimentalTextApi @Preview @Preview( uiMode = Configuration.UI_MODE_NIGHT_YES, @@ -181,13 +153,13 @@ fun PreviewChatListNavLinkGroup() { @Composable fun PreviewChatListNavLinkContactRequest() { SimpleXTheme { - ChatListNavLink( + ChatListNavLinkLayout( chat = Chat( chatInfo = ChatInfo.ContactRequest.sampleData, chatItems = listOf(), chatStats = Chat.ChatStats() ), - action = {} + click = {} ) } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt index 179ed1919e..6f06d3e366 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt @@ -14,7 +14,6 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.ExperimentalTextApi import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.navigation.NavController @@ -22,10 +21,9 @@ import chat.simplex.app.model.ChatModel import chat.simplex.app.views.chat.ChatHelpView import chat.simplex.app.views.newchat.NewChatSheet import chat.simplex.app.views.usersettings.SettingsView -import com.google.accompanist.permissions.ExperimentalPermissionsApi -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch -@ExperimentalMaterialApi class ScaffoldController(val scope: CoroutineScope) { lateinit var state: BottomSheetScaffoldState val expanded = mutableStateOf(false) @@ -49,7 +47,6 @@ class ScaffoldController(val scope: CoroutineScope) { } } -@ExperimentalMaterialApi @Composable fun scaffoldController(): ScaffoldController { val ctrl = ScaffoldController(scope = rememberCoroutineScope()) @@ -64,10 +61,6 @@ fun scaffoldController(): ScaffoldController { return ctrl } -@ExperimentalTextApi -@DelicateCoroutinesApi -@ExperimentalPermissionsApi -@ExperimentalMaterialApi @Composable fun ChatListView(chatModel: ChatModel, nav: NavController) { val scaffoldCtrl = scaffoldController() @@ -86,14 +79,11 @@ fun ChatListView(chatModel: ChatModel, nav: NavController) { .background(MaterialTheme.colors.background) ) { ChatListToolbar(scaffoldCtrl) - when (chatModel.chatsLoaded.value) { - true -> if (chatModel.chats.isNotEmpty()) { - ChatList(chatModel, nav) - } else { - val user = chatModel.currentUser.value - Help(scaffoldCtrl, displayName = user?.profile?.displayName) - } - else -> ChatList(chatModel, nav) + if (chatModel.chats.isNotEmpty()) { + ChatList(chatModel, nav) + } else { + val user = chatModel.currentUser.value + Help(scaffoldCtrl, displayName = user?.profile?.displayName) } } if (scaffoldCtrl.expanded.value) { @@ -108,7 +98,6 @@ fun ChatListView(chatModel: ChatModel, nav: NavController) { } } -@ExperimentalMaterialApi @Composable fun Help(scaffoldCtrl: ScaffoldController, displayName: String?) { Column( @@ -142,7 +131,6 @@ fun Help(scaffoldCtrl: ScaffoldController, displayName: String?) { } } -@ExperimentalMaterialApi @Composable fun ChatListToolbar(scaffoldCtrl: ScaffoldController) { Row( @@ -178,8 +166,6 @@ fun ChatListToolbar(scaffoldCtrl: ScaffoldController) { } } -@ExperimentalTextApi -@DelicateCoroutinesApi @Composable fun ChatList(chatModel: ChatModel, navController: NavController) { Divider(Modifier.padding(horizontal = 8.dp)) @@ -191,15 +177,3 @@ fun ChatList(chatModel: ChatModel, navController: NavController) { } } } -//@Preview -//@Composable -//fun PreviewChatListView() { -// SimpleXTheme { -// ChatListView( -// chats = listOf( -// Chat() -// ), -// -// ) -// } -//} diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt index caad7bdb1d..95fc05f7c2 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt @@ -9,7 +9,6 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.text.ExperimentalTextApi import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview @@ -23,7 +22,6 @@ import chat.simplex.app.views.chat.item.MarkdownText import chat.simplex.app.views.helpers.ChatInfoImage import chat.simplex.app.views.helpers.badgeLayout -@ExperimentalTextApi @Composable fun ChatPreviewView(chat: Chat) { Row { @@ -78,7 +76,6 @@ fun ChatPreviewView(chat: Chat) { } } -@ExperimentalTextApi @Preview(showBackground = true) @Preview( uiMode = Configuration.UI_MODE_NIGHT_YES, diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/ChatInfoImage.kt b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/ChatInfoImage.kt index 27eac8842b..cdc1f86039 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/ChatInfoImage.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/ChatInfoImage.kt @@ -1,7 +1,6 @@ package chat.simplex.app.views.helpers import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.icons.Icons @@ -9,8 +8,6 @@ import androidx.compose.material.icons.filled.AccountCircle import androidx.compose.material.icons.filled.SupervisedUserCircle import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/Util.kt b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/Util.kt index a8f5ec9dd4..8f148fbd3b 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/Util.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/Util.kt @@ -2,6 +2,5 @@ package chat.simplex.app.views.helpers import kotlinx.coroutines.* -@DelicateCoroutinesApi fun withApi(action: suspend CoroutineScope.() -> Unit): Job = GlobalScope.launch { withContext(Dispatchers.Main, action) } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/newchat/ConnectContactView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/newchat/ConnectContactView.kt index 5a82ea51c9..e9715229f0 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/newchat/ConnectContactView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/newchat/ConnectContactView.kt @@ -18,9 +18,7 @@ import chat.simplex.app.model.ChatModel import chat.simplex.app.ui.theme.SimpleXTheme import chat.simplex.app.views.helpers.CloseSheetBar import chat.simplex.app.views.helpers.withApi -import kotlinx.coroutines.DelicateCoroutinesApi -@DelicateCoroutinesApi @Composable fun ConnectContactView(chatModel: ChatModel, nav: NavController) { ConnectContactLayout( @@ -44,7 +42,6 @@ fun ConnectContactView(chatModel: ChatModel, nav: NavController) { ) } -@DelicateCoroutinesApi fun withUriAction( chatModel: ChatModel, uri: Uri, run: suspend (String) -> Unit diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/newchat/NewChatSheet.kt b/apps/android/app/src/main/java/chat/simplex/app/views/newchat/NewChatSheet.kt index 64db15a0cf..4b338f4f3d 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/newchat/NewChatSheet.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/newchat/NewChatSheet.kt @@ -21,13 +21,8 @@ import chat.simplex.app.ui.theme.HighOrLowlight import chat.simplex.app.ui.theme.SimpleXTheme import chat.simplex.app.views.chatlist.ScaffoldController import chat.simplex.app.views.helpers.withApi -import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.rememberPermissionState -import kotlinx.coroutines.DelicateCoroutinesApi -@DelicateCoroutinesApi -@ExperimentalPermissionsApi -@ExperimentalMaterialApi @Composable fun NewChatSheet(chatModel: ChatModel, newChatCtrl: ScaffoldController, nav: NavController) { val cameraPermissionState = rememberPermissionState(permission = Manifest.permission.CAMERA) @@ -47,15 +42,12 @@ fun NewChatSheet(chatModel: ChatModel, newChatCtrl: ScaffoldController, nav: Nav newChatCtrl.collapse() nav.navigate(Pages.Connect.route) cameraPermissionState.launchPermissionRequest() - }, - close = { - newChatCtrl.collapse() } ) } @Composable -fun NewChatSheetLayout(addContact: () -> Unit, scanCode: () -> Unit, close: () -> Unit) { +fun NewChatSheetLayout(addContact: () -> Unit, scanCode: () -> Unit) { Row(Modifier .fillMaxWidth() .padding(horizontal = 8.dp, vertical = 48.dp), @@ -116,8 +108,7 @@ fun PreviewNewChatSheet() { SimpleXTheme { NewChatSheetLayout( addContact = {}, - scanCode = {}, - close = {}, + scanCode = {} ) } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/MarkdownHelpView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/MarkdownHelpView.kt index ec33dca2ad..0e9ec8fb87 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/MarkdownHelpView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/MarkdownHelpView.kt @@ -7,10 +7,7 @@ import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.material.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.* -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavController diff --git a/apps/android/app/src/main/res/drawable-hdpi/ntf_icon.png b/apps/android/app/src/main/res/drawable-hdpi/ntf_icon.png new file mode 100644 index 0000000000..e17716d593 Binary files /dev/null and b/apps/android/app/src/main/res/drawable-hdpi/ntf_icon.png differ diff --git a/apps/android/app/src/main/res/drawable-mdpi/ntf_icon.png b/apps/android/app/src/main/res/drawable-mdpi/ntf_icon.png new file mode 100644 index 0000000000..4f9c5cf450 Binary files /dev/null and b/apps/android/app/src/main/res/drawable-mdpi/ntf_icon.png differ diff --git a/apps/android/app/src/main/res/drawable-xhdpi/ntf_icon.png b/apps/android/app/src/main/res/drawable-xhdpi/ntf_icon.png new file mode 100644 index 0000000000..44f7315eec Binary files /dev/null and b/apps/android/app/src/main/res/drawable-xhdpi/ntf_icon.png differ diff --git a/apps/android/app/src/main/res/drawable-xxhdpi/ntf_icon.png b/apps/android/app/src/main/res/drawable-xxhdpi/ntf_icon.png new file mode 100644 index 0000000000..01942e7864 Binary files /dev/null and b/apps/android/app/src/main/res/drawable-xxhdpi/ntf_icon.png differ diff --git a/apps/android/app/src/main/res/drawable-xxxhdpi/ntf_icon.png b/apps/android/app/src/main/res/drawable-xxxhdpi/ntf_icon.png new file mode 100644 index 0000000000..71e75ec569 Binary files /dev/null and b/apps/android/app/src/main/res/drawable-xxxhdpi/ntf_icon.png differ diff --git a/apps/android/build.gradle b/apps/android/build.gradle index 6cb503be83..af369aaf9a 100644 --- a/apps/android/build.gradle +++ b/apps/android/build.gradle @@ -7,7 +7,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.1.1' + classpath 'com.android.tools.build:gradle:7.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10" classpath "org.jetbrains.kotlin:kotlin-serialization:1.3.2" @@ -16,8 +16,8 @@ buildscript { } }// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '7.1.1' apply false - id 'com.android.library' version '7.1.1' apply false + id 'com.android.application' version '7.1.2' apply false + id 'com.android.library' version '7.1.2' apply false id 'org.jetbrains.kotlin.android' version '1.6.10' apply false id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.10' }