mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 01:40:07 +01:00
Add Banners to all reminder usages behind remote config.
This commit is contained in:
committed by
mtang-signal
parent
f296fcd716
commit
e2e6a73e8d
@@ -46,8 +46,8 @@ class CdsPermanentErrorBanner(private val fragmentManager: FragmentManager) : Ba
|
||||
val PERMANENT_TIME_CUTOFF = 30.days.inWholeMilliseconds
|
||||
|
||||
@JvmStatic
|
||||
fun createFlow(fragmentManager: FragmentManager): Flow<CdsPermanentErrorBanner> = createAndEmit {
|
||||
CdsPermanentErrorBanner(fragmentManager)
|
||||
fun createFlow(childFragmentManager: FragmentManager): Flow<CdsPermanentErrorBanner> = createAndEmit {
|
||||
CdsPermanentErrorBanner(childFragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ class CdsTemporaryErrorBanner(private val fragmentManager: FragmentManager) : Ba
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
fun createFlow(fragmentManager: FragmentManager): Flow<CdsTemporaryErrorBanner> = createAndEmit {
|
||||
CdsTemporaryErrorBanner(fragmentManager)
|
||||
fun createFlow(childFragmentManager: FragmentManager): Flow<CdsTemporaryErrorBanner> = createAndEmit {
|
||||
CdsTemporaryErrorBanner(childFragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.thoughtcrime.securesms.banner.banners
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -20,12 +19,15 @@ import org.thoughtcrime.securesms.util.PowerManagerCompat
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
|
||||
@RequiresApi(23)
|
||||
class DozeBanner(private val context: Context) : Banner() {
|
||||
override val enabled: Boolean = !SignalStore.account.fcmEnabled && !TextSecurePreferences.hasPromptedOptimizeDoze(context) && Build.VERSION.SDK_INT >= 23 && !ServiceUtil.getPowerManager(context).isIgnoringBatteryOptimizations(context.packageName)
|
||||
override val enabled: Boolean =
|
||||
Build.VERSION.SDK_INT >= 23 && !SignalStore.account.fcmEnabled && !TextSecurePreferences.hasPromptedOptimizeDoze(context) && !ServiceUtil.getPowerManager(context).isIgnoringBatteryOptimizations(context.packageName)
|
||||
|
||||
@Composable
|
||||
override fun DisplayBanner() {
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
throw IllegalStateException("Showing a Doze banner for an OS prior to Android 6.0")
|
||||
}
|
||||
DefaultBanner(
|
||||
title = stringResource(id = R.string.DozeReminder_optimize_for_missing_play_services),
|
||||
body = stringResource(id = R.string.DozeReminder_this_device_does_not_support_play_services_tap_to_disable_system_battery),
|
||||
@@ -45,11 +47,7 @@ class DozeBanner(private val context: Context) : Banner() {
|
||||
|
||||
@JvmStatic
|
||||
fun createFlow(context: Context): Flow<DozeBanner> = createAndEmit {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
DozeBanner(context)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
DozeBanner(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -40,7 +40,9 @@ class MediaRestoreProgressBanner(private val data: MediaRestoreEvent) : Banner()
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
return observer.flow
|
||||
} else {
|
||||
return emptyFlow()
|
||||
return flow {
|
||||
emit(MediaRestoreProgressBanner(MediaRestoreEvent(0L, 0L)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,22 +22,38 @@ import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
/**
|
||||
* Banner to let the user know their build is about to expire or has expired.
|
||||
*
|
||||
* @param status can be used to filter which conditions are shown.
|
||||
*/
|
||||
class OutdatedBuildBanner(val context: Context, private val daysUntilExpiry: Int) : Banner() {
|
||||
class OutdatedBuildBanner(val context: Context, private val daysUntilExpiry: Int, private val status: ExpiryStatus) : Banner() {
|
||||
|
||||
override val enabled = SignalStore.misc.isClientDeprecated || daysUntilExpiry <= MAX_DAYS_UNTIL_EXPIRE
|
||||
override val enabled = when (status) {
|
||||
ExpiryStatus.OUTDATED_ONLY -> SignalStore.misc.isClientDeprecated
|
||||
ExpiryStatus.EXPIRED_ONLY -> daysUntilExpiry <= MAX_DAYS_UNTIL_EXPIRE
|
||||
ExpiryStatus.OUTDATED_OR_EXPIRED -> SignalStore.misc.isClientDeprecated || daysUntilExpiry <= MAX_DAYS_UNTIL_EXPIRE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun DisplayBanner() {
|
||||
DefaultBanner(
|
||||
title = null,
|
||||
body = if (SignalStore.misc.isClientDeprecated) {
|
||||
val bodyText = when (status) {
|
||||
ExpiryStatus.OUTDATED_ONLY -> if (daysUntilExpiry == 0) {
|
||||
stringResource(id = R.string.OutdatedBuildReminder_your_version_of_signal_will_expire_today)
|
||||
} else {
|
||||
pluralStringResource(id = R.plurals.OutdatedBuildReminder_your_version_of_signal_will_expire_in_n_days, count = daysUntilExpiry, daysUntilExpiry)
|
||||
}
|
||||
|
||||
ExpiryStatus.EXPIRED_ONLY -> stringResource(id = R.string.OutdatedBuildReminder_your_version_of_signal_will_expire_today)
|
||||
ExpiryStatus.OUTDATED_OR_EXPIRED -> if (SignalStore.misc.isClientDeprecated) {
|
||||
stringResource(id = R.string.OutdatedBuildReminder_your_version_of_signal_will_expire_today)
|
||||
} else if (daysUntilExpiry == 0) {
|
||||
stringResource(id = R.string.OutdatedBuildReminder_your_version_of_signal_will_expire_today)
|
||||
} else {
|
||||
pluralStringResource(id = R.plurals.OutdatedBuildReminder_your_version_of_signal_will_expire_in_n_days, count = daysUntilExpiry, daysUntilExpiry)
|
||||
},
|
||||
}
|
||||
}
|
||||
DefaultBanner(
|
||||
title = null,
|
||||
body = bodyText,
|
||||
importance = if (SignalStore.misc.isClientDeprecated) {
|
||||
Importance.ERROR
|
||||
} else {
|
||||
@@ -51,13 +67,25 @@ class OutdatedBuildBanner(val context: Context, private val daysUntilExpiry: Int
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A enumeration for [OutdatedBuildBanner] to limit it to showing either [OUTDATED_ONLY] status, [EXPIRED_ONLY] status, or both.
|
||||
*
|
||||
* [OUTDATED_ONLY] refers to builds that are still valid but need to be updated.
|
||||
* [EXPIRED_ONLY] refers to builds that are no longer allowed to connect to the service.
|
||||
*/
|
||||
enum class ExpiryStatus {
|
||||
OUTDATED_ONLY,
|
||||
EXPIRED_ONLY,
|
||||
OUTDATED_OR_EXPIRED
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MAX_DAYS_UNTIL_EXPIRE = 10
|
||||
|
||||
@JvmStatic
|
||||
fun createFlow(context: Context): Flow<OutdatedBuildBanner> = createAndEmit {
|
||||
fun createFlow(context: Context, status: ExpiryStatus): Flow<OutdatedBuildBanner> = createAndEmit {
|
||||
val daysUntilExpiry = Util.getTimeUntilBuildExpiry(SignalStore.misc.estimatedServerTime).milliseconds.inWholeDays.toInt()
|
||||
OutdatedBuildBanner(context, daysUntilExpiry)
|
||||
OutdatedBuildBanner(context, daysUntilExpiry, status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.banner.Banner
|
||||
import org.thoughtcrime.securesms.banner.ui.compose.Action
|
||||
@@ -33,14 +32,8 @@ class PendingGroupJoinRequestsBanner(override val enabled: Boolean, private val
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
fun createFlow(suggestionsSize: Int, onViewClicked: () -> Unit): Flow<PendingGroupJoinRequestsBanner> = Producer(suggestionsSize, onViewClicked).flow
|
||||
}
|
||||
|
||||
private class Producer(suggestionsSize: Int, onViewClicked: () -> Unit) {
|
||||
val dismissListener: () -> Unit = {
|
||||
class Producer(suggestionsSize: Int, onViewClicked: () -> Unit) {
|
||||
private val dismissListener: () -> Unit = {
|
||||
mutableStateFlow.tryEmit(PendingGroupJoinRequestsBanner(false, suggestionsSize, onViewClicked, null))
|
||||
}
|
||||
private val mutableStateFlow: MutableStateFlow<PendingGroupJoinRequestsBanner> = MutableStateFlow(PendingGroupJoinRequestsBanner(true, suggestionsSize, onViewClicked, dismissListener))
|
||||
|
||||
@@ -46,6 +46,9 @@ class UsernameOutOfSyncBanner(private val context: Context, private val username
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* @param onActionClick input is true if both the username and the link are corrupted, false if only the link is corrupted
|
||||
*/
|
||||
@JvmStatic
|
||||
fun createFlow(context: Context, onActionClick: (Boolean) -> Unit): Flow<UsernameOutOfSyncBanner> = createAndEmit {
|
||||
UsernameOutOfSyncBanner(context, SignalStore.account.usernameSyncState, onActionClick)
|
||||
|
||||
Reference in New Issue
Block a user