Skip to content

Commit 88d101a

Browse files
authored
Merge pull request #133 from CrisisCleanup/improve-data-caching
Improve data caching
2 parents 306d258 + 8370f17 commit 88d101a

File tree

44 files changed

+378
-228
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+378
-228
lines changed

app-sandbox/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ dependencies {
6363
implementation(libs.androidx.profileinstaller)
6464

6565
implementation(libs.coil.kt)
66+
implementation(libs.coil.kt.compose)
6667

6768
implementation(libs.kotlinx.coroutines.playservices)
6869
implementation(libs.playservices.maps)

app-sandbox/src/main/java/com/crisiscleanup/sandbox/SandboxApp.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ import androidx.navigation.NavController
2424
import com.crisiscleanup.core.designsystem.component.CrisisCleanupBackground
2525
import com.crisiscleanup.core.designsystem.component.CrisisCleanupTextButton
2626
import com.crisiscleanup.core.designsystem.theme.listItemSpacedBy
27-
import com.crisiscleanup.sandbox.navigation.MULTI_IMAGE_ROUTE
27+
import com.crisiscleanup.sandbox.navigation.ASYNC_IMAGE_ROUTE
2828
import com.crisiscleanup.sandbox.navigation.SandboxNavHost
29+
import com.crisiscleanup.sandbox.navigation.navigateToAsyncImage
2930
import com.crisiscleanup.sandbox.navigation.navigateToBottomNav
3031
import com.crisiscleanup.sandbox.navigation.navigateToCheckboxes
3132
import com.crisiscleanup.sandbox.navigation.navigateToChips
@@ -65,7 +66,7 @@ fun SandboxApp(
6566
SandboxNavHost(
6667
appState.navController,
6768
appState::onBack,
68-
MULTI_IMAGE_ROUTE,
69+
ASYNC_IMAGE_ROUTE,
6970
)
7071
}
7172
}
@@ -98,6 +99,9 @@ fun RootRoute(navController: NavController) {
9899
CrisisCleanupTextButton(text = "Images") {
99100
navController.navigateToMultiImage()
100101
}
102+
CrisisCleanupTextButton(text = "Async image") {
103+
navController.navigateToAsyncImage()
104+
}
101105
}
102106
}
103107
}

app-sandbox/src/main/java/com/crisiscleanup/sandbox/SandboxApplication.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,6 @@ class AppSyncer @Inject constructor() : SyncPuller, SyncPusher {
134134

135135
override suspend fun syncPushWorksitesAsync() = CompletableDeferred(SyncResult.NotAttempted(""))
136136

137-
override fun stopPushWorksites() {}
138-
139137
override suspend fun syncPushMedia() = SyncResult.NotAttempted("")
140138

141139
override suspend fun syncPushWorksites() = SyncResult.NotAttempted("")

app-sandbox/src/main/java/com/crisiscleanup/sandbox/navigation/SandboxNavigation.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.navigation.NavHostController
66
import androidx.navigation.compose.NavHost
77
import androidx.navigation.compose.composable
88
import com.crisiscleanup.sandbox.RootRoute
9+
import com.crisiscleanup.sandbox.ui.AsyncImageView
910
import com.crisiscleanup.sandbox.ui.BottomNavRoute
1011
import com.crisiscleanup.sandbox.ui.CheckboxesRoute
1112
import com.crisiscleanup.sandbox.ui.ChipsRoute
@@ -18,6 +19,7 @@ private const val CHIPS_ROUTE = "chips"
1819
private const val BOTTOM_NAV_ROUTE = "bottom-nav"
1920
const val SINGLE_IMAGE_ROUTE = "single-image"
2021
const val MULTI_IMAGE_ROUTE = "multi-image"
22+
const val ASYNC_IMAGE_ROUTE = "async-image"
2123

2224
fun NavController.navigateToBottomNav() {
2325
this.navigate(BOTTOM_NAV_ROUTE)
@@ -39,6 +41,10 @@ fun NavController.navigateToMultiImage() {
3941
this.navigate(MULTI_IMAGE_ROUTE)
4042
}
4143

44+
fun NavController.navigateToAsyncImage() {
45+
this.navigate(ASYNC_IMAGE_ROUTE)
46+
}
47+
4248
@Composable
4349
fun SandboxNavHost(
4450
navController: NavHostController,
@@ -72,5 +78,9 @@ fun SandboxNavHost(
7278
composable(MULTI_IMAGE_ROUTE) {
7379
MultiImageRoute(onBack)
7480
}
81+
82+
composable(ASYNC_IMAGE_ROUTE) {
83+
AsyncImageView()
84+
}
7585
}
7686
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.crisiscleanup.sandbox.ui
2+
3+
import android.util.Log
4+
import androidx.compose.foundation.layout.fillMaxSize
5+
import androidx.compose.foundation.layout.sizeIn
6+
import androidx.compose.foundation.shape.RoundedCornerShape
7+
import androidx.compose.runtime.Composable
8+
import androidx.compose.ui.Modifier
9+
import androidx.compose.ui.draw.clip
10+
import androidx.compose.ui.graphics.vector.rememberVectorPainter
11+
import androidx.compose.ui.layout.ContentScale
12+
import androidx.compose.ui.platform.LocalContext
13+
import androidx.compose.ui.res.painterResource
14+
import androidx.compose.ui.unit.dp
15+
import coil.compose.AsyncImage
16+
import coil.request.ImageRequest
17+
import com.crisiscleanup.core.common.R
18+
import com.crisiscleanup.core.designsystem.icon.CrisisCleanupIcons
19+
20+
@Composable
21+
fun AsyncImageView() {
22+
val imageUrl = ""
23+
AsyncImage(
24+
model = ImageRequest.Builder(LocalContext.current)
25+
.data(imageUrl)
26+
.setHeader("User-Agent", "Mozilla/5.0")
27+
.build(),
28+
modifier = Modifier
29+
.sizeIn(minWidth = 96.dp)
30+
.fillMaxSize()
31+
.clip(RoundedCornerShape(8.dp)),
32+
placeholder = painterResource(R.drawable.cc_grayscale_pin),
33+
error = rememberVectorPainter(CrisisCleanupIcons.SyncProblem),
34+
fallback = rememberVectorPainter(CrisisCleanupIcons.Image),
35+
contentDescription = null,
36+
contentScale = ContentScale.Fit,
37+
onLoading = { loading ->
38+
Log.i("async-image", "Loading image $loading")
39+
},
40+
onSuccess = { success ->
41+
Log.i("async-image", "Successfully loaded ${success.result}")
42+
},
43+
onError = { e ->
44+
Log.e(
45+
"async-image",
46+
"Error loading image ${e.result} for $imageUrl",
47+
e.result.throwable,
48+
)
49+
},
50+
)
51+
}

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ plugins {
1414

1515
android {
1616
defaultConfig {
17-
val buildVersion = 247
17+
val buildVersion = 250
1818
applicationId = "com.crisiscleanup"
1919
versionCode = buildVersion
2020
versionName = "0.9.${buildVersion - 168}"

app/src/main/java/com/crisiscleanup/MainActivityViewModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class MainActivityViewModel @Inject constructor(
198198

199199
incidentSelector.incidentId
200200
.filter { it != EmptyIncident.id }
201+
.distinctUntilChanged()
201202
.onEach {
202203
sync(
203204
forcePullIncidents = false,

core/app-component/src/main/kotlin/com/crisiscleanup/core/appcomponent/AppTopBarDataProvider.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class AppTopBarDataProvider(
4343

4444
val showHeaderLoading = incidentCacheRepository.isSyncingActiveIncident
4545

46+
val enableIncidentSelect = incidentsRepository.isFirstLoad.map(Boolean::not)
47+
4648
val screenTitle = incidentSelector.incident
4749
.map { it.shortName.ifBlank { translator(screenTitleKey) } }
4850
.stateIn(

core/app-component/src/main/kotlin/com/crisiscleanup/core/appcomponent/ui/AppTopBar.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ fun AppTopBar(
2828
val isHeaderLoading by dataProvider.showHeaderLoading.collectAsState(false)
2929

3030
val disasterIconResId by dataProvider.disasterIconResId.collectAsStateWithLifecycle()
31+
val enableIncidentSelect by dataProvider.enableIncidentSelect.collectAsState(false)
3132

3233
val isAccountExpired by dataProvider.isAccountExpired.collectAsStateWithLifecycle()
3334
val profilePictureUri by dataProvider.profilePictureUri.collectAsStateWithLifecycle()
@@ -42,6 +43,7 @@ fun AppTopBar(
4243
isAccountExpired = isAccountExpired,
4344
openAuthentication = openAuthentication,
4445
disasterIconResId = disasterIconResId,
46+
enableIncidentSelect = enableIncidentSelect,
4547
onOpenIncidents = onOpenIncidents,
4648
)
4749
}
@@ -60,6 +62,7 @@ internal fun AppTopBar(
6062
isAccountExpired: Boolean = false,
6163
openAuthentication: () -> Unit = {},
6264
@DrawableRes disasterIconResId: Int = 0,
65+
enableIncidentSelect: Boolean = false,
6366
onOpenIncidents: (() -> Unit)? = null,
6467
) {
6568
val t = LocalAppTranslator.current
@@ -86,6 +89,7 @@ internal fun AppTopBar(
8689
title = title,
8790
contentDescription = t("nav.change_incident"),
8891
isLoading = isAppHeaderLoading,
92+
enabled = enableIncidentSelect,
8993
)
9094
}
9195
},

core/common/src/main/java/com/crisiscleanup/core/common/sync/Syncer.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ interface SyncPuller {
5454
interface SyncPusher {
5555
fun appPushWorksite(worksiteId: Long, scheduleMediaSync: Boolean = false)
5656
suspend fun syncPushWorksitesAsync(): Deferred<SyncResult>
57-
fun stopPushWorksites()
5857
suspend fun syncPushMedia(): SyncResult
5958
suspend fun syncPushWorksites(): SyncResult
6059

0 commit comments

Comments
 (0)