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