feat: show swipe to reply spark to upgrading users

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2025-04-25 22:39:17 +02:00
parent c7791716c5
commit 8156a5b28c
3 changed files with 67 additions and 13 deletions

View File

@ -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()

View File

@ -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")
}

View File

@ -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))
}
}
}
}