mirror of
https://codeberg.org/timelimit/timelimit-android.git
synced 2025-10-03 17:59:51 +02:00
Refactor OverviewScreen
This commit is contained in:
parent
6b9aebbeaf
commit
2971e3f55d
8 changed files with 315 additions and 242 deletions
|
@ -32,7 +32,7 @@ fun ScreenMultiplexer(
|
|||
) {
|
||||
when (screen) {
|
||||
null -> {/* nothing to do */ }
|
||||
is Screen.OverviewScreen -> OverviewScreen(screen.content, executeCommand, modifier = modifier)
|
||||
is Screen.OverviewScreen -> OverviewScreen(screen.content, modifier = modifier)
|
||||
is Screen.FragmentScreen -> FragmentScreen(screen, fragmentManager, fragmentIds, modifier = modifier)
|
||||
}
|
||||
}
|
|
@ -16,11 +16,9 @@
|
|||
package io.timelimit.android.ui.model
|
||||
|
||||
import android.app.Application
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import io.timelimit.android.BuildConfig
|
||||
import io.timelimit.android.data.model.UserType
|
||||
import io.timelimit.android.logic.DefaultAppLogic
|
||||
import io.timelimit.android.ui.main.ActivityViewModel
|
||||
|
@ -34,10 +32,6 @@ import kotlinx.coroutines.channels.ReceiveChannel
|
|||
import kotlinx.coroutines.flow.*
|
||||
|
||||
class MainModel(application: Application): AndroidViewModel(application) {
|
||||
companion object {
|
||||
private const val LOG_TAG = "MainModel"
|
||||
}
|
||||
|
||||
val activityModel = ActivityViewModel(application)
|
||||
|
||||
private val logic = DefaultAppLogic.with(application)
|
||||
|
@ -109,13 +103,7 @@ class MainModel(application: Application): AndroidViewModel(application) {
|
|||
}
|
||||
|
||||
fun execute(command: UpdateStateCommand) {
|
||||
state.update { oldState ->
|
||||
command.transform(oldState) ?: oldState.also {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(LOG_TAG, "execute($command) did not transform state")
|
||||
}
|
||||
}
|
||||
}
|
||||
command.applyTo(state)
|
||||
}
|
||||
|
||||
fun reportAuthenticationScreenClosed() {
|
||||
|
|
|
@ -15,11 +15,29 @@
|
|||
*/
|
||||
package io.timelimit.android.ui.model
|
||||
|
||||
import android.util.Log
|
||||
import io.timelimit.android.BuildConfig
|
||||
import io.timelimit.android.ui.model.main.OverviewHandling
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
||||
sealed class UpdateStateCommand {
|
||||
companion object {
|
||||
private const val LOG_TAG = "UpdateStateCommand"
|
||||
}
|
||||
|
||||
abstract fun transform(state: State): State?
|
||||
|
||||
fun applyTo(state: MutableStateFlow<State>) {
|
||||
state.update { oldState ->
|
||||
transform(oldState) ?: oldState.also {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(LOG_TAG, "$this.transform() did not transform state")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Reset: UpdateStateCommand() {
|
||||
override fun transform(state: State) = State.LaunchState
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ import kotlinx.coroutines.channels.SendChannel
|
|||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import java.util.*
|
||||
|
||||
object OverviewHandling {
|
||||
fun processState(
|
||||
|
@ -104,6 +103,11 @@ object OverviewHandling {
|
|||
}
|
||||
}
|
||||
},
|
||||
addUser = {
|
||||
launch {
|
||||
UpdateStateCommand.Overview.AddUser.applyTo(stateLive)
|
||||
}
|
||||
},
|
||||
skipTaskReview = { task ->
|
||||
launch {
|
||||
lock.tryWithLock {
|
||||
|
@ -176,16 +180,30 @@ object OverviewHandling {
|
|||
}
|
||||
}
|
||||
|
||||
stateLive.update { state ->
|
||||
if (state is State.Overview) State.ManageChild.Main(state, user.id, fromRedirect = false)
|
||||
else state
|
||||
UpdateStateCommand.Overview.ManageChild(user.id).applyTo(stateLive)
|
||||
}
|
||||
UserType.Parent -> UpdateStateCommand.Overview.ManageParent(user.id).applyTo(stateLive)
|
||||
}
|
||||
}
|
||||
UserType.Parent -> stateLive.update { state ->
|
||||
if (state is State.Overview) State.ManageParent.Main(state, user.id)
|
||||
else state
|
||||
},
|
||||
openDevice = { device ->
|
||||
launch {
|
||||
UpdateStateCommand.Overview.ManageDevice(device.device.id).applyTo(stateLive)
|
||||
}
|
||||
},
|
||||
setupDevice = {
|
||||
launch {
|
||||
UpdateStateCommand.Overview.SetupDevice.applyTo(stateLive)
|
||||
}
|
||||
},
|
||||
showMoreDevices = {
|
||||
launch {
|
||||
UpdateStateCommand.Overview.ShowMoreDevices(it).applyTo(stateLive)
|
||||
}
|
||||
},
|
||||
showMoreUsers = {
|
||||
launch {
|
||||
UpdateStateCommand.Overview.ShowAllUsers.applyTo(stateLive)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -367,10 +385,15 @@ object OverviewHandling {
|
|||
data class Actions(
|
||||
val hideIntro: () -> Unit,
|
||||
val addDevice: () -> Unit,
|
||||
val addUser: () -> Unit,
|
||||
val skipTaskReview: (TaskToReview) -> Unit,
|
||||
val reviewReject: (TaskToReview) -> Unit,
|
||||
val reviewAccept: (TaskToReview) -> Unit,
|
||||
val openUser: (UserItem) -> Unit
|
||||
val openUser: (UserItem) -> Unit,
|
||||
val openDevice: (DeviceItem) -> Unit,
|
||||
val setupDevice: () -> Unit,
|
||||
val showMoreDevices: (OverviewState.DeviceList) -> Unit,
|
||||
val showMoreUsers: () -> Unit
|
||||
)
|
||||
data class IntroFlags(
|
||||
val showSetupOption: Boolean,
|
||||
|
|
|
@ -19,6 +19,8 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyItemScope
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
|
@ -28,24 +30,50 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.unit.dp
|
||||
import io.timelimit.android.BuildConfig
|
||||
import io.timelimit.android.R
|
||||
import io.timelimit.android.ui.model.UpdateStateCommand
|
||||
import io.timelimit.android.ui.model.main.OverviewHandling
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
fun LazyListScope.deviceItems(screen: OverviewHandling.OverviewScreen) {
|
||||
item (key = Pair("devices", "header")) {
|
||||
ListCommon.SectionHeader(stringResource(R.string.overview_header_devices), Modifier.animateItemPlacement())
|
||||
}
|
||||
|
||||
items(screen.devices.list, key = { Pair("device", it.device.id) }) {
|
||||
DeviceItem(it, screen.actions.openDevice)
|
||||
}
|
||||
|
||||
if (screen.devices.canAdd) {
|
||||
item (key = Pair("devices", "add")) {
|
||||
ListCommon.ActionListItem(
|
||||
icon = Icons.Default.Add,
|
||||
label = stringResource(R.string.add_device),
|
||||
action = screen.actions.addDevice,
|
||||
modifier = Modifier.animateItemPlacement()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (screen.devices.canShowMore != null) {
|
||||
item (key = Pair("devices", "more")) {
|
||||
ListCommon.ShowMoreItem(
|
||||
modifier = Modifier.animateItemPlacement(),
|
||||
action = { screen.actions.showMoreDevices(screen.devices.canShowMore) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun LazyItemScope.DeviceItem(
|
||||
item: OverviewHandling.DeviceItem,
|
||||
executeCommand: (UpdateStateCommand) -> Unit
|
||||
openAction: (OverviewHandling.DeviceItem) -> Unit
|
||||
) {
|
||||
ListCardCommon.Card(
|
||||
Modifier
|
||||
.animateItemPlacement()
|
||||
.padding(horizontal = 8.dp)
|
||||
.clickable(
|
||||
onClick = {
|
||||
executeCommand(UpdateStateCommand.Overview.ManageDevice(item.device.id))
|
||||
}
|
||||
)
|
||||
.clickable(onClick = { openAction(item) })
|
||||
) {
|
||||
ListCardCommon.TextWithIcon(
|
||||
icon = Icons.Default.Smartphone,
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 2019 - 2023 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package io.timelimit.android.ui.overview.overview
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.timelimit.android.R
|
||||
import io.timelimit.android.ui.model.main.OverviewHandling
|
||||
import io.timelimit.android.ui.util.DateUtil
|
||||
import io.timelimit.android.util.TimeTextUtil
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
|
||||
fun LazyListScope.introItems(
|
||||
screen: OverviewHandling.OverviewScreen,
|
||||
) {
|
||||
if (screen.intro.showSetupOption) {
|
||||
item (key = Pair("intro", "finish setup")) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier
|
||||
.animateItemPlacement()
|
||||
.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.overview_finish_setup_title),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(stringResource(R.string.overview_finish_setup_text))
|
||||
|
||||
ListCardCommon.ActionButton(
|
||||
label = stringResource(R.string.generic_go),
|
||||
action = screen.actions.setupDevice
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screen.intro.showOutdatedServer) {
|
||||
item (key = Pair("intro", "outdated server")) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier
|
||||
.animateItemPlacement()
|
||||
.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.overview_server_outdated_title),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(stringResource(R.string.overview_server_outdated_text))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screen.intro.showServerMessage != null) {
|
||||
item (key = Pair("intro", "server message")) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier
|
||||
.animateItemPlacement()
|
||||
.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.overview_server_message),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(screen.intro.showServerMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screen.intro.showIntro) {
|
||||
item (key = Pair("intro", "intro")) {
|
||||
val state = remember {
|
||||
DismissState(
|
||||
initialValue = DismissValue.Default,
|
||||
confirmStateChange = {
|
||||
screen.actions.hideIntro()
|
||||
|
||||
true
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
SwipeToDismiss(
|
||||
state = state,
|
||||
background = {},
|
||||
modifier = Modifier.animateItemPlacement()
|
||||
) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.overview_intro_title),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(stringResource(R.string.overview_intro_text))
|
||||
|
||||
Text(
|
||||
stringResource(R.string.generic_swipe_to_dismiss),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screen.taskToReview != null) {
|
||||
item (key = Pair("intro", "task review")) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier
|
||||
.animateItemPlacement()
|
||||
.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.task_review_title),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(
|
||||
stringResource(R.string.task_review_text, screen.taskToReview.task.childName, screen.taskToReview.task.childTask.taskTitle)
|
||||
)
|
||||
|
||||
Text(
|
||||
stringResource(
|
||||
R.string.task_review_category,
|
||||
TimeTextUtil.time(screen.taskToReview.task.childTask.extraTimeDuration, LocalContext.current),
|
||||
screen.taskToReview.task.categoryTitle
|
||||
),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
|
||||
screen.taskToReview.task.childTask.lastGrantTimestamp.let { lastGrantTimestamp ->
|
||||
if (lastGrantTimestamp != 0L) {
|
||||
Text(
|
||||
stringResource(
|
||||
R.string.task_review_last_grant,
|
||||
DateUtil.formatAbsoluteDate(LocalContext.current, lastGrantTimestamp)
|
||||
),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
TextButton(onClick = {
|
||||
screen.actions.skipTaskReview(screen.taskToReview)
|
||||
}) {
|
||||
Text(stringResource(R.string.generic_skip))
|
||||
}
|
||||
|
||||
Spacer(Modifier.weight(1.0f))
|
||||
|
||||
OutlinedButton(onClick = { screen.actions.reviewReject(screen.taskToReview) }) {
|
||||
Text(stringResource(R.string.generic_no))
|
||||
}
|
||||
|
||||
Spacer(Modifier.width(8.dp))
|
||||
|
||||
OutlinedButton(onClick = { screen.actions.reviewAccept(screen.taskToReview) }) {
|
||||
Text(stringResource(R.string.generic_yes))
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
stringResource(R.string.purchase_required_info_local_mode_free),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,30 +15,16 @@
|
|||
*/
|
||||
package io.timelimit.android.ui.overview.overview
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.timelimit.android.R
|
||||
import io.timelimit.android.ui.model.UpdateStateCommand
|
||||
import io.timelimit.android.ui.model.main.OverviewHandling
|
||||
import io.timelimit.android.ui.util.DateUtil
|
||||
import io.timelimit.android.util.TimeTextUtil
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun OverviewScreen(
|
||||
screen: OverviewHandling.OverviewScreen,
|
||||
executeCommand: (UpdateStateCommand) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
LazyColumn (
|
||||
|
@ -46,198 +32,8 @@ fun OverviewScreen(
|
|||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = modifier
|
||||
) {
|
||||
if (screen.intro.showSetupOption) {
|
||||
item (key = Pair("intro", "finish setup")) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier
|
||||
.animateItemPlacement()
|
||||
.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.overview_finish_setup_title),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(stringResource(R.string.overview_finish_setup_text))
|
||||
|
||||
ListCardCommon.ActionButton(
|
||||
label = stringResource(R.string.generic_go),
|
||||
action = {
|
||||
executeCommand(UpdateStateCommand.Overview.SetupDevice)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screen.intro.showOutdatedServer) {
|
||||
item (key = Pair("intro", "outdated server")) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier
|
||||
.animateItemPlacement()
|
||||
.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.overview_server_outdated_title),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(stringResource(R.string.overview_server_outdated_text))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screen.intro.showServerMessage != null) {
|
||||
item (key = Pair("intro", "servermessage")) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier
|
||||
.animateItemPlacement()
|
||||
.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.overview_server_message),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(screen.intro.showServerMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screen.intro.showIntro) {
|
||||
item (key = Pair("intro", "intro")) {
|
||||
val state = remember {
|
||||
DismissState(
|
||||
initialValue = DismissValue.Default,
|
||||
confirmStateChange = {
|
||||
screen.actions.hideIntro()
|
||||
|
||||
true
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
SwipeToDismiss(
|
||||
state = state,
|
||||
background = {},
|
||||
modifier = Modifier.animateItemPlacement()
|
||||
) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.overview_intro_title),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(stringResource(R.string.overview_intro_text))
|
||||
|
||||
Text(
|
||||
stringResource(R.string.generic_swipe_to_dismiss),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screen.taskToReview != null) {
|
||||
item (key = Pair("task", "review")) {
|
||||
ListCardCommon.Card(
|
||||
modifier = Modifier
|
||||
.animateItemPlacement()
|
||||
.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.task_review_title),
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(
|
||||
stringResource(R.string.task_review_text, screen.taskToReview.task.childName, screen.taskToReview.task.childTask.taskTitle)
|
||||
)
|
||||
|
||||
Text(
|
||||
stringResource(
|
||||
R.string.task_review_category,
|
||||
TimeTextUtil.time(screen.taskToReview.task.childTask.extraTimeDuration, LocalContext.current),
|
||||
screen.taskToReview.task.categoryTitle
|
||||
),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
|
||||
screen.taskToReview.task.childTask.lastGrantTimestamp.let { lastGrantTimestamp ->
|
||||
if (lastGrantTimestamp != 0L) {
|
||||
Text(
|
||||
stringResource(
|
||||
R.string.task_review_last_grant,
|
||||
DateUtil.formatAbsoluteDate(LocalContext.current, lastGrantTimestamp)
|
||||
),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
TextButton(onClick = {
|
||||
screen.actions.skipTaskReview(screen.taskToReview)
|
||||
}) {
|
||||
Text(stringResource(R.string.generic_skip))
|
||||
}
|
||||
|
||||
Spacer(Modifier.weight(1.0f))
|
||||
|
||||
OutlinedButton(onClick = { screen.actions.reviewReject(screen.taskToReview) }) {
|
||||
Text(stringResource(R.string.generic_no))
|
||||
}
|
||||
|
||||
Spacer(Modifier.width(8.dp))
|
||||
|
||||
OutlinedButton(onClick = { screen.actions.reviewAccept(screen.taskToReview) }) {
|
||||
Text(stringResource(R.string.generic_yes))
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
stringResource(R.string.purchase_required_info_local_mode_free),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item (key = Pair("devices", "header")) { ListCommon.SectionHeader(stringResource(R.string.overview_header_devices), Modifier.animateItemPlacement()) }
|
||||
items(screen.devices.list, key = { Pair("device", it.device.id) }) {
|
||||
DeviceItem(it, executeCommand)
|
||||
}
|
||||
if (screen.devices.canAdd) {
|
||||
item (key = Pair("devices", "add")) {
|
||||
ListCommon.ActionListItem(
|
||||
icon = Icons.Default.Add,
|
||||
label = stringResource(R.string.add_device),
|
||||
action = screen.actions.addDevice,
|
||||
modifier = Modifier.animateItemPlacement()
|
||||
)
|
||||
}
|
||||
}
|
||||
if (screen.devices.canShowMore != null) {
|
||||
item (key = Pair("devices", "show more")) { ListCommon.ShowMoreItem(modifier = Modifier.animateItemPlacement()) {
|
||||
executeCommand(UpdateStateCommand.Overview.ShowMoreDevices(screen.devices.canShowMore))
|
||||
}}
|
||||
}
|
||||
|
||||
item (key = Pair("header", "users")) { ListCommon.SectionHeader(stringResource(R.string.overview_header_users), Modifier.animateItemPlacement()) }
|
||||
items(screen.users.list, key = { Pair("user", it.id) }) { UserItem(it, screen.actions) }
|
||||
if (screen.users.canAdd) item (key = Pair("header", "user.create")) {
|
||||
ListCommon.ActionListItem(
|
||||
icon = Icons.Default.Add,
|
||||
label = stringResource(R.string.add_user_title),
|
||||
action = { executeCommand(UpdateStateCommand.Overview.AddUser) },
|
||||
modifier = Modifier.animateItemPlacement()
|
||||
)
|
||||
}
|
||||
if (screen.users.canShowMore) item (key = Pair("header", "user.more")) {
|
||||
ListCommon.ShowMoreItem (modifier = Modifier.animateItemPlacement()) { executeCommand(UpdateStateCommand.Overview.ShowAllUsers) }
|
||||
}
|
||||
introItems(screen)
|
||||
deviceItems(screen)
|
||||
userItems(screen)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,11 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyItemScope
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AccountCircle
|
||||
import androidx.compose.material.icons.filled.AlarmOff
|
||||
import androidx.compose.material.icons.filled.Security
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
@ -33,6 +32,31 @@ import io.timelimit.android.R
|
|||
import io.timelimit.android.data.model.UserType
|
||||
import io.timelimit.android.ui.model.main.OverviewHandling
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
fun LazyListScope.userItems(screen: OverviewHandling.OverviewScreen) {
|
||||
item (key = Pair("users", "header")) {
|
||||
ListCommon.SectionHeader(stringResource(R.string.overview_header_users), Modifier.animateItemPlacement())
|
||||
}
|
||||
|
||||
items(screen.users.list, key = { Pair("user", it.id) }) { UserItem(it, screen.actions) }
|
||||
|
||||
if (screen.users.canAdd) item (key = Pair("users", "create")) {
|
||||
ListCommon.ActionListItem(
|
||||
icon = Icons.Default.Add,
|
||||
label = stringResource(R.string.add_user_title),
|
||||
action = screen.actions.addUser,
|
||||
modifier = Modifier.animateItemPlacement()
|
||||
)
|
||||
}
|
||||
|
||||
if (screen.users.canShowMore) item (key = Pair("users", "more")) {
|
||||
ListCommon.ShowMoreItem (
|
||||
modifier = Modifier.animateItemPlacement(),
|
||||
action = screen.actions.showMoreUsers
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun LazyItemScope.UserItem(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue