1
1
package dev.aungkyawpaing.ccdroidx.feature.projectlist
2
2
3
- import androidx.compose.foundation.layout.Column
4
3
import androidx.compose.foundation.layout.fillMaxSize
5
4
import androidx.compose.foundation.layout.padding
6
5
import androidx.compose.material.icons.Icons
7
6
import androidx.compose.material.icons.filled.Add
8
- import androidx.compose.material.icons.filled.Settings
9
- import androidx.compose.material.icons.filled.Sync
10
7
import androidx.compose.material3.AlertDialog
11
- import androidx.compose.material3.ExperimentalMaterial3Api
12
8
import androidx.compose.material3.FloatingActionButton
13
9
import androidx.compose.material3.Icon
14
- import androidx.compose.material3.IconButton
15
- import androidx.compose.material3.MaterialTheme
16
10
import androidx.compose.material3.Scaffold
17
11
import androidx.compose.material3.Text
18
12
import androidx.compose.material3.TextButton
19
- import androidx.compose.material3.TopAppBar
20
- import androidx.compose.material3.TopAppBarDefaults
21
13
import androidx.compose.runtime.Composable
22
14
import androidx.compose.runtime.livedata.observeAsState
23
15
import androidx.compose.runtime.mutableStateOf
@@ -26,9 +18,6 @@ import androidx.compose.runtime.rememberCoroutineScope
26
18
import androidx.compose.ui.Modifier
27
19
import androidx.compose.ui.platform.LocalContext
28
20
import androidx.compose.ui.res.stringResource
29
- import androidx.compose.ui.semantics.contentDescription
30
- import androidx.compose.ui.semantics.semantics
31
- import androidx.compose.ui.semantics.stateDescription
32
21
import androidx.compose.ui.unit.dp
33
22
import androidx.constraintlayout.compose.ConstraintLayout
34
23
import androidx.constraintlayout.compose.Dimension
@@ -41,122 +30,36 @@ import dev.aungkyawpaing.ccdroidx.common.Project
41
30
import dev.aungkyawpaing.ccdroidx.common.extensions.findActivity
42
31
import dev.aungkyawpaing.ccdroidx.feature.browser.openInBrowser
43
32
import dev.aungkyawpaing.ccdroidx.feature.destinations.AddProjectDialogScreenDestination
44
- import dev.aungkyawpaing.ccdroidx.feature.destinations.SettingsPageDestination
45
33
import dev.aungkyawpaing.ccdroidx.feature.notification.prompt.NotificationPrompt
46
34
import dev.aungkyawpaing.ccdroidx.feature.notification.prompt.NotificationPromptViewModel
47
35
import dev.aungkyawpaing.ccdroidx.feature.projectlist.component.ProjectList
48
- import dev.aungkyawpaing.ccdroidx.feature.sync.LastSyncedState
36
+ import dev.aungkyawpaing.ccdroidx.feature.projectlist.component.ProjectListTopAppBar
49
37
import dev.aungkyawpaing.ccdroidx.feature.sync.LastSyncedStatus
50
38
import kotlinx.coroutines.launch
51
- import org.ocpsoft.prettytime.PrettyTime
52
39
import java.time.Clock
53
40
54
- @Composable
55
- private fun getSubtitleText (lastSyncedStatus : LastSyncedStatus ? , clock : Clock ): String =
56
- if (lastSyncedStatus == null ) {
57
- stringResource(R .string.welcome)
58
- } else {
59
- when (lastSyncedStatus.lastSyncedState) {
60
- LastSyncedState .SYNCING -> {
61
- stringResource(R .string.syncing)
62
- }
63
-
64
- LastSyncedState .SUCCESS , LastSyncedState .FAILED -> {
65
- stringResource(
66
- R .string.last_synced_x,
67
- PrettyTime (clock.instant()).format(lastSyncedStatus.lastSyncedDateTime)
68
- )
69
- }
70
- }
71
- }
72
-
73
- @OptIn(ExperimentalMaterial3Api ::class )
74
- @Composable
75
- fun ProjectListTopAppBar (
76
- lastSyncedStatus : LastSyncedStatus ? ,
77
- onProgressSyncedEvent : Boolean ,
78
- onPressSync : () -> Unit ,
79
- clearOnProgressSyncedEvent : () -> Unit ,
80
- navigator : DestinationsNavigator ,
81
- clock : Clock
82
- ) {
83
- TopAppBar (
84
- title = {
85
- Column {
86
- Text (stringResource(id = R .string.app_name), modifier = Modifier .semantics {
87
- contentDescription = " CC Droid X"
88
- })
89
- Text (
90
- text = getSubtitleText(lastSyncedStatus, clock),
91
- style = MaterialTheme .typography.bodyMedium
92
- )
93
- }
94
- },
95
- actions = {
96
- IconButton (
97
- onClick = onPressSync,
98
- modifier = Modifier .semantics {
99
- stateDescription = if (onProgressSyncedEvent) " Finished syncing" else " "
100
-
101
- if (onProgressSyncedEvent) {
102
- clearOnProgressSyncedEvent()
103
- }
104
- }
105
- ) {
106
- Icon (
107
- Icons .Filled .Sync ,
108
- contentDescription = stringResource(R .string.menu_item_sync_project_status)
109
- )
110
- }
111
-
112
- IconButton (onClick = {
113
- navigator.navigate(SettingsPageDestination ())
114
- }) {
115
- Icon (
116
- Icons .Filled .Settings ,
117
- contentDescription = stringResource(R .string.menu_item_settings)
118
- )
119
- }
120
- },
121
- colors = TopAppBarDefaults .topAppBarColors(
122
- containerColor = MaterialTheme .colorScheme.primary,
123
- titleContentColor = MaterialTheme .colorScheme.onPrimary,
124
- actionIconContentColor = MaterialTheme .colorScheme.onPrimary
125
- )
126
- )
127
- }
128
-
129
41
@Composable
130
42
fun DeleteConfirmationDialog (
131
- onConfirmDelete : () -> Unit ,
132
- onDismiss : () -> Unit
43
+ onConfirmDelete : () -> Unit , onDismiss : () -> Unit
133
44
) {
134
- AlertDialog (
135
- onDismissRequest = onDismiss,
136
- title = {
137
- Text (text = stringResource(id = R .string.confirm_delete_title))
138
- },
139
- text = {
140
- Text (text = stringResource(id = R .string.confirm_delete_message))
141
- },
142
- confirmButton = {
143
- TextButton (
144
- onClick = {
145
- onConfirmDelete()
146
- onDismiss()
147
- }
148
- ) {
149
- Text (stringResource(id = R .string.action_item_project_delete_project))
150
- }
151
- },
152
- dismissButton = {
153
- TextButton (
154
- onClick = onDismiss
155
- ) {
156
- Text (stringResource(id = android.R .string.cancel))
157
- }
45
+ AlertDialog (onDismissRequest = onDismiss, title = {
46
+ Text (text = stringResource(id = R .string.confirm_delete_title))
47
+ }, text = {
48
+ Text (text = stringResource(id = R .string.confirm_delete_message))
49
+ }, confirmButton = {
50
+ TextButton (onClick = {
51
+ onConfirmDelete()
52
+ onDismiss()
53
+ }) {
54
+ Text (stringResource(id = R .string.action_item_project_delete_project))
158
55
}
159
- )
56
+ }, dismissButton = {
57
+ TextButton (
58
+ onClick = onDismiss
59
+ ) {
60
+ Text (stringResource(id = android.R .string.cancel))
61
+ }
62
+ })
160
63
}
161
64
162
65
@Composable
@@ -176,20 +79,17 @@ fun ProjectListPageContent(
176
79
val context = LocalContext .current
177
80
val scope = rememberCoroutineScope()
178
81
179
- Scaffold (
180
- topBar = {
181
- ProjectListTopAppBar (
182
- lastSyncedStatus,
183
- onProgressSyncedEvent,
184
- onPressSync,
185
- clearOnProgressSyncedEvent,
186
- navigator,
187
- clock
188
- )
189
- }
190
- ) { contentPadding ->
191
- val deleteConfirmDialog =
192
- remember { mutableStateOf<Project ?>(null ) }
82
+ Scaffold (topBar = {
83
+ ProjectListTopAppBar (
84
+ lastSyncedStatus,
85
+ onProgressSyncedEvent,
86
+ onPressSync,
87
+ clearOnProgressSyncedEvent,
88
+ navigator,
89
+ clock
90
+ )
91
+ }) { contentPadding ->
92
+ val deleteConfirmDialog = remember { mutableStateOf<Project ?>(null ) }
193
93
194
94
ConstraintLayout (
195
95
modifier = Modifier
@@ -199,28 +99,22 @@ fun ProjectListPageContent(
199
99
200
100
val (notificationPrompt, projectListComponent, fabAddProject) = createRefs()
201
101
202
- ProjectList (
203
- projectList = projectList,
204
- onOpenRepoClick = { project ->
205
- context.findActivity()?.let { activity ->
206
- scope.launch {
207
- openInBrowser(activity, project.webUrl)
208
- }
102
+ ProjectList (projectList = projectList, onOpenRepoClick = { project ->
103
+ context.findActivity()?.let { activity ->
104
+ scope.launch {
105
+ openInBrowser(activity, project.webUrl)
209
106
}
210
- },
211
- onDeleteClick = { project ->
212
- deleteConfirmDialog.value = project
213
- },
214
- onToggleMute = onToggleMute,
215
- modifier = Modifier .constrainAs(projectListComponent) {
216
- end.linkTo(parent.end)
217
- start.linkTo(parent.start)
218
- bottom.linkTo(notificationPrompt.top)
219
- top.linkTo(parent.top)
220
- height = Dimension .fillToConstraints
221
- width = Dimension .fillToConstraints
222
- },
223
- clock = clock
107
+ }
108
+ }, onDeleteClick = { project ->
109
+ deleteConfirmDialog.value = project
110
+ }, onToggleMute = onToggleMute, modifier = Modifier .constrainAs(projectListComponent) {
111
+ end.linkTo(parent.end)
112
+ start.linkTo(parent.start)
113
+ bottom.linkTo(notificationPrompt.top)
114
+ top.linkTo(parent.top)
115
+ height = Dimension .fillToConstraints
116
+ width = Dimension .fillToConstraints
117
+ }, clock = clock
224
118
)
225
119
226
120
NotificationPrompt (
@@ -240,22 +134,18 @@ fun ProjectListPageContent(
240
134
}
241
135
.padding(16 .dp)) {
242
136
Icon (
243
- Icons .Filled .Add ,
244
- contentDescription = stringResource(R .string.cd_fab_add_project)
137
+ Icons .Filled .Add , contentDescription = stringResource(R .string.cd_fab_add_project)
245
138
)
246
139
}
247
140
248
141
}
249
142
250
143
if (deleteConfirmDialog.value != null ) {
251
- DeleteConfirmationDialog (
252
- onConfirmDelete = {
253
- onDeleteProject(deleteConfirmDialog.value!! )
254
- },
255
- onDismiss = {
256
- deleteConfirmDialog.value = null
257
- }
258
- )
144
+ DeleteConfirmationDialog (onConfirmDelete = {
145
+ onDeleteProject(deleteConfirmDialog.value!! )
146
+ }, onDismiss = {
147
+ deleteConfirmDialog.value = null
148
+ })
259
149
}
260
150
}
261
151
}
0 commit comments