From ee9bbaf2d821b660236f63992f42ef90a223c325 Mon Sep 17 00:00:00 2001 From: Luna <46259660+LunaticHacker@users.noreply.github.com> Date: Thu, 14 Jul 2022 23:23:12 +0530 Subject: [PATCH] Add api settings (#183) * start working on settings page * functionality is done Now we just need to make this pretty * add relevant modifiers * fix lint * some refactoring * add todos --- app/src/main/java/com/jerboa/MainActivity.kt | 13 + app/src/main/java/com/jerboa/api/Http.kt | 21 ++ .../java/com/jerboa/datatypes/api/Person.kt | 2 +- .../common/{TextFields.kt => InputFields.kt} | 74 +++++ .../ui/components/common/PictrsImage.kt | 5 +- .../com/jerboa/ui/components/home/Home.kt | 13 + .../jerboa/ui/components/home/HomeActivity.kt | 8 + .../ui/components/post/create/CreatePost.kt | 5 +- .../jerboa/ui/components/settings/Settings.kt | 290 ++++++++++++++++++ .../components/settings/SettingsActivity.kt | 55 ++++ .../components/settings/SettingsViewModel.kt | 33 ++ 11 files changed, 515 insertions(+), 4 deletions(-) rename app/src/main/java/com/jerboa/ui/components/common/{TextFields.kt => InputFields.kt} (89%) create mode 100644 app/src/main/java/com/jerboa/ui/components/settings/Settings.kt create mode 100644 app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt create mode 100644 app/src/main/java/com/jerboa/ui/components/settings/SettingsViewModel.kt diff --git a/app/src/main/java/com/jerboa/MainActivity.kt b/app/src/main/java/com/jerboa/MainActivity.kt index 9962a9ded..757ece879 100644 --- a/app/src/main/java/com/jerboa/MainActivity.kt +++ b/app/src/main/java/com/jerboa/MainActivity.kt @@ -47,6 +47,8 @@ import com.jerboa.ui.components.private_message.PrivateMessageReplyActivity import com.jerboa.ui.components.report.CreateReportViewModel import com.jerboa.ui.components.report.comment.CreateCommentReportActivity import com.jerboa.ui.components.report.post.CreatePostReportActivity +import com.jerboa.ui.components.settings.SettingsActivity +import com.jerboa.ui.components.settings.SettingsViewModel import com.jerboa.ui.theme.JerboaTheme class JerboaApplication : Application() { @@ -69,6 +71,7 @@ class MainActivity : ComponentActivity() { private val commentEditViewModel by viewModels() private val postEditViewModel by viewModels() private val createReportViewModel by viewModels() + private val settingsViewModel by viewModels() private val accountViewModel: AccountViewModel by viewModels { AccountViewModelFactory((application as JerboaApplication).repository) @@ -318,6 +321,16 @@ class MainActivity : ComponentActivity() { navController = navController, ) } + composable( + route = "settings", + ) { + SettingsActivity( + navController = navController, + accountViewModel = accountViewModel, + siteViewModel = siteViewModel, + settingsViewModel = settingsViewModel + ) + } } } } diff --git a/app/src/main/java/com/jerboa/api/Http.kt b/app/src/main/java/com/jerboa/api/Http.kt index eded937c5..f6612413d 100644 --- a/app/src/main/java/com/jerboa/api/Http.kt +++ b/app/src/main/java/com/jerboa/api/Http.kt @@ -222,6 +222,11 @@ interface API { @POST("community/block") suspend fun blockCommunity(@Body form: BlockCommunity): Response + /** + * Save your user settings. + */ + @PUT("user/save_user_settings") + suspend fun saveUserSettings(@Body form: SaveUserSettings): Response /** * Upload an image. */ @@ -725,6 +730,22 @@ suspend fun blockCommunityWrapper( return blockCommunityRes } +suspend fun saveUserSettingsWrapper( + form: SaveUserSettings, + ctx: Context, +): LoginResponse? { + + var saveUserSettingsResponse: LoginResponse? = null + val api = API.getInstance() + + try { + saveUserSettingsResponse = retrofitErrorHandler(api.saveUserSettings(form)) + } catch (e: Exception) { + toastException(ctx = ctx, error = e) + } + return saveUserSettingsResponse +} + suspend fun uploadPictrsImage(account: Account, imageIs: InputStream, ctx: Context): String? { var imageUrl: String? = null val api = API.getInstance() diff --git a/app/src/main/java/com/jerboa/datatypes/api/Person.kt b/app/src/main/java/com/jerboa/datatypes/api/Person.kt index 536c212d3..e56c6929a 100644 --- a/app/src/main/java/com/jerboa/datatypes/api/Person.kt +++ b/app/src/main/java/com/jerboa/datatypes/api/Person.kt @@ -55,7 +55,7 @@ data class SaveUserSettings( val show_bot_accounts: Boolean?, val show_read_posts: Boolean?, val show_new_post_notifs: Boolean?, - val auth: String?, + val auth: String, ) data class ChangePassword( diff --git a/app/src/main/java/com/jerboa/ui/components/common/TextFields.kt b/app/src/main/java/com/jerboa/ui/components/common/InputFields.kt similarity index 89% rename from app/src/main/java/com/jerboa/ui/components/common/TextFields.kt rename to app/src/main/java/com/jerboa/ui/components/common/InputFields.kt index 34b67fb29..fe1d53cae 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/TextFields.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/InputFields.kt @@ -15,6 +15,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester @@ -33,6 +34,7 @@ import com.jerboa.appendMarkdownImage import com.jerboa.db.Account import com.jerboa.imageInputStreamFromUri import com.jerboa.ui.theme.MEDIUM_PADDING +import com.jerboa.ui.theme.SMALL_PADDING import com.jerboa.ui.theme.XXL_PADDING import com.jerboa.ui.theme.muted import dev.jeziellago.compose.markdowntext.MarkdownText @@ -513,6 +515,78 @@ fun MarkdownHelperBar( } } +@Composable +fun MyCheckBox( + checked: Boolean, + enabled: Boolean = true, + label: String, + onCheckedChange: (Boolean) -> Unit +) { + Row( + modifier = Modifier.padding(SMALL_PADDING), + verticalAlignment = Alignment.CenterVertically + ) { + Text(text = label) + Checkbox( + checked = checked, + onCheckedChange = onCheckedChange, + enabled = enabled, + ) + } +} + +// https://stackoverflow.com/a/67111599 +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun MyDropDown( + suggestions: List, + onValueChange: (Int) -> Unit, + initialValue: Int, + label: String +) { + var expanded by remember { mutableStateOf(false) } + var selectedText by remember { mutableStateOf(suggestions[initialValue]) } + + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { + expanded = !expanded + } + ) { + TextField( + readOnly = true, + value = selectedText, + modifier = Modifier.fillMaxWidth(), + onValueChange = { }, + label = { Text(label) }, + trailingIcon = { + ExposedDropdownMenuDefaults.TrailingIcon( + expanded = expanded + ) + }, + colors = ExposedDropdownMenuDefaults.textFieldColors() + ) + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { + expanded = false + } + ) { + suggestions.forEach { selectionOption -> + DropdownMenuItem( + onClick = { + selectedText = selectionOption + expanded = false + onValueChange(suggestions.indexOf(selectedText)) + } + ) { + Text(text = selectionOption) + } + } + } + } +} + @Preview @Composable fun ReplyMarkdownBarPreview() { diff --git a/app/src/main/java/com/jerboa/ui/components/common/PictrsImage.kt b/app/src/main/java/com/jerboa/ui/components/common/PictrsImage.kt index 9f23c916f..6ac6638c8 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/PictrsImage.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/PictrsImage.kt @@ -141,6 +141,7 @@ fun PickImage( onPickedImage: (image: Uri) -> Unit, image: Uri? = null, showImage: Boolean = true, + horizontalAlignment: Alignment.Horizontal = Alignment.Start ) { val ctx = LocalContext.current var imageUri by remember { @@ -168,8 +169,8 @@ fun PickImage( onPickedImage(uri!!) } Column( - modifier = modifier.fillMaxWidth(), - horizontalAlignment = Alignment.End + modifier = modifier, + horizontalAlignment = horizontalAlignment ) { OutlinedButton(onClick = { launcher.launch("image/*") diff --git a/app/src/main/java/com/jerboa/ui/components/home/Home.kt b/app/src/main/java/com/jerboa/ui/components/home/Home.kt index 2761c26d5..a98c170ca 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/Home.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/Home.kt @@ -47,6 +47,7 @@ fun Drawer( onClickProfile: () -> Unit, onClickInbox: () -> Unit, onClickSaved: () -> Unit, + onClickSettings: () -> Unit, unreadCounts: GetUnreadCountResponse?, ) { var showAccountAddMode by rememberSaveable { mutableStateOf(false) } @@ -71,6 +72,7 @@ fun Drawer( onClickProfile = onClickProfile, onClickInbox = onClickInbox, onClickSaved = onClickSaved, + onClickSettings = onClickSettings ) } @@ -86,6 +88,7 @@ fun DrawerContent( onClickProfile: () -> Unit, onClickInbox: () -> Unit, onClickSaved: () -> Unit, + onClickSettings: () -> Unit, follows: List?, unreadCounts: GetUnreadCountResponse?, ) { @@ -111,6 +114,7 @@ fun DrawerContent( onClickSaved = onClickSaved, follows = follows, unreadCounts = unreadCounts, + onClickSettings = onClickSettings ) } } @@ -121,6 +125,7 @@ fun DrawerItemsMain( onClickSaved: () -> Unit, onClickProfile: () -> Unit, onClickInbox: () -> Unit, + onClickSettings: () -> Unit, onClickListingType: (ListingType) -> Unit, onCommunityClick: (community: CommunitySafe) -> Unit, unreadCounts: GetUnreadCountResponse? = null, @@ -181,6 +186,13 @@ fun DrawerItemsMain( iconBadgeCount = totalUnreads, ) } + item { + IconAndTextDrawerItem( + text = "Settings", + icon = Icons.Default.Settings, + onClick = onClickSettings, + ) + } item { Divider() } @@ -213,6 +225,7 @@ fun DrawerItemsMainPreview() { onClickInbox = {}, onCommunityClick = {}, onClickSaved = {}, + onClickSettings = {} ) } diff --git a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt index 4e9adcf23..511a476a5 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt @@ -40,6 +40,7 @@ import com.jerboa.ui.components.post.edit.postEditClickWrapper import com.jerboa.ui.components.post.postClickWrapper import com.jerboa.ui.components.report.CreateReportViewModel import com.jerboa.ui.components.report.postReportClickWrapper +import com.jerboa.ui.components.settings.settingsClickWrapper import kotlinx.coroutines.CoroutineScope @Composable @@ -404,6 +405,13 @@ fun MainDrawer( ) closeDrawer(scope, scaffoldState) }, + onClickSettings = { + settingsClickWrapper( + navController = navController, + account = account + ) + closeDrawer(scope, scaffoldState) + }, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/post/create/CreatePost.kt b/app/src/main/java/com/jerboa/ui/components/post/create/CreatePost.kt index 4a7cbcdb6..c4beb2728 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/create/CreatePost.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/create/CreatePost.kt @@ -12,6 +12,7 @@ import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material.icons.filled.Close import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.Preview @@ -152,7 +153,9 @@ fun CreatePostBody( item { PickImage( onPickedImage = onPickedImage, - image = image + image = image, + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.End ) } // TODO change this to reply text field at some point diff --git a/app/src/main/java/com/jerboa/ui/components/settings/Settings.kt b/app/src/main/java/com/jerboa/ui/components/settings/Settings.kt new file mode 100644 index 000000000..fd728137c --- /dev/null +++ b/app/src/main/java/com/jerboa/ui/components/settings/Settings.kt @@ -0,0 +1,290 @@ +package com.jerboa.ui.components.settings + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.Close +import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.tooling.preview.Preview +import androidx.navigation.NavController +import androidx.navigation.compose.rememberNavController +import com.jerboa.api.uploadPictrsImage +import com.jerboa.datatypes.api.SaveUserSettings +import com.jerboa.db.Account +import com.jerboa.imageInputStreamFromUri +import com.jerboa.ui.components.common.* +import com.jerboa.ui.components.home.SiteViewModel +import com.jerboa.ui.theme.* +import kotlinx.coroutines.launch + +fun settingsClickWrapper( + navController: NavController, + account: Account? +) { + account.also { + navController.navigate(route = "settings") + } +} + +@Composable +fun SettingsHeader( + navController: NavController = rememberNavController(), +) { + + val backgroundColor = MaterialTheme.colors.primarySurface + val contentColor = contentColorFor(backgroundColor) + + TopAppBar( + title = { + Text( + text = "Settings", + ) + }, + backgroundColor = backgroundColor, + contentColor = contentColor, + elevation = APP_BAR_ELEVATION, + navigationIcon = { + IconButton( + onClick = { + navController.popBackStack() + } + ) { + Icon( + Icons.Filled.ArrowBack, + contentDescription = "Back" + ) + } + }, + ) +} + +@Composable +fun SettingsTextField( + label: String, + text: String, + onValueChange: (String) -> Unit +) { + Column( + modifier = Modifier.padding(SMALL_PADDING) + ) { + Text(text = label) + OutlinedTextField( + value = text, + onValueChange = onValueChange, + modifier = Modifier.fillMaxWidth(), + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy( + capitalization = KeyboardCapitalization.None, + keyboardType = KeyboardType.Text, + autoCorrect = false, + ) + ) + } +} + +@Composable +fun ImageWithClose(onClick: () -> Unit, composable: @Composable() () -> Unit) { + Box(contentAlignment = Alignment.TopEnd) { + composable() + IconButton(onClick = onClick) { + Icon(imageVector = Icons.Default.Close, contentDescription = "Remove Current Avatar") + } + } +} + +@Composable +fun SettingsForm( + settingsViewModel: SettingsViewModel, + siteViewModel: SiteViewModel, + account: Account?, + onClickSave: (form: SaveUserSettings) -> Unit, +) { + val luv = siteViewModel.siteRes?.my_user?.local_user_view + val scope = rememberCoroutineScope() + val ctx = LocalContext.current + var displayName by rememberSaveable { mutableStateOf(luv?.person?.display_name.orEmpty()) } + var bio by rememberSaveable { mutableStateOf(luv?.person?.bio.orEmpty()) } + var email by rememberSaveable { mutableStateOf(luv?.local_user?.email.orEmpty()) } + var matrixUserId by rememberSaveable { mutableStateOf(luv?.person?.matrix_user_id.orEmpty()) } + val theme by rememberSaveable { mutableStateOf(luv?.local_user?.theme.orEmpty()) } + val lang by rememberSaveable { mutableStateOf(luv?.local_user?.lang.orEmpty()) } + var avatar by rememberSaveable { mutableStateOf(luv?.person?.avatar.orEmpty()) } + var banner by rememberSaveable { mutableStateOf(luv?.person?.banner.orEmpty()) } + var defaultSortType by rememberSaveable { mutableStateOf(luv?.local_user?.default_sort_type) } + var defaultListingType by rememberSaveable { mutableStateOf(luv?.local_user?.default_listing_type) } + var showAvatars by rememberSaveable { mutableStateOf(luv?.local_user?.show_avatars) } + var showNsfw by rememberSaveable { mutableStateOf(luv?.local_user?.show_nsfw ?: false) } + var showScores by rememberSaveable { mutableStateOf(luv?.local_user?.show_scores) } + var showBotAccount by rememberSaveable { mutableStateOf(luv?.local_user?.show_bot_accounts) } + var botAccount by rememberSaveable { mutableStateOf(luv?.person?.bot_account) } + var showReadPosts by rememberSaveable { mutableStateOf(luv?.local_user?.show_read_posts) } + var showNewPostNotifs by rememberSaveable { mutableStateOf(luv?.local_user?.show_new_post_notifs) } + var sendNotificationsToEmail by rememberSaveable { mutableStateOf(luv?.local_user?.send_notifications_to_email) } + val form = SaveUserSettings( + display_name = displayName, + bio = bio, + email = email, + auth = account?.jwt ?: "", + avatar = avatar, + banner = banner, + matrix_user_id = matrixUserId, + lang = lang, + bot_account = botAccount, + default_sort_type = defaultSortType, + send_notifications_to_email = sendNotificationsToEmail, + show_avatars = showAvatars, + show_bot_accounts = showBotAccount, + show_nsfw = showNsfw, + default_listing_type = defaultListingType, + show_new_post_notifs = showNewPostNotifs, + show_read_posts = showReadPosts, + theme = theme, + show_scores = showScores + ) + Column( + modifier = Modifier + .padding(SMALL_PADDING) + .verticalScroll(rememberScrollState()), + verticalArrangement = Arrangement.spacedBy(SMALL_PADDING) + ) { + SettingsTextField( + label = "Display Name", + text = displayName, + onValueChange = { displayName = it } + ) + // Todo: Use MarkdownField + SettingsTextField( + label = "Bio", + text = bio, + onValueChange = { bio = it } + ) + SettingsTextField( + label = "Email", + text = email, + onValueChange = { email = it } + ) + SettingsTextField( + label = "Matrix User", + text = matrixUserId, + onValueChange = { matrixUserId = it } + ) + Text(text = "Avatar") + if (avatar.isNotEmpty()) { + ImageWithClose(onClick = { avatar = "" }) { + LargerCircularIcon(icon = avatar) + } + } else { + PickImage(onPickedImage = { uri -> + val imageIs = imageInputStreamFromUri(ctx, uri) + scope.launch { + account?.also { acct -> + avatar = uploadPictrsImage(acct, imageIs, ctx).orEmpty() + } + } + }, showImage = false) + } + Text(text = "Banner") + if (banner.isNotEmpty()) { + ImageWithClose(onClick = { banner = "" }) { + PictrsBannerImage(url = banner) + } + } else { + PickImage(onPickedImage = { uri -> + val imageIs = imageInputStreamFromUri(ctx, uri) + scope.launch { + account?.also { acct -> + banner = uploadPictrsImage(acct, imageIs, ctx).orEmpty() + } + } + }, showImage = false) + } + // Todo Update AppDb to save new sort and listing_type settings. + MyDropDown( + suggestions = listOf("All", "Local", "Subscribed"), + onValueChange = { defaultListingType = it }, defaultListingType ?: 0, + label = "Default Listing Type" + ) + MyDropDown( + suggestions = listOf( + "Active", + "Hot", + "New", + "TopDay", + "TopWeek", + "TopMonth", + "TopYear", + "TopAll", + "MostComments", + "NewComments" + ), + onValueChange = { defaultSortType = it }, defaultSortType ?: 0, + label = "Default Sort Type" + ) + + MyCheckBox( + checked = showNsfw, + label = "Show NSFW", + onCheckedChange = { showNsfw = it } + ) + MyCheckBox( + checked = showAvatars == true, + label = "Show Avatars", + onCheckedChange = { showAvatars = it } + ) + MyCheckBox( + checked = showReadPosts == true, + label = "Show Read Posts", + onCheckedChange = { showReadPosts = it } + ) + MyCheckBox( + checked = botAccount == true, + label = "Bot Account", + onCheckedChange = { botAccount = it } + ) + MyCheckBox( + checked = showBotAccount == true, + label = "Show Bot Accounts", + onCheckedChange = { showBotAccount = it } + ) + MyCheckBox( + checked = showScores == true, + label = "Show Scores", + onCheckedChange = { showScores = it } + ) + MyCheckBox( + checked = showNewPostNotifs == true, + label = "Show Notifications for New Posts", + onCheckedChange = { showNewPostNotifs = it } + ) + MyCheckBox( + enabled = email.isNotEmpty(), + checked = sendNotificationsToEmail == true, + label = "Send Notifications to Email", + onCheckedChange = { sendNotificationsToEmail = it } + ) + // Todo: Remove this + Button( + enabled = !settingsViewModel.loading, + onClick = { onClickSave(form) }, + modifier = Modifier.fillMaxWidth() + ) { + Text(text = "Save Settings") + } + } +} + +@Preview +@Composable +fun MyCheckBoxPreview() { + MyCheckBox(checked = true, label = " Test", onCheckedChange = {}) +} diff --git a/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt b/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt new file mode 100644 index 000000000..3be4ec52f --- /dev/null +++ b/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt @@ -0,0 +1,55 @@ +package com.jerboa.ui.components.settings + +import android.util.Log +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Scaffold +import androidx.compose.material.Surface +import androidx.compose.material.rememberScaffoldState +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext +import androidx.navigation.NavController +import com.jerboa.db.AccountViewModel +import com.jerboa.ui.components.common.getCurrentAccount +import com.jerboa.ui.components.home.SiteViewModel + +@Composable +fun SettingsActivity( + navController: NavController, + settingsViewModel: SettingsViewModel, + accountViewModel: AccountViewModel, + siteViewModel: SiteViewModel, +) { + Log.d("jerboa", "Got to settings activity") + + val scaffoldState = rememberScaffoldState() + val ctx = LocalContext.current + val account = getCurrentAccount(accountViewModel = accountViewModel) + + Surface(color = MaterialTheme.colors.background) { + Scaffold( + scaffoldState = scaffoldState, + topBar = { + SettingsHeader( + navController = navController, + ) + }, + content = { + account.also { + SettingsForm( + settingsViewModel, + onClickSave = { form -> + settingsViewModel.saveSettings( + form, + ctx, + siteViewModel = siteViewModel, + account = account, + ) + }, + siteViewModel = siteViewModel, + account = account, + ) + } + } + ) + } +} diff --git a/app/src/main/java/com/jerboa/ui/components/settings/SettingsViewModel.kt b/app/src/main/java/com/jerboa/ui/components/settings/SettingsViewModel.kt new file mode 100644 index 000000000..7e2bc81f9 --- /dev/null +++ b/app/src/main/java/com/jerboa/ui/components/settings/SettingsViewModel.kt @@ -0,0 +1,33 @@ +package com.jerboa.ui.components.settings + +import android.content.Context +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.jerboa.api.saveUserSettingsWrapper +import com.jerboa.datatypes.api.SaveUserSettings +import com.jerboa.db.Account +import com.jerboa.ui.components.home.SiteViewModel +import kotlinx.coroutines.launch + +class SettingsViewModel : ViewModel() { + + var loading by mutableStateOf(false) + + fun saveSettings( + form: SaveUserSettings, + ctx: Context, + siteViewModel: SiteViewModel, + account: Account? + ) { + + viewModelScope.launch { + loading = true + saveUserSettingsWrapper(form, ctx) + siteViewModel.fetchSite(account?.jwt, ctx) + loading = false + } + } +}