Add specific registration error cases for SVRB.

This commit is contained in:
Greyson Parrelli
2025-08-05 16:04:10 -04:00
committed by Cody Henthorne
parent 0726c29528
commit 9dcc704a9e
9 changed files with 97 additions and 30 deletions

View File

@@ -27,6 +27,11 @@ interface ContactSupportCallbacks {
override fun submitWithoutDebuglog() = Unit
override fun cancel() = Unit
}
fun interface StringForReason<Reason> {
@StringRes
operator fun invoke(reason: Reason?): Int
}
}
/**
@@ -58,23 +63,23 @@ fun ContactSupportDialog(
* sending an email when ready.
*/
@Composable
fun SendSupportEmailEffect(
contactSupportState: ContactSupportViewModel.ContactSupportState,
@StringRes subjectRes: Int,
@StringRes filterRes: Int,
fun <Reason> SendSupportEmailEffect(
contactSupportState: ContactSupportViewModel.ContactSupportState<Reason>,
subjectRes: ContactSupportCallbacks.StringForReason<Reason>,
filterRes: ContactSupportCallbacks.StringForReason<Reason>,
hide: () -> Unit
) {
val context = LocalContext.current
LaunchedEffect(contactSupportState.sendEmail) {
if (contactSupportState.sendEmail) {
val subject = context.getString(subjectRes)
val subject = context.getString(subjectRes(contactSupportState.reason))
val prefix = if (contactSupportState.debugLogUrl != null) {
"\n${context.getString(R.string.HelpFragment__debug_log)} ${contactSupportState.debugLogUrl}\n\n"
} else {
""
}
val body = SupportEmailUtil.generateSupportEmailBody(context, filterRes, prefix, null)
val body = SupportEmailUtil.generateSupportEmailBody(context, filterRes(contactSupportState.reason), prefix, null)
CommunicationActions.openEmail(context, SupportEmailUtil.getSupportEmailAddress(context), subject, body)
hide()
}

View File

@@ -35,23 +35,20 @@ class ContactSupportDialogFragment : ComposeDialogFragment() {
}
}
private val contactSupportViewModel: ContactSupportViewModel by viewModel {
private val contactSupportViewModel: ContactSupportViewModel<Unit> by viewModel {
ContactSupportViewModel(
showInitially = true
)
}
private val subject: Int by lazy { requireArguments().getInt(SUBJECT) }
private val filter: Int by lazy { requireArguments().getInt(FILTER) }
@Composable
override fun DialogContent() {
val contactSupportState by contactSupportViewModel.state.collectAsStateWithLifecycle()
SendSupportEmailEffect(
contactSupportState = contactSupportState,
subjectRes = subject,
filterRes = filter
subjectRes = { requireArguments().getInt(SUBJECT) },
filterRes = { requireArguments().getInt(FILTER) }
) {
contactSupportViewModel.hideContactSupport()
dismissAllowingStateLoss()

View File

@@ -17,18 +17,21 @@ import org.thoughtcrime.securesms.logsubmit.SubmitDebugLogRepository
/**
* Intended to be used to drive [ContactSupportDialog].
*
* @param Reason A type that can be supplied as the reason for showing the dialog when you invoke [showContactSupport]. Useful for when you may want to show
* the option for different reasons. Will be given back to you, if set, via [state] in [ContactSupportState.reason].
*/
class ContactSupportViewModel(
class ContactSupportViewModel<Reason>(
val showInitially: Boolean = false
) : ViewModel(), ContactSupportCallbacks {
private val submitDebugLogRepository: SubmitDebugLogRepository = SubmitDebugLogRepository()
private val store: MutableStateFlow<ContactSupportState> = MutableStateFlow(ContactSupportState(show = showInitially))
private val store: MutableStateFlow<ContactSupportState<Reason>> = MutableStateFlow(ContactSupportState(show = showInitially))
val state: StateFlow<ContactSupportState> = store.asStateFlow()
val state: StateFlow<ContactSupportState<Reason>> = store.asStateFlow()
fun showContactSupport() {
store.update { it.copy(show = true) }
fun showContactSupport(reason: Reason? = null) {
store.update { it.copy(show = true, reason = reason) }
}
fun hideContactSupport() {
@@ -60,10 +63,11 @@ class ContactSupportViewModel(
hideContactSupport()
}
data class ContactSupportState(
data class ContactSupportState<Reason>(
val show: Boolean = false,
val showAsProgress: Boolean = false,
val sendEmail: Boolean = false,
val debugLogUrl: String? = null
val debugLogUrl: String? = null,
val reason: Reason? = null
)
}

View File

@@ -360,6 +360,7 @@ class InternalBackupPlaygroundViewModel : ViewModel() {
RemoteRestoreResult.Success -> _state.value = _state.value.copy(statusMessage = "Import complete!")
RemoteRestoreResult.Canceled,
RemoteRestoreResult.Failure,
RemoteRestoreResult.PermanentSvrBFailure,
RemoteRestoreResult.NetworkError -> {
_state.value = _state.value.copy(statusMessage = "Import failed! $result")
}