A cheap attempt at a native Bluesky client for Android

Compose: Update pull-to-refresh indicator

Use the new `PullToRefreshBox` from Material 3 Expressive, which provides a more modern pull-to-refresh indicator.

This also includes updating various androidx and other third-party dependencies.

+36 -41
+14 -14
app/build.gradle.kts
··· 57 57 58 58 dependencies { 59 59 implementation("androidx.core:core-splashscreen:1.0.1") 60 - implementation("io.ktor:ktor-client-cio:3.0.1") // Or another engine like OkHttp 61 - implementation("io.ktor:ktor-client-plugins:3.0.1") // Or more specifically: 62 - implementation("io.ktor:ktor-client-core:3.0.1") // Or the version aligned with the library 63 - implementation("io.ktor:ktor-client-okhttp:3.0.1") // Or your preferred engine 64 - implementation("io.ktor:ktor-client-content-negotiation:3.0.1") 65 - implementation("io.ktor:ktor-serialization-kotlinx-json:3.0.1") 60 + implementation("io.ktor:ktor-client-cio:3.3.1") // Or another engine like OkHttp 61 + implementation("io.ktor:ktor-client-plugins:3.1.1") // Or more specifically: 62 + implementation("io.ktor:ktor-client-core:3.3.1") // Or the version aligned with the library 63 + implementation("io.ktor:ktor-client-okhttp:3.3.1") // Or your preferred engine 64 + implementation("io.ktor:ktor-client-content-negotiation:3.3.1") 65 + implementation("io.ktor:ktor-serialization-kotlinx-json:3.3.1") 66 66 implementation("sh.christian.ozone:bluesky:0.3.3") 67 - implementation("androidx.navigation:navigation-compose:2.9.4") 68 - implementation("io.coil-kt.coil3:coil-compose:3.0.1") 69 - implementation("io.coil-kt.coil3:coil-network-okhttp:3.0.1") 67 + implementation("androidx.navigation:navigation-compose:2.9.5") 68 + implementation("io.coil-kt.coil3:coil-compose:3.3.0") 69 + implementation("io.coil-kt.coil3:coil-network-okhttp:3.3.0") 70 70 implementation("io.github.fornewid:placeholder-material3:2.0.0") 71 71 implementation("androidx.media3:media3-exoplayer:1.8.0") // [Required] androidx.media3 ExoPlayer dependency 72 72 implementation("androidx.media3:media3-session:1.8.0") // [Required] MediaSession Extension dependency ··· 75 75 implementation("androidx.media3:media3-exoplayer-dash:1.8.0") 76 76 implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.9.4") 77 77 implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.4") 78 - implementation("com.google.dagger:hilt-android:2.57.1") 78 + implementation("com.google.dagger:hilt-android:2.57.2") 79 79 implementation("androidx.hilt:hilt-navigation-compose:1.3.0") 80 80 implementation("androidx.compose.material3:material3-adaptive-navigation-suite") 81 81 implementation("androidx.compose.material:material-icons-extended") 82 82 implementation("androidx.datastore:datastore-preferences:1.1.7") 83 83 implementation("androidx.datastore:datastore:1.1.7") 84 84 implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0") 85 - implementation(platform("androidx.compose:compose-bom:2025.09.00")) 86 - implementation("androidx.paging:paging-compose:3.3.0-alpha05") 87 - implementation("me.saket.telephoto:zoomable:0.17.0") 88 - implementation("me.saket.telephoto:zoomable-image-coil3:0.17.0") 85 + implementation(platform("androidx.compose:compose-bom:2025.10.01")) 86 + implementation("androidx.paging:paging-compose:3.3.6") 87 + implementation("me.saket.telephoto:zoomable:0.18.0") 88 + implementation("me.saket.telephoto:zoomable-image-coil3:0.18.0") 89 89 implementation("androidx.browser:browser:1.9.0") 90 90 implementation("androidx.media3:media3-transformer:1.8.0") 91 91 implementation("androidx.media3:media3-effect:1.8.0")
+13 -18
app/src/main/java/industries/geesawra/monarch/MainView.kt
··· 32 32 import androidx.compose.material3.BottomSheetScaffold 33 33 import androidx.compose.material3.DrawerValue 34 34 import androidx.compose.material3.ExperimentalMaterial3Api 35 + import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi 35 36 import androidx.compose.material3.FloatingActionButton 36 37 import androidx.compose.material3.FloatingActionButtonDefaults 37 38 import androidx.compose.material3.Icon ··· 51 52 import androidx.compose.material3.TopAppBarColors 52 53 import androidx.compose.material3.TopAppBarDefaults 53 54 import androidx.compose.material3.pulltorefresh.PullToRefreshBox 55 + import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults.LoadingIndicator 56 + import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState 54 57 import androidx.compose.material3.rememberBottomSheetScaffoldState 55 58 import androidx.compose.material3.rememberDrawerState 56 59 import androidx.compose.material3.rememberModalBottomSheetState ··· 189 192 ) 190 193 } 191 194 192 - @OptIn(ExperimentalMaterial3Api::class) 195 + @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) 193 196 @Composable 194 197 private fun InnerTimelineView( 195 198 modifier: Modifier = Modifier, ··· 230 233 } 231 234 } 232 235 236 + val pullToRefreshState = rememberPullToRefreshState() 233 237 PullToRefreshBox( 238 + state = pullToRefreshState, 234 239 isRefreshing = isRefreshing, 240 + indicator = { 241 + LoadingIndicator( 242 + modifier = Modifier.align(Alignment.TopCenter), 243 + isRefreshing = isRefreshing, 244 + state = pullToRefreshState, 245 + ) 246 + }, 235 247 onRefresh = { 236 248 timelineViewModel.fetchAllNewData() { 237 249 coroutineScope.launch { ··· 243 255 } 244 256 } 245 257 } 246 - // when (currentDestination) { 247 - // TabBarDestinations.TIMELINE -> { 248 - // timelineViewModel.fetchTimeline(fresh = true) { 249 - // coroutineScope.launch { 250 - // timelineState.scrollToItem(0) 251 - // } 252 - // } 253 - // } 254 - // 255 - // TabBarDestinations.NOTIFICATIONS -> { 256 - // timelineViewModel.fetchNotifications(fresh = true) { 257 - // coroutineScope.launch { 258 - // notificationsState.scrollToItem(0) 259 - // } 260 - // } 261 - // } 262 - // } 263 258 }, 264 259 ) { 265 260 ModalNavigationDrawer(
+9 -9
gradle/libs.versions.toml
··· 1 1 [versions] 2 2 agp = "8.13.0" 3 - kotlin = "2.0.21" 4 - coreKtx = "1.10.1" 3 + kotlin = "2.2.21" 4 + coreKtx = "1.17.0" 5 5 junit = "4.13.2" 6 - junitVersion = "1.1.5" 7 - espressoCore = "3.5.1" 8 - lifecycleRuntimeKtx = "2.6.1" 9 - activityCompose = "1.8.0" 10 - composeBom = "2024.09.00" 11 - animationCoreLint = "1.9.2" 12 - material3 = "1.4.0" 6 + junitVersion = "1.3.0" 7 + espressoCore = "3.7.0" 8 + lifecycleRuntimeKtx = "2.9.4" 9 + activityCompose = "1.11.0" 10 + composeBom = "2025.10.01" 11 + animationCoreLint = "1.9.4" 12 + material3 = "1.5.0-alpha07" 13 13 14 14 [libraries] 15 15 androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }