feat(regression/cs2): age gate

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2024-06-03 20:38:18 +02:00
parent 8049c29e38
commit 5e4f542894
3 changed files with 488 additions and 457 deletions

View File

@ -13,6 +13,7 @@ import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateIntAsState import androidx.compose.animation.core.animateIntAsState
@ -469,6 +470,20 @@ fun ChannelScreen(
) )
} }
) { pv -> ) { pv ->
Crossfade(
targetState = viewModel.ageGateUnlocked,
label = "ageGateUnlocked"
) { ageGateUnlocked ->
if (!ageGateUnlocked) {
ChannelScreenAgeGate(
onAccept = {
viewModel.ageGateUnlocked = true
},
onDeny = {
onToggleDrawer()
}
)
} else {
Column( Column(
modifier = Modifier modifier = Modifier
.padding(pv) .padding(pv)
@ -592,7 +607,9 @@ fun ChannelScreen(
Text( Text(
stringResource(R.string.message_failed_to_send), stringResource(R.string.message_failed_to_send),
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.error.copy(alpha = 0.8f), color = MaterialTheme.colorScheme.error.copy(
alpha = 0.8f
),
modifier = Modifier.padding( modifier = Modifier.padding(
top = 4.dp, top = 4.dp,
bottom = 4.dp, bottom = 4.dp,
@ -761,7 +778,8 @@ fun ChannelScreen(
if (viewModel.activePane == ChannelScreenActivePane.EmojiPicker) { if (viewModel.activePane == ChannelScreenActivePane.EmojiPicker) {
viewModel.activePane = ChannelScreenActivePane.None viewModel.activePane = ChannelScreenActivePane.None
} else { } else {
viewModel.activePane = ChannelScreenActivePane.EmojiPicker viewModel.activePane =
ChannelScreenActivePane.EmojiPicker
} }
}, },
onSendMessage = viewModel::sendPendingMessage, onSendMessage = viewModel::sendPendingMessage,
@ -866,11 +884,13 @@ fun ChannelScreen(
InbuiltMediaPicker( InbuiltMediaPicker(
onOpenDocumentsUi = { onOpenDocumentsUi = {
pickFileLauncher.launch(arrayOf("*/*")) pickFileLauncher.launch(arrayOf("*/*"))
viewModel.activePane = ChannelScreenActivePane.None viewModel.activePane =
ChannelScreenActivePane.None
}, },
onOpenCamera = { onOpenCamera = {
// Create a new content URI to store the captured image. // Create a new content URI to store the captured image.
val contentResolver = context.contentResolver val contentResolver =
context.contentResolver
val contentValues = ContentValues().apply { val contentValues = ContentValues().apply {
put( put(
MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.DISPLAY_NAME,
@ -886,13 +906,16 @@ fun ChannelScreen(
) )
} }
capturedPhotoUri.value = contentResolver.insert( capturedPhotoUri.value =
contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues contentValues
) )
try { try {
pickCameraLauncher.launch(capturedPhotoUri.value) pickCameraLauncher.launch(
capturedPhotoUri.value
)
} catch (e: Exception) { } catch (e: Exception) {
Toast.makeText( Toast.makeText(
context, context,
@ -903,10 +926,12 @@ fun ChannelScreen(
).show() ).show()
} }
viewModel.activePane = ChannelScreenActivePane.None viewModel.activePane =
ChannelScreenActivePane.None
}, },
onClose = { onClose = {
viewModel.activePane = ChannelScreenActivePane.None viewModel.activePane =
ChannelScreenActivePane.None
}, },
onMediaSelected = { media -> onMediaSelected = { media ->
try { try {
@ -947,4 +972,6 @@ fun ChannelScreen(
} }
} }
} }
}
}
} }

View File

@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button import androidx.compose.material3.Button
@ -116,7 +117,7 @@ fun ChannelScreenAgeGate(
} }
Column( Column(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize().imePadding(),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically) verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically)
) { ) {
@ -181,7 +182,7 @@ fun ChannelScreenAgeGate(
} }
} }
@Preview @Preview(showBackground = true)
@Composable @Composable
private fun AgeGateScreenPreview() { private fun AgeGateScreenPreview() {
ChannelScreenAgeGate(onAccept = { /*TODO*/ }, onDeny = { /*TODO*/ }) ChannelScreenAgeGate(onAccept = { /*TODO*/ }, onDeny = { /*TODO*/ })

View File

@ -92,6 +92,8 @@ class ChannelScreenViewModel @Inject constructor(
var editingMessage by mutableStateOf<String?>(null) var editingMessage by mutableStateOf<String?>(null)
var ageGateUnlocked by mutableStateOf(false)
init { init {
viewModelScope.launch { viewModelScope.launch {
keyboardHeight = kvStorage.getInt("keyboardHeight") ?: 900 // reasonable default for now keyboardHeight = kvStorage.getInt("keyboardHeight") ?: 900 // reasonable default for now
@ -110,6 +112,7 @@ class ChannelScreenViewModel @Inject constructor(
this.denyMessageField = false this.denyMessageField = false
this.denyMessageFieldReasonResource = R.string.typing_blank this.denyMessageFieldReasonResource = R.string.typing_blank
this.editingMessage = null this.editingMessage = null
this.ageGateUnlocked = channel?.nsfw != true
viewModelScope.launch { viewModelScope.launch {
draftContent = kvStorage.get("draftContent/$id") ?: "" draftContent = kvStorage.get("draftContent/$id") ?: ""