Migrate BrightDisplayActivity to compose

This commit is contained in:
Ensar Sarajčić 2023-09-28 15:09:52 +02:00
parent ee7780f9e7
commit 68f4e32ce2
3 changed files with 231 additions and 55 deletions

View File

@ -1,23 +1,31 @@
package com.simplemobiletools.flashlight.activities
import android.app.Application
import android.content.pm.ActivityInfo
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.WindowManager
import android.widget.RelativeLayout
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.runtime.getValue
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.simplemobiletools.commons.compose.extensions.enableEdgeToEdgeSimple
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.flashlight.databinding.ActivityBrightDisplayBinding
import com.simplemobiletools.commons.extensions.getFormattedDuration
import com.simplemobiletools.flashlight.extensions.config
import com.simplemobiletools.flashlight.helpers.stopSleepTimerCountDown
import com.simplemobiletools.flashlight.models.Events
import com.simplemobiletools.flashlight.screens.BrightDisplayScreen
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import kotlin.system.exitProcess
class BrightDisplayActivity : SimpleActivity() {
private val binding by viewBinding(ActivityBrightDisplayBinding::inflate)
private val viewModel by viewModels<BrightDisplayViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
window.addFlags(
@ -29,29 +37,35 @@ class BrightDisplayActivity : SimpleActivity() {
useDynamicTheme = false
super.onCreate(savedInstanceState)
setContentView(binding.root)
supportActionBar?.hide()
setBackgroundColor(config.brightDisplayColor)
enableEdgeToEdgeSimple()
setContent {
AppThemeSurface {
val backgroundColor by viewModel.backgroundColor.collectAsStateWithLifecycle()
val timerVisible by viewModel.timerVisible.collectAsStateWithLifecycle()
val timerText by viewModel.timerText.collectAsStateWithLifecycle()
binding.brightDisplayChangeColor.setOnClickListener {
ColorPickerDialog(this, config.brightDisplayColor, true, currentColorCallback = {
setBackgroundColor(it)
}) { wasPositivePressed, color ->
if (wasPositivePressed) {
config.brightDisplayColor = color
val contrastColor = color.getContrastColor()
binding.brightDisplayChangeColor.apply {
setTextColor(contrastColor)
background.applyColorFilter(contrastColor)
BrightDisplayScreen(
backgroundColor = backgroundColor,
onChangeColorPress = {
ColorPickerDialog(this, config.brightDisplayColor, true, currentColorCallback = {
viewModel.updateBackgroundColor(it)
}) { wasPositivePressed, color ->
if (wasPositivePressed) {
config.brightDisplayColor = color
viewModel.updateBackgroundColor(color)
} else {
viewModel.updateBackgroundColor(config.brightDisplayColor)
}
}
},
timerVisible = timerVisible,
timerText = timerText,
onTimerCloseClick = {
stopSleepTimer()
}
} else {
setBackgroundColor(config.brightDisplayColor)
}
)
}
}
binding.sleepTimerStop.setOnClickListener { stopSleepTimer() }
}
override fun onResume() {
@ -59,8 +73,6 @@ class BrightDisplayActivity : SimpleActivity() {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
toggleBrightness(true)
requestedOrientation = if (config.forcePortraitMode) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_SENSOR
(binding.sleepTimerHolder.layoutParams as RelativeLayout.LayoutParams).bottomMargin = navigationBarHeight
}
override fun onPause() {
@ -69,28 +81,6 @@ class BrightDisplayActivity : SimpleActivity() {
toggleBrightness(false)
}
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}
private fun setBackgroundColor(color: Int) {
binding.apply {
brightDisplay.background = ColorDrawable(color)
val contrastColor = config.brightDisplayColor.getContrastColor()
brightDisplayChangeColor.apply {
setTextColor(contrastColor)
background.applyColorFilter(contrastColor)
}
}
}
private fun toggleBrightness(increase: Boolean) {
val layout = window.attributes
layout.screenBrightness = (if (increase) 1 else 0).toFloat()
@ -98,17 +88,50 @@ class BrightDisplayActivity : SimpleActivity() {
}
private fun stopSleepTimer() {
binding.sleepTimerHolder.fadeOut()
viewModel.hideTimer()
stopSleepTimerCountDown()
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun sleepTimerChanged(event: Events.SleepTimerChanged) {
binding.sleepTimerValue.text = event.seconds.getFormattedDuration()
binding.sleepTimerHolder.beVisible()
if (event.seconds == 0) {
exitProcess(0)
internal class BrightDisplayViewModel(
application: Application
) : AndroidViewModel(application) {
private val _timerText: MutableStateFlow<String> = MutableStateFlow("00:00")
val timerText = _timerText.asStateFlow()
private val _timerVisible: MutableStateFlow<Boolean> = MutableStateFlow(false)
val timerVisible = _timerVisible.asStateFlow()
private val _backgroundColor: MutableStateFlow<Int> = MutableStateFlow(application.config.backgroundColor)
val backgroundColor = _backgroundColor.asStateFlow()
init {
EventBus.getDefault().register(this)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun sleepTimerChanged(event: Events.SleepTimerChanged) {
_timerText.value = event.seconds.getFormattedDuration()
_timerVisible.value = true
if (event.seconds == 0) {
exitProcess(0)
}
}
fun updateBackgroundColor(color: Int) {
_backgroundColor.value = color
}
fun hideTimer() {
_timerVisible.value = false
}
override fun onCleared() {
super.onCleared()
EventBus.getDefault().unregister(this)
}
}
}

View File

@ -0,0 +1,80 @@
package com.simplemobiletools.flashlight.screens
import androidx.compose.animation.*
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.extensions.getContrastColor
import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.views.SleepTimer
@Composable
internal fun BrightDisplayScreen(
backgroundColor: Int,
timerText: String?,
timerVisible: Boolean,
onChangeColorPress: () -> Unit,
onTimerCloseClick: () -> Unit
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(backgroundColor))
) {
TextButton(
modifier = Modifier
.wrapContentSize()
.align(Alignment.Center)
.border(
width = 1.dp,
color = Color(backgroundColor.getContrastColor()),
shape = MaterialTheme.shapes.extraLarge
),
onClick = onChangeColorPress
) {
Text(
text = stringResource(id = R.string.change_color),
color = Color(backgroundColor.getContrastColor())
)
}
AnimatedVisibility(
modifier = Modifier.align(Alignment.BottomEnd)
.navigationBarsPadding(),
visible = timerVisible,
enter = fadeIn(),
exit = fadeOut()
) {
SleepTimer(
timerText = timerText ?: "",
onCloseClick = onTimerCloseClick
)
}
}
}
@Composable
@MyDevices
private fun BrightDisplayScreenPreview() {
AppThemeSurface {
BrightDisplayScreen(
backgroundColor = MaterialTheme.colorScheme.background.toArgb(),
timerText = "00:00",
timerVisible = true,
onChangeColorPress = {},
onTimerCloseClick = {}
)
}
}

View File

@ -0,0 +1,73 @@
package com.simplemobiletools.flashlight.views
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.flashlight.R
@Composable
internal fun SleepTimer(
modifier: Modifier = Modifier,
timerText: String,
onCloseClick: () -> Unit
) {
Row(
modifier = modifier
.wrapContentSize()
.background(MaterialTheme.colorScheme.background)
.border(
width = 1.dp,
color = Color.Gray,
shape = RectangleShape
)
) {
Text(
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(12.dp, 0.dp),
text = stringResource(id = R.string.sleep_timer)
)
Text(
modifier = Modifier.align(Alignment.CenterVertically),
text = timerText
)
IconButton(
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(8.dp),
onClick = onCloseClick,
) {
Icon(
painter = painterResource(id = R.drawable.ic_cross_vector),
contentDescription = stringResource(id = R.string.close)
)
}
}
}
@Composable
@MyDevices
internal fun SleepTimerPreview() {
AppThemeSurface {
SleepTimer(
timerText = "00:00",
onCloseClick = {}
)
}
}