Skip to content

Commit 830b3a4

Browse files
Let API shrink images
1 parent 4ab211b commit 830b3a4

File tree

4 files changed

+55
-5
lines changed

4 files changed

+55
-5
lines changed

app/src/main/kotlin/app/fyreplace/fyreplace/ui/screens/SettingsScreen.kt

+2
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@ fun SettingsScreen(viewModel: SettingsViewModel = hiltViewModel()) {
4545
.verticalScroll(rememberScrollState())
4646
) {
4747
val currentUser by viewModel.currentUser.collectAsStateWithLifecycle()
48+
val isLoadingAvatar by viewModel.isLoadingAvatar.collectAsStateWithLifecycle()
4849

4950
Section(stringResource(R.string.settings_profile_header)) {
5051
AvatarListItem(
5152
user = currentUser,
53+
isLoading = isLoadingAvatar,
5254
onUpdateAvatar = viewModel::updateAvatar,
5355
onRemoveAvatar = viewModel::removeAvatar
5456
)

app/src/main/kotlin/app/fyreplace/fyreplace/ui/views/settings/AvatarListItem.kt

+41-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.size
99
import androidx.compose.material.icons.Icons
1010
import androidx.compose.material.icons.outlined.Delete
1111
import androidx.compose.material.icons.outlined.Upload
12+
import androidx.compose.material3.CircularProgressIndicator
1213
import androidx.compose.material3.DropdownMenu
1314
import androidx.compose.material3.DropdownMenuItem
1415
import androidx.compose.material3.Icon
@@ -19,16 +20,19 @@ import androidx.compose.runtime.getValue
1920
import androidx.compose.runtime.mutableStateOf
2021
import androidx.compose.runtime.remember
2122
import androidx.compose.runtime.setValue
23+
import androidx.compose.ui.Alignment
2224
import androidx.compose.ui.Modifier
2325
import androidx.compose.ui.draganddrop.mimeTypes
2426
import androidx.compose.ui.graphics.Color
2527
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
2628
import androidx.compose.ui.platform.LocalHapticFeedback
2729
import androidx.compose.ui.res.stringResource
30+
import androidx.compose.ui.tooling.preview.Preview
2831
import androidx.compose.ui.unit.dp
2932
import app.fyreplace.api.data.User
3033
import app.fyreplace.fyreplace.R
3134
import app.fyreplace.fyreplace.extensions.activity
35+
import app.fyreplace.fyreplace.fakes.placeholder
3236
import app.fyreplace.fyreplace.ui.views.Avatar
3337
import java.io.File
3438
import java.time.format.DateTimeFormatter
@@ -38,6 +42,7 @@ import java.time.format.FormatStyle
3842
@Composable
3943
fun AvatarListItem(
4044
user: User?,
45+
isLoading: Boolean,
4146
onUpdateAvatar: (File) -> Unit,
4247
onRemoveAvatar: () -> Unit
4348
) {
@@ -79,7 +84,20 @@ fun AvatarListItem(
7984
}
8085
)
8186
},
82-
leadingContent = { Avatar(user = user, modifier = Modifier.size(56.dp)) },
87+
leadingContent = {
88+
val modifier = Modifier.size(56.dp)
89+
90+
if (isLoading) {
91+
Box(
92+
contentAlignment = Alignment.Center,
93+
modifier = modifier
94+
) {
95+
CircularProgressIndicator()
96+
}
97+
} else {
98+
Avatar(user = user, modifier = modifier)
99+
}
100+
},
83101
modifier = Modifier.combinedClickable(
84102
onClick = ::selectImage,
85103
onLongClick = {
@@ -112,3 +130,25 @@ fun AvatarListItem(
112130
}
113131
}
114132
}
133+
134+
@Preview
135+
@Composable
136+
fun AvatarListItemPreview() {
137+
AvatarListItem(
138+
user = User.placeholder,
139+
isLoading = false,
140+
onUpdateAvatar = {},
141+
onRemoveAvatar = {}
142+
)
143+
}
144+
145+
@Preview
146+
@Composable
147+
fun AvatarListItemLoadingPreview() {
148+
AvatarListItem(
149+
user = User.placeholder,
150+
isLoading = true,
151+
onUpdateAvatar = {},
152+
onRemoveAvatar = {}
153+
)
154+
}

app/src/main/kotlin/app/fyreplace/fyreplace/viewmodels/screens/SettingsViewModel.kt

+10-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class SettingsViewModel @Inject constructor(
3030
) : ApiViewModelBase(eventBus, storeResolver) {
3131
val currentUser: StateFlow<User?> =
3232
state.getStateFlow(::currentUser.name, null)
33+
val isLoadingAvatar: StateFlow<Boolean> =
34+
state.getStateFlow(::isLoadingAvatar.name, false)
3335

3436
init {
3537
viewModelScope.launch {
@@ -46,6 +48,8 @@ class SettingsViewModel @Inject constructor(
4648
}
4749

4850
fun updateAvatar(file: File) = call(apiResolver::users) {
51+
state[::isLoadingAvatar.name] = true
52+
4953
val avatar = setCurrentUserAvatar(file).failWith {
5054
when (it.code) {
5155
413 -> Event.Failure(
@@ -60,9 +64,13 @@ class SettingsViewModel @Inject constructor(
6064

6165
else -> Event.Failure()
6266
}
63-
} ?: return@call
67+
}
6468

65-
state[::currentUser.name] = currentUser.value?.copy(avatar = avatar)
69+
state[::isLoadingAvatar.name] = false
70+
71+
if (avatar != null) {
72+
state[::currentUser.name] = currentUser.value?.copy(avatar = avatar)
73+
}
6674
}
6775

6876
fun removeAvatar() = call(apiResolver::users) {

app/src/main/res/values/strings.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
<string name="settings_about_privacy_policy">Privacy policy</string>
2929
<string name="settings_about_source_code">Source code</string>
3030
<string name="settings_error_413_title">File too large</string>
31-
<string name="settings_error_413_message">This file is too heavy; please select a file under 1M.</string>
31+
<string name="settings_error_413_message">Uploaded files can only go up to 10M.</string>
3232
<string name="settings_error_415_title">Unsupported file format</string>
33-
<string name="settings_error_415_message">This file you have selected is not supported.</string>
33+
<string name="settings_error_415_message">The type of file you have selected is not supported.</string>
3434

3535
<string name="account_environment_main">Production server</string>
3636
<string name="account_environment_dev">Testing server</string>

0 commit comments

Comments
 (0)