Merge pull request #5941 from vector-im/feature/bma/konfetti_speed
No animation -> no chat effect
This commit is contained in:
commit
e35bb772c1
|
@ -0,0 +1 @@
|
|||
If animations are disable on the System, chat effects and confetti will be disabled too
|
|
@ -31,7 +31,7 @@ class TestBatteryOptimization @Inject constructor(
|
|||
) : TroubleshootTest(R.string.settings_troubleshoot_test_battery_title) {
|
||||
|
||||
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {
|
||||
if (isIgnoringBatteryOptimizations(context)) {
|
||||
if (context.isIgnoringBatteryOptimizations()) {
|
||||
description = stringProvider.getString(R.string.settings_troubleshoot_test_battery_success)
|
||||
status = TestStatus.SUCCESS
|
||||
quickFix = null
|
||||
|
|
|
@ -43,21 +43,20 @@ import im.vector.app.features.notifications.NotificationUtils
|
|||
* This user option appears on Android M but Android O enforces its usage and kills apps not
|
||||
* authorised by the user to run in background.
|
||||
*
|
||||
* @param context the context
|
||||
* @return true if battery optimisations are ignored
|
||||
*/
|
||||
fun isIgnoringBatteryOptimizations(context: Context): Boolean {
|
||||
fun Context.isIgnoringBatteryOptimizations(): Boolean {
|
||||
// no issue before Android M, battery optimisations did not exist
|
||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
|
||||
context.getSystemService<PowerManager>()?.isIgnoringBatteryOptimizations(context.packageName) == true
|
||||
getSystemService<PowerManager>()?.isIgnoringBatteryOptimizations(packageName) == true
|
||||
}
|
||||
|
||||
fun isAirplaneModeOn(context: Context): Boolean {
|
||||
return Settings.Global.getInt(context.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
|
||||
fun Context.isAirplaneModeOn(): Boolean {
|
||||
return Settings.Global.getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
|
||||
}
|
||||
|
||||
fun isAnimationDisabled(context: Context): Boolean {
|
||||
return Settings.Global.getFloat(context.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f) == 0f
|
||||
fun Context.isAnimationEnabled(): Boolean {
|
||||
return Settings.Global.getFloat(contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f) != 0f
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -105,6 +105,7 @@ import im.vector.app.core.utils.colorizeMatchingText
|
|||
import im.vector.app.core.utils.copyToClipboard
|
||||
import im.vector.app.core.utils.createJSonViewerStyleProvider
|
||||
import im.vector.app.core.utils.createUIHandler
|
||||
import im.vector.app.core.utils.isAnimationEnabled
|
||||
import im.vector.app.core.utils.isValidUrl
|
||||
import im.vector.app.core.utils.onPermissionDeniedDialog
|
||||
import im.vector.app.core.utils.onPermissionDeniedSnackbar
|
||||
|
@ -586,6 +587,10 @@ class TimelineFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleChatEffect(chatEffect: ChatEffect) {
|
||||
if (!requireContext().isAnimationEnabled()) {
|
||||
Timber.d("Do not perform chat effect, animations are disabled.")
|
||||
return
|
||||
}
|
||||
when (chatEffect) {
|
||||
ChatEffect.CONFETTI -> {
|
||||
views.viewKonfetti.isVisible = true
|
||||
|
@ -666,11 +671,13 @@ class TimelineFragment @Inject constructor(
|
|||
).apply {
|
||||
directListener = { granted ->
|
||||
if (granted) {
|
||||
timelineViewModel.handle(RoomDetailAction.EnsureNativeWidgetAllowed(
|
||||
widget = it.widget,
|
||||
userJustAccepted = true,
|
||||
grantedEvents = it.grantedEvents
|
||||
))
|
||||
timelineViewModel.handle(
|
||||
RoomDetailAction.EnsureNativeWidgetAllowed(
|
||||
widget = it.widget,
|
||||
userJustAccepted = true,
|
||||
grantedEvents = it.grantedEvents
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -791,25 +798,29 @@ class TimelineFragment @Inject constructor(
|
|||
|
||||
override fun onSendVoiceMessage() {
|
||||
messageComposerViewModel.handle(
|
||||
MessageComposerAction.EndRecordingVoiceMessage(isCancelled = false, rootThreadEventId = getRootThreadEventId()))
|
||||
MessageComposerAction.EndRecordingVoiceMessage(isCancelled = false, rootThreadEventId = getRootThreadEventId())
|
||||
)
|
||||
updateRecordingUiState(RecordingUiState.Idle)
|
||||
}
|
||||
|
||||
override fun onDeleteVoiceMessage() {
|
||||
messageComposerViewModel.handle(
|
||||
MessageComposerAction.EndRecordingVoiceMessage(isCancelled = true, rootThreadEventId = getRootThreadEventId()))
|
||||
MessageComposerAction.EndRecordingVoiceMessage(isCancelled = true, rootThreadEventId = getRootThreadEventId())
|
||||
)
|
||||
updateRecordingUiState(RecordingUiState.Idle)
|
||||
}
|
||||
|
||||
override fun onRecordingLimitReached() {
|
||||
messageComposerViewModel.handle(
|
||||
MessageComposerAction.PauseRecordingVoiceMessage)
|
||||
MessageComposerAction.PauseRecordingVoiceMessage
|
||||
)
|
||||
updateRecordingUiState(RecordingUiState.Draft)
|
||||
}
|
||||
|
||||
override fun onRecordingWaveformClicked() {
|
||||
messageComposerViewModel.handle(
|
||||
MessageComposerAction.PauseRecordingVoiceMessage)
|
||||
MessageComposerAction.PauseRecordingVoiceMessage
|
||||
)
|
||||
updateRecordingUiState(RecordingUiState.Draft)
|
||||
}
|
||||
|
||||
|
@ -827,7 +838,8 @@ class TimelineFragment @Inject constructor(
|
|||
|
||||
private fun updateRecordingUiState(state: RecordingUiState) {
|
||||
messageComposerViewModel.handle(
|
||||
MessageComposerAction.OnVoiceRecordingUiStateChanged(state))
|
||||
MessageComposerAction.OnVoiceRecordingUiStateChanged(state)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1527,9 +1539,11 @@ class TimelineFragment @Inject constructor(
|
|||
attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@TimelineFragment)
|
||||
attachmentTypeSelector.setAttachmentVisibility(
|
||||
AttachmentTypeSelectorView.Type.LOCATION,
|
||||
vectorPreferences.isLocationSharingEnabled())
|
||||
vectorPreferences.isLocationSharingEnabled()
|
||||
)
|
||||
attachmentTypeSelector.setAttachmentVisibility(
|
||||
AttachmentTypeSelectorView.Type.POLL, !isThreadTimeLine())
|
||||
AttachmentTypeSelectorView.Type.POLL, !isThreadTimeLine()
|
||||
)
|
||||
}
|
||||
attachmentTypeSelector.show(views.composerLayout.views.attachmentButton)
|
||||
}
|
||||
|
@ -2292,12 +2306,18 @@ class TimelineFragment @Inject constructor(
|
|||
handleCancelSend(action)
|
||||
}
|
||||
is EventSharedAction.ReportContentSpam -> {
|
||||
timelineViewModel.handle(RoomDetailAction.ReportContent(
|
||||
action.eventId, action.senderId, "This message is spam", spam = true))
|
||||
timelineViewModel.handle(
|
||||
RoomDetailAction.ReportContent(
|
||||
action.eventId, action.senderId, "This message is spam", spam = true
|
||||
)
|
||||
)
|
||||
}
|
||||
is EventSharedAction.ReportContentInappropriate -> {
|
||||
timelineViewModel.handle(RoomDetailAction.ReportContent(
|
||||
action.eventId, action.senderId, "This message is inappropriate", inappropriate = true))
|
||||
timelineViewModel.handle(
|
||||
RoomDetailAction.ReportContent(
|
||||
action.eventId, action.senderId, "This message is inappropriate", inappropriate = true
|
||||
)
|
||||
)
|
||||
}
|
||||
is EventSharedAction.ReportContentCustom -> {
|
||||
promptReasonToReportContent(action)
|
||||
|
@ -2443,7 +2463,8 @@ class TimelineFragment @Inject constructor(
|
|||
displayName = timelineViewModel.getRoomSummary()?.displayName,
|
||||
avatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl,
|
||||
roomEncryptionTrustLevel = timelineViewModel.getRoomSummary()?.roomEncryptionTrustLevel,
|
||||
rootThreadEventId = rootThreadEventId)
|
||||
rootThreadEventId = rootThreadEventId
|
||||
)
|
||||
navigator.openThread(it, roomThreadDetailArgs)
|
||||
}
|
||||
}
|
||||
|
@ -2479,7 +2500,8 @@ class TimelineFragment @Inject constructor(
|
|||
roomId = timelineArgs.roomId,
|
||||
displayName = timelineViewModel.getRoomSummary()?.displayName,
|
||||
roomEncryptionTrustLevel = timelineViewModel.getRoomSummary()?.roomEncryptionTrustLevel,
|
||||
avatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl)
|
||||
avatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl
|
||||
)
|
||||
navigator.openThreadList(it, roomThreadDetailArgs)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import androidx.core.view.isVisible
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.animations.play
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.utils.isAnimationEnabled
|
||||
import im.vector.app.databinding.FragmentFtueAccountCreatedBinding
|
||||
import im.vector.app.features.onboarding.OnboardingAction
|
||||
import im.vector.app.features.onboarding.OnboardingViewEvents
|
||||
|
@ -57,7 +58,7 @@ class FtueAuthAccountCreatedFragment @Inject constructor(
|
|||
views.personalizeButtonGroup.isVisible = canPersonalize
|
||||
views.takeMeHomeButtonGroup.isVisible = !canPersonalize
|
||||
|
||||
if (!hasPlayedConfetti && !canPersonalize) {
|
||||
if (!hasPlayedConfetti && !canPersonalize && requireContext().isAnimationEnabled()) {
|
||||
hasPlayedConfetti = true
|
||||
views.viewKonfetti.isVisible = true
|
||||
views.viewKonfetti.play()
|
||||
|
|
|
@ -22,6 +22,7 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import im.vector.app.core.animations.play
|
||||
import im.vector.app.core.utils.isAnimationEnabled
|
||||
import im.vector.app.databinding.FragmentFtuePersonalizationCompleteBinding
|
||||
import im.vector.app.features.onboarding.OnboardingAction
|
||||
import im.vector.app.features.onboarding.OnboardingViewEvents
|
||||
|
@ -43,7 +44,7 @@ class FtueAuthPersonalizationCompleteFragment @Inject constructor() : AbstractFt
|
|||
private fun setupViews() {
|
||||
views.personalizationCompleteCta.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome)) }
|
||||
|
||||
if (!hasPlayedConfetti) {
|
||||
if (!hasPlayedConfetti && requireContext().isAnimationEnabled()) {
|
||||
hasPlayedConfetti = true
|
||||
views.viewKonfetti.isVisible = true
|
||||
views.viewKonfetti.play()
|
||||
|
|
|
@ -25,7 +25,7 @@ import com.tapadoo.alerter.Alerter
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.time.Clock
|
||||
import im.vector.app.core.utils.isAnimationDisabled
|
||||
import im.vector.app.core.utils.isAnimationEnabled
|
||||
import im.vector.app.features.analytics.ui.consent.AnalyticsOptInActivity
|
||||
import im.vector.app.features.pin.PinActivity
|
||||
import im.vector.app.features.signout.hard.SignedOutActivity
|
||||
|
@ -218,7 +218,7 @@ class PopupAlertManager @Inject constructor(
|
|||
if (!alert.isLight) {
|
||||
clearLightStatusBar()
|
||||
}
|
||||
val noAnimation = !animate || isAnimationDisabled(activity)
|
||||
val noAnimation = !(animate && activity.isAnimationEnabled())
|
||||
|
||||
alert.weakCurrentActivity = WeakReference(activity)
|
||||
val alerter = Alerter.create(activity, alert.layoutRes)
|
||||
|
|
|
@ -204,7 +204,7 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
|
|||
// Important, Battery optim white listing is needed in this mode;
|
||||
// Even if using foreground service with foreground notif, it stops to work
|
||||
// in doze mode for certain devices :/
|
||||
if (!isIgnoringBatteryOptimizations(requireContext())) {
|
||||
if (!requireContext().isIgnoringBatteryOptimizations()) {
|
||||
requestDisablingBatteryOptimization(requireActivity(), batteryStartForActivityResult)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute
|
|||
views.syncStateProgressBar.isVisible = newState is SyncState.Running && newState.afterPause
|
||||
|
||||
if (newState == SyncState.NoNetwork) {
|
||||
val isAirplaneModeOn = isAirplaneModeOn(context)
|
||||
val isAirplaneModeOn = context.isAirplaneModeOn()
|
||||
views.syncStateNoNetwork.isVisible = isAirplaneModeOn.not()
|
||||
views.syncStateNoNetworkAirplane.isVisible = isAirplaneModeOn
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue