diff --git a/app/src/main/java/chat/revolt/screens/chat/ChatRouterScreen.kt b/app/src/main/java/chat/revolt/screens/chat/ChatRouterScreen.kt index 5d870cff..8678e753 100644 --- a/app/src/main/java/chat/revolt/screens/chat/ChatRouterScreen.kt +++ b/app/src/main/java/chat/revolt/screens/chat/ChatRouterScreen.kt @@ -92,6 +92,7 @@ import chat.revolt.sheets.ServerContextSheet import chat.revolt.sheets.StatusSheet import chat.revolt.sheets.UserInfoSheet import chat.revolt.sheets.WebHookUserSheet +import chat.revolt.sheets.spark.SwipeToReplySparkSheet import com.google.android.gms.tasks.OnCompleteListener import com.google.firebase.messaging.FirebaseMessaging import dagger.hilt.android.lifecycle.HiltViewModel @@ -150,6 +151,7 @@ class ChatRouterViewModel @Inject constructor( var latestChangelogBody by mutableStateOf("") var showNotificationRationale by mutableStateOf(false) var showEarlyAccessSpark by mutableStateOf(false) + var showSwipeToReplySpark by mutableStateOf(false) private val changelogs = Changelogs(context, kvStorage) @@ -166,9 +168,17 @@ class ChatRouterViewModel @Inject constructor( changelogs.markAsSeen() } - val seenEarlyAccess = kvStorage.get("spark/earlyAccess/dismissed") + val seenEarlyAccess = kvStorage.getBoolean("spark/earlyAccess/dismissed") + val seenSwipeToReply = kvStorage.getBoolean("spark/swipeToReply/dismissed") if (seenEarlyAccess == null) { showEarlyAccessSpark = true + // we don't show swipe to reply to new users, + // as they would expect it to be working already + kvStorage.set("spark/swipeToReply/dismissed", true) + } + + if (seenEarlyAccess == true && seenSwipeToReply != true) { + showSwipeToReplySpark = true } val hasNotificationPermission = @@ -228,6 +238,13 @@ class ChatRouterViewModel @Inject constructor( } } + fun dismissSwipeToReplySpark() { + showSwipeToReplySpark = false + viewModelScope.launch { + kvStorage.set("spark/swipeToReply/dismissed", true) + } + } + fun navigateToServer(serverId: String) { viewModelScope.launch { val savedLastChannel = kvStorage.get("lastChannel/$serverId") @@ -751,6 +768,31 @@ fun ChatRouterScreen( } } + if (viewModel.showSwipeToReplySpark) { + val swipeToReplySheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + + ModalBottomSheet( + sheetState = swipeToReplySheetState, + sheetGesturesEnabled = false, + dragHandle = {}, + onDismissRequest = { + // Only dismiss using button in sheet + } + ) { + SwipeToReplySparkSheet( + onDismissSheet = { + scope.launch { + swipeToReplySheetState.hide() + viewModel.dismissSwipeToReplySpark() + } + }, + onOpenOptions = { + topNav.navigate("settings/chat") + } + ) + } + } + Column( modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/java/chat/revolt/screens/settings/DebugSettingsScreen.kt b/app/src/main/java/chat/revolt/screens/settings/DebugSettingsScreen.kt index 82b4735a..525fc048 100644 --- a/app/src/main/java/chat/revolt/screens/settings/DebugSettingsScreen.kt +++ b/app/src/main/java/chat/revolt/screens/settings/DebugSettingsScreen.kt @@ -69,6 +69,7 @@ class DebugSettingsScreenViewModel @Inject constructor( fun forgetAllSparks() { forgetPhysicalKeyboardSpark() forgetEarlyAccessSpark() + forgetSwipeToReplySpark() } fun forgetPhysicalKeyboardSpark() { @@ -83,6 +84,12 @@ class DebugSettingsScreenViewModel @Inject constructor( } } + fun forgetSwipeToReplySpark() { + viewModelScope.launch { + kvStorage.remove("spark/swipeToReply/dismissed") + } + } + fun forgetLatestChangelog() { viewModelScope.launch { kvStorage.remove("latestChangelogRead") @@ -228,6 +235,9 @@ fun DebugSettingsScreen( ElevatedButton(onClick = { viewModel.forgetEarlyAccessSpark() }) { Text("Forget early access spark") } + ElevatedButton(onClick = { viewModel.forgetSwipeToReplySpark() }) { + Text("Forget swipe to reply spark") + } Button(onClick = { viewModel.forgetAllSparks() }) { Text("Forget all sparks") } diff --git a/app/src/main/java/chat/revolt/sheets/spark/SwipeToReplySparkSheet.kt b/app/src/main/java/chat/revolt/sheets/spark/SwipeToReplySparkSheet.kt index 3e9ca780..0fa77d65 100644 --- a/app/src/main/java/chat/revolt/sheets/spark/SwipeToReplySparkSheet.kt +++ b/app/src/main/java/chat/revolt/sheets/spark/SwipeToReplySparkSheet.kt @@ -4,8 +4,9 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme @@ -28,8 +29,10 @@ fun SwipeToReplySparkSheet( ) { Column( verticalArrangement = Arrangement.spacedBy(16.dp), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(horizontal = 16.dp) ) { + Spacer(Modifier.height(32.dp)) Image(SwipeToReplySpark, contentDescription = null) Spacer(Modifier) // Counts towards the vertical arrangement @@ -45,22 +48,21 @@ fun SwipeToReplySparkSheet( textAlign = TextAlign.Center ) - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically, + Column( + verticalArrangement = Arrangement.spacedBy(8.dp) ) { - Button( - onClick = onDismissSheet, - modifier = Modifier.weight(1f) - ) { - Text(stringResource(R.string.spark_swipe_to_reply_cta)) - } TextButton( onClick = onOpenOptions, - modifier = Modifier.weight(1f) + modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.spark_swipe_to_reply_customise)) } + Button( + onClick = onDismissSheet, + modifier = Modifier.fillMaxWidth() + ) { + Text(stringResource(R.string.spark_swipe_to_reply_cta)) + } } } }