Split compose screens into multiple smaller sections

This commit is contained in:
Ensar Sarajčić
2023-10-03 09:10:32 +02:00
parent c644def18e
commit 3f901ff290
5 changed files with 281 additions and 206 deletions

View File

@ -22,6 +22,7 @@ import com.simplemobiletools.flashlight.extensions.config
import com.simplemobiletools.flashlight.helpers.SleepTimer import com.simplemobiletools.flashlight.helpers.SleepTimer
import com.simplemobiletools.flashlight.helpers.stopSleepTimerCountDown import com.simplemobiletools.flashlight.helpers.stopSleepTimerCountDown
import com.simplemobiletools.flashlight.screens.BrightDisplayScreen import com.simplemobiletools.flashlight.screens.BrightDisplayScreen
import com.simplemobiletools.flashlight.views.AnimatedSleepTimer
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -63,10 +64,8 @@ class BrightDisplayActivity : ComponentActivity() {
} }
} }
}, },
timerVisible = timerVisible, sleepTimer = {
timerText = timerText, AnimatedSleepTimer(timerText = timerText, timerVisible = timerVisible, onTimerClosePress = ::stopSleepTimer)
onTimerClosePress = {
stopSleepTimer()
} }
) )
} }

View File

@ -40,7 +40,8 @@ import com.simplemobiletools.flashlight.dialogs.SleepTimerCustomDialog
import com.simplemobiletools.flashlight.extensions.config import com.simplemobiletools.flashlight.extensions.config
import com.simplemobiletools.flashlight.extensions.startAboutActivity import com.simplemobiletools.flashlight.extensions.startAboutActivity
import com.simplemobiletools.flashlight.helpers.* import com.simplemobiletools.flashlight.helpers.*
import com.simplemobiletools.flashlight.screens.MainScreen import com.simplemobiletools.flashlight.screens.*
import com.simplemobiletools.flashlight.views.AnimatedSleepTimer
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import java.util.* import java.util.*
import kotlin.system.exitProcess import kotlin.system.exitProcess
@ -61,25 +62,6 @@ class MainActivity : ComponentActivity() {
setContent { setContent {
AppThemeSurface { AppThemeSurface {
val showMoreApps = onEventValue { !resources.getBoolean(R.bool.hide_google_relations) } val showMoreApps = onEventValue { !resources.getBoolean(R.bool.hide_google_relations) }
val timerVisible by viewModel.timerVisible.collectAsStateWithLifecycle()
val timerText by viewModel.timerText.collectAsStateWithLifecycle()
val flashlightActive by viewModel.flashlightOn.collectAsStateWithLifecycle()
val showBrightDisplayButton by preferences.brightDisplayFlow.collectAsStateWithLifecycle(
config.brightDisplay,
minActiveState = Lifecycle.State.CREATED
)
val showSosButton by preferences.sosFlow.collectAsStateWithLifecycle(config.sos, minActiveState = Lifecycle.State.CREATED)
val sosActive by viewModel.sosActive.collectAsStateWithLifecycle()
val showStroboscopeButton by preferences.stroboscopeFlow.collectAsStateWithLifecycle(
config.stroboscope,
minActiveState = Lifecycle.State.CREATED
)
val stroboscopeActive by viewModel.stroboscopeActive.collectAsStateWithLifecycle()
val brightnessBarVisible by viewModel.brightnessBarVisible.collectAsStateWithLifecycle(false)
val brightnessBarValue by viewModel.brightnessBarValue.collectAsStateWithLifecycle()
val stroboscopeBarVisible by viewModel.stroboscopeBarVisible.collectAsStateWithLifecycle(false)
val stroboscopeBarValue by viewModel.stroboscopeBarValue.collectAsStateWithLifecycle()
val sosPermissionLauncher = rememberLauncherForActivityResult( val sosPermissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission(), contract = ActivityResultContracts.RequestPermission(),
onResult = { onResult = {
@ -102,25 +84,63 @@ class MainActivity : ComponentActivity() {
) )
MainScreen( MainScreen(
timerText = timerText, flashlightButton = {
timerVisible = timerVisible, val flashlightActive by viewModel.flashlightOn.collectAsStateWithLifecycle()
onTimerClosePress = { stopSleepTimer() },
FlashlightButton(
onFlashlightPress = { viewModel.toggleFlashlight() }, onFlashlightPress = { viewModel.toggleFlashlight() },
flashlightActive = flashlightActive, flashlightActive = flashlightActive,
showBrightDisplayButton = showBrightDisplayButton, )
},
brightDisplayButton = {
val showBrightDisplayButton by preferences.brightDisplayFlow.collectAsStateWithLifecycle(
config.brightDisplay,
minActiveState = Lifecycle.State.CREATED
)
if (showBrightDisplayButton) {
BrightDisplayButton(
onBrightDisplayPress = { onBrightDisplayPress = {
startActivity(Intent(applicationContext, BrightDisplayActivity::class.java)) startActivity(Intent(applicationContext, BrightDisplayActivity::class.java))
}
)
}
}, },
showSosButton = showSosButton, sosButton = {
val showSosButton by preferences.sosFlow.collectAsStateWithLifecycle(config.sos, minActiveState = Lifecycle.State.CREATED)
val sosActive by viewModel.sosActive.collectAsStateWithLifecycle()
if (showSosButton) {
SosButton(
sosActive = sosActive, sosActive = sosActive,
onSosButtonPress = { onSosButtonPress = {
toggleStroboscope(true, sosPermissionLauncher) toggleStroboscope(true, sosPermissionLauncher)
}, },
showStroboscopeButton = showStroboscopeButton, )
}
},
stroboscopeButton = {
val showStroboscopeButton by preferences.stroboscopeFlow.collectAsStateWithLifecycle(
config.stroboscope,
minActiveState = Lifecycle.State.CREATED
)
val stroboscopeActive by viewModel.stroboscopeActive.collectAsStateWithLifecycle()
if (showStroboscopeButton) {
StroboscopeButton(
stroboscopeActive = stroboscopeActive, stroboscopeActive = stroboscopeActive,
onStroboscopeButtonPress = { onStroboscopeButtonPress = {
toggleStroboscope(false, stroboscopePermissionLauncher) toggleStroboscope(false, stroboscopePermissionLauncher)
}, },
)
}
},
slidersSection = {
val brightnessBarVisible by viewModel.brightnessBarVisible.collectAsStateWithLifecycle(false)
val brightnessBarValue by viewModel.brightnessBarValue.collectAsStateWithLifecycle()
val stroboscopeBarVisible by viewModel.stroboscopeBarVisible.collectAsStateWithLifecycle(false)
val stroboscopeBarValue by viewModel.stroboscopeBarValue.collectAsStateWithLifecycle()
MainScreenSlidersSection(
showBrightnessBar = brightnessBarVisible, showBrightnessBar = brightnessBarVisible,
brightnessBarValue = brightnessBarValue, brightnessBarValue = brightnessBarValue,
onBrightnessBarValueChange = { onBrightnessBarValueChange = {
@ -131,6 +151,18 @@ class MainActivity : ComponentActivity() {
onStroboscopeBarValueChange = { onStroboscopeBarValueChange = {
viewModel.updateStroboscopeBarValue(it) viewModel.updateStroboscopeBarValue(it)
}, },
)
},
sleepTimer = {
val timerVisible by viewModel.timerVisible.collectAsStateWithLifecycle()
val timerText by viewModel.timerText.collectAsStateWithLifecycle()
AnimatedSleepTimer(
timerText = timerText,
timerVisible = timerVisible,
onTimerClosePress = { stopSleepTimer() },
)
},
showMoreApps = showMoreApps, showMoreApps = showMoreApps,
openSettings = ::launchSettings, openSettings = ::launchSettings,
openAbout = ::launchAbout, openAbout = ::launchAbout,

View File

@ -1,8 +1,5 @@
package com.simplemobiletools.flashlight.screens package com.simplemobiletools.flashlight.screens
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -23,16 +20,14 @@ import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.extensions.getContrastColor import com.simplemobiletools.commons.extensions.getContrastColor
import com.simplemobiletools.flashlight.R import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.views.SleepTimer import com.simplemobiletools.flashlight.views.AnimatedSleepTimer
@Composable @Composable
internal fun BrightDisplayScreen( internal fun BrightDisplayScreen(
backgroundColor: Int, backgroundColor: Int,
contrastColor: Int, contrastColor: Int,
timerText: String,
timerVisible: Boolean,
onChangeColorPress: () -> Unit, onChangeColorPress: () -> Unit,
onTimerClosePress: () -> Unit sleepTimer: @Composable () -> Unit
) { ) {
Box( Box(
modifier = Modifier modifier = Modifier
@ -56,18 +51,12 @@ internal fun BrightDisplayScreen(
) )
} }
AnimatedVisibility( Box(
modifier = Modifier modifier = Modifier
.align(Alignment.BottomEnd) .align(Alignment.BottomEnd)
.navigationBarsPadding(), .navigationBarsPadding()
visible = timerVisible && timerText.isNotEmpty(),
enter = fadeIn(),
exit = fadeOut()
) { ) {
SleepTimer( sleepTimer()
timerText = timerText,
onCloseClick = onTimerClosePress
)
} }
} }
} }
@ -79,10 +68,10 @@ private fun BrightDisplayScreenPreview() {
BrightDisplayScreen( BrightDisplayScreen(
backgroundColor = MaterialTheme.colorScheme.background.toArgb(), backgroundColor = MaterialTheme.colorScheme.background.toArgb(),
contrastColor = MaterialTheme.colorScheme.background.toArgb().getContrastColor(), contrastColor = MaterialTheme.colorScheme.background.toArgb().getContrastColor(),
timerText = "00:00", sleepTimer = {
timerVisible = true, AnimatedSleepTimer(timerText = "00:00", timerVisible = true, onTimerClosePress = {})
},
onChangeColorPress = {}, onChangeColorPress = {},
onTimerClosePress = {}
) )
} }
} }

View File

@ -1,8 +1,5 @@
package com.simplemobiletools.flashlight.screens package com.simplemobiletools.flashlight.screens
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
@ -32,31 +29,18 @@ import com.simplemobiletools.commons.compose.settings.scaffold.topAppBarInsets
import com.simplemobiletools.commons.compose.settings.scaffold.topAppBarPaddings import com.simplemobiletools.commons.compose.settings.scaffold.topAppBarPaddings
import com.simplemobiletools.commons.compose.theme.AppThemeSurface import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.flashlight.R import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.views.SleepTimer import com.simplemobiletools.flashlight.views.AnimatedSleepTimer
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
@Composable @Composable
internal fun MainScreen( internal fun MainScreen(
timerText: String, flashlightButton: @Composable () -> Unit,
timerVisible: Boolean, brightDisplayButton: @Composable () -> Unit,
onTimerClosePress: () -> Unit, sosButton: @Composable () -> Unit,
flashlightActive: Boolean, stroboscopeButton: @Composable () -> Unit,
onFlashlightPress: () -> Unit, slidersSection: @Composable () -> Unit,
showBrightDisplayButton: Boolean, sleepTimer: @Composable () -> Unit,
onBrightDisplayPress: () -> Unit,
showSosButton: Boolean,
sosActive: Boolean,
onSosButtonPress: () -> Unit,
showStroboscopeButton: Boolean,
stroboscopeActive: Boolean,
onStroboscopeButtonPress: () -> Unit,
showBrightnessBar: Boolean,
brightnessBarValue: Float,
onBrightnessBarValueChange: (Float) -> Unit,
showStroboscopeBar: Boolean,
stroboscopeBarValue: Float,
onStroboscopeBarValueChange: (Float) -> Unit,
showMoreApps: Boolean, showMoreApps: Boolean,
openSettings: () -> Unit, openSettings: () -> Unit,
openAbout: () -> Unit, openAbout: () -> Unit,
@ -89,6 +73,26 @@ internal fun MainScreen(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly verticalArrangement = Arrangement.SpaceEvenly
) {
flashlightButton()
brightDisplayButton()
sosButton()
stroboscopeButton()
slidersSection()
}
Box(
modifier = Modifier.align(Alignment.BottomEnd),
) {
sleepTimer()
}
}
}
@Composable
internal fun FlashlightButton(
flashlightActive: Boolean,
onFlashlightPress: () -> Unit,
) { ) {
Icon( Icon(
modifier = Modifier modifier = Modifier
@ -103,8 +107,12 @@ internal fun MainScreen(
contentDescription = stringResource(id = R.string.flashlight_short), contentDescription = stringResource(id = R.string.flashlight_short),
tint = if (flashlightActive) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface tint = if (flashlightActive) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface
) )
}
if (showBrightDisplayButton) { @Composable
internal fun BrightDisplayButton(
onBrightDisplayPress: () -> Unit,
) {
Icon( Icon(
modifier = Modifier modifier = Modifier
.size(dimensionResource(id = R.dimen.smaller_button_size)) .size(dimensionResource(id = R.dimen.smaller_button_size))
@ -120,7 +128,11 @@ internal fun MainScreen(
) )
} }
if (showSosButton) { @Composable
internal fun SosButton(
sosActive: Boolean,
onSosButtonPress: () -> Unit,
) {
Text( Text(
modifier = Modifier modifier = Modifier
.padding(vertical = dimensionResource(id = R.dimen.normal_margin)) .padding(vertical = dimensionResource(id = R.dimen.normal_margin))
@ -136,7 +148,11 @@ internal fun MainScreen(
) )
} }
if (showStroboscopeButton) { @Composable
internal fun StroboscopeButton(
stroboscopeActive: Boolean,
onStroboscopeButtonPress: () -> Unit,
) {
Icon( Icon(
modifier = Modifier modifier = Modifier
.size(dimensionResource(id = R.dimen.smaller_button_size)) .size(dimensionResource(id = R.dimen.smaller_button_size))
@ -152,6 +168,15 @@ internal fun MainScreen(
) )
} }
@Composable
internal fun MainScreenSlidersSection(
showBrightnessBar: Boolean,
brightnessBarValue: Float,
onBrightnessBarValueChange: (Float) -> Unit,
showStroboscopeBar: Boolean,
stroboscopeBarValue: Float,
onStroboscopeBarValueChange: (Float) -> Unit,
) {
val sliderModifier = Modifier val sliderModifier = Modifier
.padding(dimensionResource(id = R.dimen.activity_margin)) .padding(dimensionResource(id = R.dimen.activity_margin))
.padding(vertical = dimensionResource(R.dimen.medium_margin)) .padding(vertical = dimensionResource(R.dimen.medium_margin))
@ -181,20 +206,6 @@ internal fun MainScreen(
} }
} }
AnimatedVisibility(
modifier = Modifier.align(Alignment.BottomEnd),
visible = timerVisible && timerText.isNotEmpty(),
enter = fadeIn(),
exit = fadeOut(),
) {
SleepTimer(
timerText = timerText,
onCloseClick = onTimerClosePress
)
}
}
}
private fun buildActionMenu( private fun buildActionMenu(
showMoreApps: Boolean, showMoreApps: Boolean,
openSettings: () -> Unit, openSettings: () -> Unit,
@ -218,25 +229,46 @@ private fun buildActionMenu(
internal fun MainScreenPreview() { internal fun MainScreenPreview() {
AppThemeSurface { AppThemeSurface {
MainScreen( MainScreen(
timerText = "00:00", flashlightButton = {
timerVisible = true, FlashlightButton(
onTimerClosePress = {},
onFlashlightPress = {}, onFlashlightPress = {},
flashlightActive = true, flashlightActive = true,
showBrightDisplayButton = true, )
onBrightDisplayPress = {}, },
showSosButton = true, brightDisplayButton = {
BrightDisplayButton(
onBrightDisplayPress = {}
)
},
sosButton = {
SosButton(
sosActive = false, sosActive = false,
onSosButtonPress = {}, onSosButtonPress = {},
showStroboscopeButton = true, )
},
stroboscopeButton = {
StroboscopeButton(
stroboscopeActive = false, stroboscopeActive = false,
onStroboscopeButtonPress = {}, onStroboscopeButtonPress = {},
)
},
slidersSection = {
MainScreenSlidersSection(
showBrightnessBar = false, showBrightnessBar = false,
brightnessBarValue = 0f, brightnessBarValue = 0f,
onBrightnessBarValueChange = {}, onBrightnessBarValueChange = {},
showStroboscopeBar = false, showStroboscopeBar = false,
stroboscopeBarValue = 0f, stroboscopeBarValue = 0f,
onStroboscopeBarValueChange = {}, onStroboscopeBarValueChange = {},
)
},
sleepTimer = {
AnimatedSleepTimer(
timerText = "00:00",
timerVisible = true,
onTimerClosePress = {},
)
},
showMoreApps = true, showMoreApps = true,
openSettings = {}, openSettings = {},
openAbout = {}, openAbout = {},

View File

@ -1,5 +1,8 @@
package com.simplemobiletools.flashlight.views package com.simplemobiletools.flashlight.views
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -61,6 +64,26 @@ internal fun SleepTimer(
} }
} }
@Composable
internal fun AnimatedSleepTimer(
modifier: Modifier = Modifier,
timerText: String,
timerVisible: Boolean,
onTimerClosePress: () -> Unit
) {
AnimatedVisibility(
modifier = modifier,
visible = timerVisible && timerText.isNotEmpty(),
enter = fadeIn(),
exit = fadeOut()
) {
SleepTimer(
timerText = timerText,
onCloseClick = onTimerClosePress
)
}
}
@Composable @Composable
@MyDevices @MyDevices
internal fun SleepTimerPreview() { internal fun SleepTimerPreview() {