Skip to content

Commit 6432060

Browse files
committed
Desktop refresh
1 parent 580beb8 commit 6432060

File tree

4 files changed

+71
-17
lines changed

4 files changed

+71
-17
lines changed

desktop/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ plugins {
99
dependencies {
1010
implementation(project(":shared"))
1111
implementation(compose.desktop.currentOs)
12+
implementation(compose.material3)
1213
implementation(libs.compose.viewmodel)
1314
implementation(libs.coroutines.swing)
1415
implementation(libs.koin)

desktop/src/main/kotlin/com/jdamcd/arrivals/desktop/ArrivalsView.kt

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,16 @@ import androidx.compose.foundation.layout.Column
1313
import androidx.compose.foundation.layout.Row
1414
import androidx.compose.foundation.layout.fillMaxSize
1515
import androidx.compose.foundation.layout.fillMaxWidth
16+
import androidx.compose.foundation.layout.height
1617
import androidx.compose.foundation.layout.padding
18+
import androidx.compose.foundation.layout.size
19+
import androidx.compose.material.ButtonDefaults
1720
import androidx.compose.material.CircularProgressIndicator
21+
import androidx.compose.material.Icon
1822
import androidx.compose.material.Text
23+
import androidx.compose.material.TextButton
24+
import androidx.compose.material.icons.Icons
25+
import androidx.compose.material.icons.rounded.Refresh
1926
import androidx.compose.runtime.Composable
2027
import androidx.compose.runtime.getValue
2128
import androidx.compose.ui.Alignment
@@ -27,7 +34,8 @@ import com.jdamcd.arrivals.Arrival
2734

2835
@Composable
2936
fun ArrivalsView(
30-
state: ArrivalsState
37+
state: ArrivalsState,
38+
onClickRefresh: () -> Unit
3139
) {
3240
Column(
3341
modifier = Modifier
@@ -37,7 +45,7 @@ fun ArrivalsView(
3745
) {
3846
when (state) {
3947
is ArrivalsState.Loading -> Loading()
40-
is ArrivalsState.Data -> Data(state)
48+
is ArrivalsState.Data -> Data(state, onClickRefresh)
4149
is ArrivalsState.Error -> Error(state.message)
4250
}
4351
}
@@ -49,12 +57,12 @@ private fun Loading() {
4957
modifier = Modifier.fillMaxSize(),
5058
contentAlignment = Alignment.Center
5159
) {
52-
CircularProgressIndicator(color = Text)
60+
CircularProgressIndicator(color = LedYellow)
5361
}
5462
}
5563

5664
@Composable
57-
private fun Data(state: ArrivalsState.Data) {
65+
private fun Data(state: ArrivalsState.Data, onClickRefresh: () -> Unit) {
5866
Column(
5967
modifier = Modifier
6068
.padding(32.dp)
@@ -68,8 +76,11 @@ private fun Data(state: ArrivalsState.Data) {
6876
Row(
6977
modifier = Modifier
7078
.background(color = Footer)
71-
.padding(16.dp)
79+
.padding(start = 32.dp, end = 28.dp, bottom = 4.dp)
7280
.fillMaxWidth()
81+
.height(70.dp),
82+
horizontalArrangement = Arrangement.SpaceBetween,
83+
verticalAlignment = Alignment.CenterVertically
7384
) {
7485
Text(
7586
text = state.result.station,
@@ -78,6 +89,29 @@ private fun Data(state: ArrivalsState.Data) {
7889
fontSize = 32.sp
7990
)
8091
)
92+
Box(
93+
modifier = Modifier.size(42.dp),
94+
contentAlignment = Alignment.Center
95+
) {
96+
if (state.refreshing) {
97+
CircularProgressIndicator(color = LedYellow, modifier = Modifier.size(22.dp))
98+
} else {
99+
TextButton(
100+
onClick = { onClickRefresh() },
101+
colors = ButtonDefaults.textButtonColors(
102+
contentColor = Text,
103+
backgroundColor = Footer
104+
)
105+
) {
106+
Icon(
107+
Icons.Rounded.Refresh,
108+
contentDescription = "Refresh",
109+
modifier = Modifier.size(32.dp),
110+
tint = Text
111+
)
112+
}
113+
}
114+
}
81115
}
82116
}
83117

desktop/src/main/kotlin/com/jdamcd/arrivals/desktop/ArrivalsViewModel.kt

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,55 @@ import androidx.lifecycle.ViewModel
44
import androidx.lifecycle.viewModelScope
55
import com.jdamcd.arrivals.Arrivals
66
import com.jdamcd.arrivals.ArrivalsInfo
7+
import kotlinx.coroutines.Job
78
import kotlinx.coroutines.delay
89
import kotlinx.coroutines.flow.MutableStateFlow
910
import kotlinx.coroutines.flow.StateFlow
1011
import kotlinx.coroutines.flow.asStateFlow
1112
import kotlinx.coroutines.launch
1213

13-
class ArrivalsViewModel(arrivals: Arrivals) : ViewModel() {
14+
class ArrivalsViewModel(private val arrivals: Arrivals) : ViewModel() {
1415

1516
private val _uiState = MutableStateFlow<ArrivalsState>(ArrivalsState.Loading)
1617
val uiState: StateFlow<ArrivalsState> = _uiState.asStateFlow()
1718

19+
private var job: Job? = null
20+
1821
init {
19-
viewModelScope.launch {
22+
startUpdates()
23+
}
24+
25+
fun refresh() {
26+
startUpdates()
27+
}
28+
29+
private fun startUpdates() {
30+
job?.cancel()
31+
job = viewModelScope.launch {
2032
while (true) {
21-
try {
22-
val result = arrivals.latest()
23-
_uiState.value = ArrivalsState.Data(result)
24-
} catch (e: Exception) {
25-
if (_uiState.value !is ArrivalsState.Data) {
26-
_uiState.value = ArrivalsState.Error(e.message ?: "Unknown error")
27-
}
28-
}
33+
update()
2934
delay(60_000L) // 60 seconds
3035
}
3136
}
3237
}
38+
39+
private suspend fun update() {
40+
if (_uiState.value is ArrivalsState.Data) {
41+
_uiState.value = ArrivalsState.Data((_uiState.value as ArrivalsState.Data).result, true)
42+
}
43+
try {
44+
val result = arrivals.latest()
45+
_uiState.value = ArrivalsState.Data(result, false)
46+
} catch (e: Exception) {
47+
if (_uiState.value !is ArrivalsState.Data) {
48+
_uiState.value = ArrivalsState.Error(e.message ?: "Unknown error")
49+
}
50+
}
51+
}
3352
}
3453

3554
sealed class ArrivalsState {
3655
data object Loading : ArrivalsState()
37-
data class Data(val result: ArrivalsInfo) : ArrivalsState()
56+
data class Data(val result: ArrivalsInfo, val refreshing: Boolean) : ArrivalsState()
3857
data class Error(val message: String) : ArrivalsState()
3958
}

desktop/src/main/kotlin/com/jdamcd/arrivals/desktop/Main.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ fun main() = application {
2828
state = windowState,
2929
title = "Arrivals"
3030
) {
31-
ArrivalsView(state)
31+
ArrivalsView(state, viewModel::refresh)
3232
}
3333
}

0 commit comments

Comments
 (0)