A cheap attempt at a native Bluesky client for Android
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

TimelineView: uploading post with a spinner

geesawra 35e7d5eb da2dcb18

+41 -13
+41 -13
app/src/main/java/industries/geesawra/jerryno/TimelineView.kt
··· 35 35 import androidx.compose.material3.Button 36 36 import androidx.compose.material3.ButtonDefaults 37 37 import androidx.compose.material3.Card 38 + import androidx.compose.material3.CircularProgressIndicator 38 39 import androidx.compose.material3.ExperimentalMaterial3Api 39 40 import androidx.compose.material3.FloatingActionButton 40 41 import androidx.compose.material3.HorizontalDivider ··· 58 59 import androidx.compose.runtime.Composable 59 60 import androidx.compose.runtime.LaunchedEffect 60 61 import androidx.compose.runtime.getValue 62 + import androidx.compose.runtime.mutableIntStateOf 61 63 import androidx.compose.runtime.mutableStateOf 62 64 import androidx.compose.runtime.remember 63 65 import androidx.compose.runtime.saveable.rememberSaveable ··· 161 163 sheetPeekHeight = 0.dp, 162 164 modifier = Modifier.consumeWindowInsets(WindowInsets.ime), 163 165 sheetContent = { 166 + val uploadingPost = remember { mutableStateOf(false) } 164 167 Box( 165 168 modifier = Modifier 166 169 .fillMaxWidth() ··· 173 176 .fillMaxHeight(), 174 177 horizontalAlignment = Alignment.CenterHorizontally 175 178 ) { 176 - Text( 177 - "New Post", 178 - style = MaterialTheme.typography.titleLarge, 179 - modifier = Modifier.padding(bottom = 16.dp) 180 - ) 179 + Row { 180 + Text( 181 + "New Post", 182 + style = MaterialTheme.typography.titleLarge, 183 + modifier = Modifier.padding(bottom = 16.dp) 184 + ) 185 + } 181 186 182 - val charCount = remember { mutableStateOf(0) } 187 + val charCount = remember { mutableIntStateOf(0) } 183 188 val wasEdited = remember { mutableStateOf(false) } 184 189 185 190 OutlinedTextField( ··· 194 199 onValueChange = { 195 200 wasEdited.value = true 196 201 postText = it 197 - charCount.value = it.length 202 + charCount.intValue = it.length 198 203 }, 199 204 modifier = Modifier 200 205 .fillMaxWidth() ··· 203 208 label = { 204 209 if (wasEdited.value) { 205 210 Text( 206 - text = "${maxChars - charCount.value}", 211 + text = "${maxChars - charCount.intValue}", 207 212 color = if (postText.length > maxChars) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurface 208 213 ) 209 214 // return@OutlinedTextField // This return might be causing label issues, consider removing or restructuring ··· 255 260 Icon(Icons.Default.Attachment, contentDescription = "Attach media") 256 261 } 257 262 263 + if (uploadingPost.value) { 264 + CircularProgressIndicator() 265 + } 266 + 267 + val postButtonEnabled = remember { mutableStateOf(true) } 258 268 Button( 259 269 onClick = { 260 270 if (postText.isNotBlank() && postText.length <= maxChars) { 261 - // viewModel.postSkeet(postText) // Example action 262 271 coroutineScope.launch { 263 - scaffoldState.bottomSheetState.hide() 272 + postButtonEnabled.value = false 273 + uploadingPost.value = true 274 + timelineViewModel.post( 275 + postText, 276 + mediaSelected.value.keys.toList(), 277 + null 278 + ).onSuccess { 279 + scaffoldState.bottomSheetState.hide() 280 + postText = "" // Clear the text field 281 + wasEdited.value = false // Reset edited state 282 + postButtonEnabled.value = true 283 + uploadingPost.value = false 284 + }.onFailure { 285 + postButtonEnabled.value = true 286 + Toast.makeText( 287 + context, 288 + "Could not post: ${it.message}", 289 + Toast.LENGTH_SHORT 290 + ).show() 291 + uploadingPost.value = false 292 + postButtonEnabled.value = true 293 + } 264 294 } 265 - postText = "" // Clear the text field 266 - wasEdited.value = false // Reset edited state 267 295 } 268 296 }, 269 - enabled = postText.isNotBlank() && postText.length <= maxChars 297 + enabled = (postText.isNotBlank() || mediaSelected.value.isNotEmpty()) && postText.length <= maxChars && postButtonEnabled.value 270 298 ) { 271 299 Icon(Icons.AutoMirrored.Filled.Send, contentDescription = "Post") 272 300 Spacer(Modifier.size(ButtonDefaults.IconSpacing))