Commit d7e060c1 by Aleksandr

Template for Job details screen

parent fa0d47f7
......@@ -6,7 +6,7 @@ annotation class Argument {
const val URI = "URI"
const val LATITUDE = "LATITUDE"
const val LONGITUDE = "LONGITUDE"
const val SPOT_ID = "SPOT_ID"
const val SPOT_CODE = "SPOT_CODE"
const val ID = "ID"
}
}
......@@ -11,16 +11,14 @@ import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.navArgument
import com.isidroid.c23.ui.navigation.Content
import com.isidroid.c23.ui.navigation.Home
import com.isidroid.c23.ui.navigation.Map
import com.isidroid.c23.ui.navigation.PrintJobs
import com.isidroid.c23.ui.navigation.RenderPreview
val String?.isEdgeToEdge
get() = arrayOf(
RenderPreview.route,
Content.route,
Map.route,
PrintJobs.route
get() = !arrayOf(
Home.route,
).any {
this?.contains(it) == true
}
......@@ -54,7 +52,7 @@ fun BasicNavHost(
)
}
internal fun makeNavArgument(name: String, type: NavType<*>, nullable: Boolean = true, defaultValue: Any? = null) = navArgument(name){
internal fun makeNavArgument(name: String, type: NavType<*>, nullable: Boolean = true, defaultValue: Any? = null) = navArgument(name) {
this.type = type
this.nullable = nullable
this.defaultValue = defaultValue
......
......@@ -2,6 +2,7 @@ package com.isidroid.c23.ui._component
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.KeyboardArrowLeft
......
......@@ -22,4 +22,8 @@ object Map: NavDirection {
object PrintJobs: NavDirection {
override val route: String = "PrintJobs"
}
\ No newline at end of file
}
object JobDetails: NavDirection {
override val route: String = "JobDetails"
}
......@@ -11,6 +11,7 @@ import com.isidroid.c23.ext.isDebug
import com.isidroid.c23.ext.makeNavArgument
import com.isidroid.c23.ui.navigation.destinations.ContentScreenDestination
import com.isidroid.c23.ui.navigation.destinations.HomeScreenDestination
import com.isidroid.c23.ui.navigation.destinations.JobDetailsDestination
import com.isidroid.c23.ui.navigation.destinations.MapScreenDestination
import com.isidroid.c23.ui.navigation.destinations.PrintJobsScreenDestination
import com.isidroid.c23.ui.navigation.destinations.RenderScreenDestination
......@@ -46,6 +47,14 @@ fun AppNavHost(
),
content = { MapScreenDestination(navController) }
)
composable(
route = routeJobDetails(id = "{${Argument.ID}}"),
arguments = listOf(
makeNavArgument(Argument.ID, NavType.StringType, nullable = true)
),
content = { JobDetailsDestination(navController) }
)
}
}
......@@ -15,3 +15,7 @@ internal fun routeMap(lat: String? = null, lng: String? = null, spotCode: String
.appendQueryParameter(Argument.LONGITUDE, lng)
.appendQueryParameter(Argument.SPOT_CODE, spotCode)
.toString()
internal fun routeJobDetails(id: String = Argument.ID) = JobDetails.route.toUri().buildUpon()
.appendQueryParameter(Argument.ID, id)
.toString()
\ No newline at end of file
package com.isidroid.c23.ui.navigation.destinations
import androidx.compose.runtime.Composable
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import com.isidroid.c23.ui.screen.details.JobDetailsContract
import com.isidroid.c23.ui.screen.details.JobDetailsScreen
import com.isidroid.c23.ui.screen.details.JobDetailsViewModel
import com.isidroid.c23.ui.screen.print_jobs.PrintJobsContract
import com.isidroid.c23.ui.screen.print_jobs.PrintJobsScreen
import com.isidroid.c23.ui.screen.print_jobs.PrintJobsViewModel
@Composable
fun JobDetailsDestination(navController: NavHostController) {
val viewModel: JobDetailsViewModel = hiltViewModel()
JobDetailsScreen(
state = viewModel.viewState,
effectFlow = viewModel.effect,
onEventSent = { event -> viewModel.setEvent(event) },
onNavigationRequested = { effect ->
when (effect) {
JobDetailsContract.Effect.Navigation.ToBack -> navController.popBackStack()
}
},
)
}
\ No newline at end of file
......@@ -3,6 +3,7 @@ package com.isidroid.c23.ui.navigation.destinations
import androidx.compose.runtime.Composable
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import com.isidroid.c23.ui.navigation.routeJobDetails
import com.isidroid.c23.ui.screen.print_jobs.PrintJobsContract
import com.isidroid.c23.ui.screen.print_jobs.PrintJobsScreen
import com.isidroid.c23.ui.screen.print_jobs.PrintJobsViewModel
......@@ -18,6 +19,7 @@ fun PrintJobsScreenDestination(navController: NavHostController) {
onNavigationRequested = { effect ->
when (effect) {
PrintJobsContract.Effect.Navigation.ToBack -> navController.popBackStack()
is PrintJobsContract.Effect.Navigation.ToDetails -> navController.navigate(routeJobDetails(id = effect.id))
}
},
)
......
package com.isidroid.c23.ui.screen.details
import com.isidroid.c23.ui.screen.content.ContentContract
import com.isidroid.core.vm.ViewEvent
import com.isidroid.core.vm.ViewSideEffect
import com.isidroid.core.vm.ViewState
class JobDetailsContract {
sealed interface Event : ViewEvent {
data object ToBack : Event
}
sealed interface Effect : ViewSideEffect {
sealed interface Navigation : Effect {
data object ToBack : Navigation
}
}
data class State(val i: Int = 0) : ViewState
}
\ No newline at end of file
package com.isidroid.c23.ui.screen.details
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import com.isidroid.c23.R
import com.isidroid.c23.ui._component.TopAppBarComponent
import com.isidroid.core.vm.SIDE_EFFECTS_KEY
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun JobDetailsScreen(
state: State<JobDetailsContract.State>,
effectFlow: Flow<JobDetailsContract.Effect>?,
onEventSent: (event: JobDetailsContract.Event) -> Unit,
onNavigationRequested: (navigationEffect: JobDetailsContract.Effect.Navigation) -> Unit,
modifier: Modifier = Modifier,
) {
LaunchedEffect(SIDE_EFFECTS_KEY) {
effectFlow?.collect { effect ->
when (effect) {
is JobDetailsContract.Effect.Navigation -> onNavigationRequested(effect)
}
}
}
BackHandler { onEventSent(JobDetailsContract.Event.ToBack) }
Scaffold(
modifier = modifier.fillMaxSize(),
topBar = {
TopAppBarComponent(
text = "Print job details",
colors = TopAppBarDefaults.topAppBarColors(),
onNavigationClick = { onEventSent(JobDetailsContract.Event.ToBack) }
)
}
) { paddingValues ->
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text("Screen is under construction")
}
}
}
package com.isidroid.c23.ui.screen.details
import com.isidroid.c23.ext.isDebug
import com.isidroid.core.vm.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
@HiltViewModel
class JobDetailsViewModel @Inject constructor() : BaseViewModel<JobDetailsContract.Event, JobDetailsContract.State, JobDetailsContract.Effect>() {
override val isDebug: Boolean = isDebug()
override fun setInitialState(): JobDetailsContract.State = JobDetailsContract.State()
override suspend fun handleEvents(event: JobDetailsContract.Event) {
when(event){
JobDetailsContract.Event.ToBack -> setEffect { JobDetailsContract.Effect.Navigation.ToBack }
}
}
}
\ No newline at end of file
package com.isidroid.c23.ui.screen.print_jobs
import com.isidroid.c23.domain.dto.PrintJobListItem
import com.isidroid.c23.ui.screen.content.ContentContract
import com.isidroid.core.vm.ViewEvent
import com.isidroid.core.vm.ViewSideEffect
import com.isidroid.core.vm.ViewState
import com.isidroid.job.model.PrintJob
class PrintJobsContract {
sealed interface Event : ViewEvent {
data object ToBack : Event
data class ToDetails(val id: String) : Event
}
sealed interface Effect : ViewSideEffect {
sealed interface Navigation : Effect {
data object ToBack : Navigation
data class ToDetails(val id: String) : Navigation
}
}
......
package com.isidroid.c23.ui.screen.print_jobs
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
......@@ -36,11 +37,13 @@ fun PrintJobsScreen(
}
}
BackHandler { onEventSent(PrintJobsContract.Event.ToBack) }
Scaffold(
modifier = modifier.fillMaxSize(),
topBar = {
TopAppBarComponent(
text = stringResource(id = R.string.print_job_list),
text = stringResource(id = R.string.print_job_list),
colors = TopAppBarDefaults.topAppBarColors(),
onNavigationClick = { onEventSent(PrintJobsContract.Event.ToBack) }
)
......@@ -49,14 +52,19 @@ fun PrintJobsScreen(
ListComponent(
state = state,
modifier = Modifier.padding(paddingValues)
onEventSent = onEventSent,
modifier = Modifier.padding(paddingValues),
)
}
}
@Composable
private fun ListComponent(state: State<PrintJobsContract.State>, modifier: Modifier) {
private fun ListComponent(
state: State<PrintJobsContract.State>,
onEventSent: (event: PrintJobsContract.Event) -> Unit,
modifier: Modifier
) {
val list = state.value.jobs ?: return
LazyColumn(modifier) {
......@@ -69,7 +77,8 @@ private fun ListComponent(state: State<PrintJobsContract.State>, modifier: Modif
accessCode = item.accessCode,
statusColor = item.statusColor,
createdAt = item.createdAt,
modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp)
modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp),
clickOnCard = { onEventSent(PrintJobsContract.Event.ToDetails(item.id)) }
)
}
}
......
......@@ -8,10 +8,8 @@ import com.isidroid.core.vm.BaseViewModel
import com.isidroid.utils.catchTimber
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@HiltViewModel
......@@ -27,6 +25,7 @@ class PrintJobsViewModel @Inject constructor(
override suspend fun handleEvents(event: PrintJobsContract.Event) {
when (event) {
PrintJobsContract.Event.ToBack -> setEffect { PrintJobsContract.Effect.Navigation.ToBack }
is PrintJobsContract.Event.ToDetails -> setEffect { PrintJobsContract.Effect.Navigation.ToDetails(event.id) }
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment