Skip to content

Commit b15d0ab

Browse files
committed
refactor: make error and loading reusable components
1 parent 155d7a5 commit b15d0ab

File tree

9 files changed

+84
-71
lines changed

9 files changed

+84
-71
lines changed

dataconnect/app/src/main/java/com/google/firebase/example/dataconnect/feature/actordetail/ActorDetailScreen.kt

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ import androidx.lifecycle.viewmodel.compose.viewModel
3434
import coil.compose.AsyncImage
3535
import com.google.firebase.dataconnect.movies.GetActorByIdQuery
3636
import com.google.firebase.example.dataconnect.R
37-
import com.google.firebase.example.dataconnect.feature.moviedetail.ErrorMessage
37+
import com.google.firebase.example.dataconnect.ui.components.ErrorCard
38+
import com.google.firebase.example.dataconnect.ui.components.LoadingScreen
3839
import com.google.firebase.example.dataconnect.ui.components.Movie
3940
import com.google.firebase.example.dataconnect.ui.components.MoviesList
4041

@@ -48,17 +49,10 @@ fun ActorDetailScreen(
4849
Scaffold { innerPadding ->
4950
when (uiState) {
5051
is ActorDetailUIState.Error -> {
51-
ErrorMessage((uiState as ActorDetailUIState.Error).errorMessage)
52+
ErrorCard((uiState as ActorDetailUIState.Error).errorMessage)
5253
}
5354

54-
ActorDetailUIState.Loading -> {
55-
Box(
56-
contentAlignment = Alignment.Center,
57-
modifier = Modifier.fillMaxSize()
58-
) {
59-
CircularProgressIndicator()
60-
}
61-
}
55+
ActorDetailUIState.Loading -> LoadingScreen()
6256

6357
is ActorDetailUIState.Success -> {
6458
val ui = uiState as ActorDetailUIState.Success
@@ -88,7 +82,7 @@ fun ActorInformation(
8882
onFavoriteToggled: (newValue: Boolean) -> Unit
8983
) {
9084
if (actor == null) {
91-
ErrorMessage(stringResource(R.string.error_movie_not_found))
85+
ErrorCard(stringResource(R.string.error_movie_not_found))
9286
} else {
9387
Column(
9488
modifier = modifier

dataconnect/app/src/main/java/com/google/firebase/example/dataconnect/feature/genredetail/GenreDetailScreen.kt

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
package com.google.firebase.example.dataconnect.feature.genredetail
22

3-
import androidx.compose.foundation.layout.Box
43
import androidx.compose.foundation.layout.Column
5-
import androidx.compose.foundation.layout.fillMaxSize
64
import androidx.compose.foundation.layout.padding
75
import androidx.compose.foundation.rememberScrollState
86
import androidx.compose.foundation.verticalScroll
9-
import androidx.compose.material3.CircularProgressIndicator
107
import androidx.compose.material3.MaterialTheme
118
import androidx.compose.material3.Text
129
import androidx.compose.runtime.Composable
1310
import androidx.compose.runtime.collectAsState
1411
import androidx.compose.runtime.getValue
15-
import androidx.compose.ui.Alignment
1612
import androidx.compose.ui.Modifier
1713
import androidx.compose.ui.res.stringResource
1814
import androidx.compose.ui.unit.dp
1915
import androidx.lifecycle.viewmodel.compose.viewModel
2016
import com.google.firebase.example.dataconnect.R
17+
import com.google.firebase.example.dataconnect.ui.components.ErrorCard
18+
import com.google.firebase.example.dataconnect.ui.components.LoadingScreen
2119
import com.google.firebase.example.dataconnect.ui.components.Movie
2220
import com.google.firebase.example.dataconnect.ui.components.MoviesList
2321

@@ -36,29 +34,20 @@ fun GenreDetailScreen(
3634
uiState: GenreDetailUIState
3735
) {
3836
when (uiState) {
39-
GenreDetailUIState.Loading -> {
40-
Box(
41-
contentAlignment = Alignment.Center,
42-
modifier = Modifier.fillMaxSize()
43-
) {
44-
CircularProgressIndicator()
45-
}
46-
}
37+
GenreDetailUIState.Loading -> LoadingScreen()
4738

48-
is GenreDetailUIState.Error -> {
49-
Text(uiState.errorMessage)
50-
}
39+
is GenreDetailUIState.Error -> ErrorCard(uiState.errorMessage)
5140

5241
is GenreDetailUIState.Success -> {
5342
val scrollState = rememberScrollState()
5443
Column(
5544
modifier = Modifier
56-
.padding(16.dp)
5745
.verticalScroll(scrollState)
5846
) {
5947
Text(
6048
text = stringResource(R.string.title_genre_detail, uiState.genreName),
61-
style = MaterialTheme.typography.headlineLarge
49+
style = MaterialTheme.typography.headlineLarge,
50+
modifier = Modifier.padding(8.dp)
6251
)
6352
MoviesList(
6453
listTitle = stringResource(R.string.title_most_popular),

dataconnect/app/src/main/java/com/google/firebase/example/dataconnect/feature/moviedetail/MovieDetailScreen.kt

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ import com.google.firebase.dataconnect.movies.GetMovieByIdQuery
4747
import com.google.firebase.example.dataconnect.R
4848
import com.google.firebase.example.dataconnect.ui.components.Actor
4949
import com.google.firebase.example.dataconnect.ui.components.ActorsList
50+
import com.google.firebase.example.dataconnect.ui.components.ErrorCard
51+
import com.google.firebase.example.dataconnect.ui.components.LoadingScreen
5052
import com.google.firebase.example.dataconnect.ui.components.ReviewCard
5153

5254
@Composable
@@ -60,17 +62,10 @@ fun MovieDetailScreen(
6062
Scaffold { padding ->
6163
when (uiState) {
6264
is MovieDetailUIState.Error -> {
63-
ErrorMessage((uiState as MovieDetailUIState.Error).errorMessage)
65+
ErrorCard((uiState as MovieDetailUIState.Error).errorMessage)
6466
}
6567

66-
MovieDetailUIState.Loading -> {
67-
Box(
68-
contentAlignment = Alignment.Center,
69-
modifier = Modifier.fillMaxSize()
70-
) {
71-
CircularProgressIndicator()
72-
}
73-
}
68+
MovieDetailUIState.Loading -> LoadingScreen()
7469

7570
is MovieDetailUIState.Success -> {
7671
val ui = uiState as MovieDetailUIState.Success
@@ -130,7 +125,7 @@ fun MovieInformation(
130125
onFavoriteToggled: (newValue: Boolean) -> Unit
131126
) {
132127
if (movie == null) {
133-
ErrorMessage(stringResource(R.string.error_movie_not_found))
128+
ErrorCard(stringResource(R.string.error_movie_not_found))
134129
} else {
135130
Column(
136131
modifier = modifier
@@ -282,10 +277,3 @@ fun UserReviews(
282277
}
283278
}
284279
}
285-
286-
@Composable
287-
fun ErrorMessage(
288-
message: String
289-
) {
290-
Text(message)
291-
}

dataconnect/app/src/main/java/com/google/firebase/example/dataconnect/feature/movies/MoviesScreen.kt

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
11
package com.google.firebase.example.dataconnect.feature.movies
22

3-
import androidx.compose.foundation.layout.Box
43
import androidx.compose.foundation.layout.Column
54
import androidx.compose.foundation.layout.Spacer
6-
import androidx.compose.foundation.layout.fillMaxSize
75
import androidx.compose.foundation.layout.height
8-
import androidx.compose.foundation.layout.padding
96
import androidx.compose.foundation.rememberScrollState
107
import androidx.compose.foundation.verticalScroll
11-
import androidx.compose.material3.CircularProgressIndicator
12-
import androidx.compose.material3.Text
138
import androidx.compose.runtime.Composable
149
import androidx.compose.runtime.collectAsState
1510
import androidx.compose.runtime.getValue
16-
import androidx.compose.ui.Alignment
1711
import androidx.compose.ui.Modifier
1812
import androidx.compose.ui.res.stringResource
1913
import androidx.compose.ui.unit.dp
2014
import androidx.lifecycle.viewmodel.compose.viewModel
2115
import com.google.firebase.example.dataconnect.R
16+
import com.google.firebase.example.dataconnect.ui.components.ErrorCard
17+
import com.google.firebase.example.dataconnect.ui.components.LoadingScreen
2218
import com.google.firebase.example.dataconnect.ui.components.Movie
2319
import com.google.firebase.example.dataconnect.ui.components.MoviesList
2420

@@ -37,17 +33,8 @@ fun MoviesScreen(
3733
onMovieClicked: (movie: String) -> Unit
3834
) {
3935
when (uiState) {
40-
MoviesUIState.Loading -> {
41-
Box(
42-
contentAlignment = Alignment.Center,
43-
modifier = Modifier.fillMaxSize()
44-
) {
45-
CircularProgressIndicator()
46-
}
47-
}
48-
is MoviesUIState.Error -> {
49-
Text(uiState.errorMessage)
50-
}
36+
MoviesUIState.Loading -> LoadingScreen()
37+
is MoviesUIState.Error -> ErrorCard(uiState.errorMessage)
5138
is MoviesUIState.Success -> {
5239
val scrollState = rememberScrollState()
5340
Column(

dataconnect/app/src/main/java/com/google/firebase/example/dataconnect/feature/profile/ProfileScreen.kt

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import com.google.firebase.dataconnect.movies.GetUserByIdQuery
2424
import com.google.firebase.example.dataconnect.R
2525
import com.google.firebase.example.dataconnect.ui.components.Actor
2626
import com.google.firebase.example.dataconnect.ui.components.ActorsList
27+
import com.google.firebase.example.dataconnect.ui.components.ErrorCard
28+
import com.google.firebase.example.dataconnect.ui.components.LoadingScreen
2729
import com.google.firebase.example.dataconnect.ui.components.Movie
2830
import com.google.firebase.example.dataconnect.ui.components.MoviesList
2931
import com.google.firebase.example.dataconnect.ui.components.ReviewCard
@@ -35,7 +37,7 @@ fun ProfileScreen(
3537
val uiState by profileViewModel.uiState.collectAsState()
3638
when (uiState) {
3739
is ProfileUIState.Error -> {
38-
Text((uiState as ProfileUIState.Error).errorMessage)
40+
ErrorCard((uiState as ProfileUIState.Error).errorMessage)
3941
}
4042

4143
is ProfileUIState.AuthState -> {
@@ -63,14 +65,7 @@ fun ProfileScreen(
6365
)
6466
}
6567

66-
ProfileUIState.Loading -> {
67-
Box(
68-
contentAlignment = Alignment.Center,
69-
modifier = Modifier.fillMaxSize()
70-
) {
71-
CircularProgressIndicator()
72-
}
73-
}
68+
ProfileUIState.Loading -> LoadingScreen()
7469
}
7570
}
7671

dataconnect/app/src/main/java/com/google/firebase/example/dataconnect/ui/components/ActorsList.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.google.firebase.example.dataconnect.ui.components
33
import androidx.compose.foundation.clickable
44
import androidx.compose.foundation.layout.Column
55
import androidx.compose.foundation.layout.Spacer
6+
import androidx.compose.foundation.layout.fillMaxWidth
67
import androidx.compose.foundation.layout.height
78
import androidx.compose.foundation.layout.padding
89
import androidx.compose.foundation.layout.size
@@ -44,6 +45,7 @@ fun ActorsList(
4445
) {
4546
Column(
4647
modifier = modifier.padding(horizontal = 16.dp)
48+
.fillMaxWidth()
4749
) {
4850
Text(
4951
text = listTitle,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.google.firebase.example.dataconnect.ui.components
2+
3+
import androidx.compose.foundation.layout.fillMaxWidth
4+
import androidx.compose.foundation.layout.padding
5+
import androidx.compose.material3.Card
6+
import androidx.compose.material3.CardDefaults
7+
import androidx.compose.material3.MaterialTheme
8+
import androidx.compose.material3.Text
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.tooling.preview.Preview
12+
import androidx.compose.ui.unit.dp
13+
14+
@Composable
15+
fun ErrorCard(
16+
errorMessage: String
17+
) {
18+
Card(
19+
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.errorContainer),
20+
modifier = Modifier.padding(16.dp)
21+
.fillMaxWidth()
22+
) {
23+
Text(
24+
text = errorMessage,
25+
modifier = Modifier.padding(16.dp)
26+
.fillMaxWidth()
27+
)
28+
}
29+
}
30+
31+
@Composable
32+
@Preview
33+
fun ErrorCardPreview() {
34+
ErrorCard("Something went terribly wrong :(")
35+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.google.firebase.example.dataconnect.ui.components
2+
3+
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.fillMaxSize
5+
import androidx.compose.material3.CircularProgressIndicator
6+
import androidx.compose.runtime.Composable
7+
import androidx.compose.ui.Alignment
8+
import androidx.compose.ui.Modifier
9+
10+
/**
11+
* A screen that displays a loading spinner in the center.
12+
*/
13+
@Composable
14+
fun LoadingScreen() {
15+
Box(
16+
contentAlignment = Alignment.Center,
17+
modifier = Modifier.fillMaxSize()
18+
) {
19+
CircularProgressIndicator()
20+
}
21+
}

dataconnect/app/src/main/java/com/google/firebase/example/dataconnect/ui/components/MoviesList.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.google.firebase.example.dataconnect.ui.components
33
import androidx.compose.foundation.clickable
44
import androidx.compose.foundation.layout.Column
55
import androidx.compose.foundation.layout.aspectRatio
6+
import androidx.compose.foundation.layout.fillMaxWidth
67
import androidx.compose.foundation.layout.padding
78
import androidx.compose.foundation.layout.sizeIn
89
import androidx.compose.foundation.lazy.LazyRow
@@ -40,6 +41,7 @@ fun MoviesList(
4041
) {
4142
Column(
4243
modifier = modifier.padding(horizontal = 16.dp)
44+
.fillMaxWidth()
4345
) {
4446
Text(
4547
text = listTitle,

0 commit comments

Comments
 (0)