Skip to content

Commit a41982b

Browse files
committed
First iteration of AddSubscriptionScreen cleanup
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
1 parent 83012b4 commit a41982b

2 files changed

Lines changed: 47 additions & 69 deletions

File tree

app/src/main/java/at/bitfire/icsdroid/model/AddSubscriptionModel.kt

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package at.bitfire.icsdroid.model
22

33
import android.content.Context
4+
import android.content.Intent
45
import android.net.Uri
6+
import android.provider.OpenableColumns
57
import android.util.Log
8+
import android.widget.Toast
69
import androidx.compose.runtime.getValue
710
import androidx.compose.runtime.mutableStateOf
811
import androidx.compose.runtime.setValue
@@ -19,6 +22,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
1922
import dagger.hilt.android.qualifiers.ApplicationContext
2023
import kotlinx.coroutines.Dispatchers
2124
import kotlinx.coroutines.launch
25+
import kotlinx.coroutines.withContext
2226
import okhttp3.HttpUrl.Companion.toHttpUrl
2327
import java.net.URI
2428
import java.net.URISyntaxException
@@ -33,7 +37,6 @@ class AddSubscriptionModel @Inject constructor(
3337
) : ViewModel() {
3438

3539
data class UiState(
36-
val success: Boolean = false,
3740
val errorMessage: String? = null,
3841
val isCreating: Boolean = false,
3942
val showNextButton: Boolean = false,
@@ -129,10 +132,14 @@ class AddSubscriptionModel @Inject constructor(
129132
// sync the subscription to reflect the changes in the calendar provider
130133
SyncWorker.run(context)
131134
}
132-
uiState = uiState.copy(success = true)
135+
withContext(Dispatchers.Main) {
136+
Toast.makeText(context, R.string.add_calendar_created, Toast.LENGTH_LONG).show()
137+
}
133138
} catch (e: Exception) {
134139
Log.e(Constants.TAG, "Couldn't create calendar", e)
135-
uiState = uiState.copy(errorMessage = e.localizedMessage ?: e.message)
140+
withContext(Dispatchers.Main) {
141+
Toast.makeText(context, e.localizedMessage ?: e.message, Toast.LENGTH_LONG).show()
142+
}
136143
} finally {
137144
uiState = uiState.copy(isCreating = false)
138145
}
@@ -217,4 +224,32 @@ class AddSubscriptionModel @Inject constructor(
217224
}
218225
return uri
219226
}
227+
228+
fun initialize(title: String?, color: Int?, url: String?,) {
229+
if (subscriptionSettingsUseCase.uiState.isInitialized()) return
230+
subscriptionSettingsUseCase.setInitialValues(title, color, url)
231+
232+
if (url != null) {
233+
checkUrlIntroductionPage()
234+
}
235+
}
236+
237+
fun onFilePicked(uri: Uri?) {
238+
if (uri == null) return
239+
240+
// keep the picked file accessible after the first sync and reboots
241+
context.contentResolver.takePersistableUriPermission(
242+
uri,
243+
Intent.FLAG_GRANT_READ_URI_PERMISSION
244+
)
245+
subscriptionSettingsUseCase.setUrl(uri.toString())
246+
247+
// Get file name
248+
val displayName = context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
249+
if (!cursor.moveToFirst()) return@use null
250+
val name = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
251+
cursor.getString(name)
252+
}
253+
subscriptionSettingsUseCase.setFileName(displayName)
254+
}
220255
}

app/src/main/java/at/bitfire/icsdroid/ui/screen/AddSubscriptionScreen.kt

Lines changed: 9 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,14 @@
44

55
package at.bitfire.icsdroid.ui.screen
66

7-
import android.content.Intent
87
import android.net.Uri
9-
import android.provider.OpenableColumns
108
import android.util.Log
11-
import android.widget.Toast
129
import androidx.activity.compose.rememberLauncherForActivityResult
1310
import androidx.activity.result.contract.ActivityResultContracts
1411
import androidx.compose.animation.AnimatedVisibility
1512
import androidx.compose.animation.expandVertically
1613
import androidx.compose.foundation.ExperimentalFoundationApi
1714
import androidx.compose.foundation.layout.Arrangement
18-
import androidx.compose.foundation.layout.Box
1915
import androidx.compose.foundation.layout.Row
2016
import androidx.compose.foundation.layout.fillMaxSize
2117
import androidx.compose.foundation.layout.fillMaxWidth
@@ -42,7 +38,6 @@ import androidx.compose.runtime.rememberCoroutineScope
4238
import androidx.compose.ui.Alignment
4339
import androidx.compose.ui.Modifier
4440
import androidx.compose.ui.graphics.toArgb
45-
import androidx.compose.ui.platform.LocalContext
4641
import androidx.compose.ui.res.stringResource
4742
import androidx.compose.ui.unit.dp
4843
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
@@ -63,69 +58,16 @@ fun AddSubscriptionScreen(
6358
model: AddSubscriptionModel = hiltViewModel(),
6459
onBackRequested: () -> Unit
6560
) {
66-
val context = LocalContext.current
67-
val uiState = model.uiState
68-
69-
LaunchedEffect(uiState) {
70-
if (uiState.success) {
71-
// on success, show notification and close activity
72-
Toast.makeText(context, context.getString(R.string.add_calendar_created), Toast.LENGTH_LONG).show()
73-
onBackRequested()
74-
}
75-
uiState.errorMessage?.let {
76-
// on error, show error message
77-
Toast.makeText(context, it, Toast.LENGTH_LONG).show()
78-
}
79-
}
80-
81-
LaunchedEffect(title, color, url) {
82-
if (model.subscriptionSettingsUseCase.uiState.isInitialized())
83-
return@LaunchedEffect
84-
model.subscriptionSettingsUseCase.setInitialValues(title, color, url)
85-
86-
if (url != null) {
87-
model.checkUrlIntroductionPage()
88-
}
89-
}
61+
val scope = rememberCoroutineScope()
62+
val pagerState = rememberPagerState { 2 }
9063

9164
val pickFile = rememberLauncherForActivityResult(
9265
ActivityResultContracts.OpenDocument()
93-
) { uri: Uri? ->
94-
if (uri != null) {
95-
// keep the picked file accessible after the first sync and reboots
96-
context.contentResolver.takePersistableUriPermission(
97-
uri,
98-
Intent.FLAG_GRANT_READ_URI_PERMISSION
99-
)
100-
model.subscriptionSettingsUseCase.setUrl(uri.toString())
66+
) { uri: Uri? -> model.onFilePicked(uri) }
10167

102-
// Get file name
103-
val displayName = context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
104-
if (!cursor.moveToFirst()) return@use null
105-
val name = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
106-
cursor.getString(name)
107-
}
108-
model.subscriptionSettingsUseCase.setFileName(displayName)
109-
}
110-
}
111-
112-
Box(modifier = Modifier.imePadding()) {
113-
AddSubscriptionScreen(
114-
model = model,
115-
onPickFileRequested = { pickFile.launch(arrayOf("text/calendar")) },
116-
finish = onBackRequested
117-
)
68+
LaunchedEffect(title, color, url) {
69+
model.initialize(title, color, url)
11870
}
119-
}
120-
121-
@Composable
122-
fun AddSubscriptionScreen(
123-
model: AddSubscriptionModel,
124-
onPickFileRequested: () -> Unit,
125-
finish: () -> Unit
126-
) {
127-
val scope = rememberCoroutineScope()
128-
val pagerState = rememberPagerState { 2 }
12971

13072
// Receive updates for the URL introduction page
13173
with(model.subscriptionSettingsUseCase.uiState) {
@@ -202,7 +144,7 @@ fun AddSubscriptionScreen(
202144
isCreating = model.uiState.isCreating,
203145
validationResult = validationResult,
204146
onResetResult = model::resetValidationResult,
205-
onPickFileRequested = onPickFileRequested,
147+
onPickFileRequested = { pickFile.launch(arrayOf("text/calendar")) },
206148
onNextRequested = { page: Int ->
207149
when (page) {
208150
// First page (Enter Url)
@@ -225,13 +167,13 @@ fun AddSubscriptionScreen(
225167
}
226168
// Second page (details and confirm)
227169
1 -> {
228-
model.createSubscription()
170+
model.createSubscription().invokeOnCompletion { onBackRequested() }
229171
}
230172
}
231173
},
232174
onNavigationClicked = {
233175
// If first page, close activity
234-
if (pagerState.currentPage <= 0) finish()
176+
if (pagerState.currentPage <= 0) onBackRequested()
235177
// otherwise, go back a page
236178
else scope.launch {
237179
// Needed for non-first-time validations to trigger following validation result updates
@@ -296,6 +238,7 @@ fun AddSubscriptionScreen(
296238
modifier = Modifier
297239
.fillMaxSize()
298240
.padding(paddingValues)
241+
.imePadding()
299242
) { page ->
300243
when (page) {
301244
0 -> EnterUrlComposable(

0 commit comments

Comments
 (0)