From 9e71d9d3b0a57d7dd85d8e15e20ead90d4259b8d Mon Sep 17 00:00:00 2001 From: 0xd9a <0xd9a@noreply.codeberg.org> Date: Sat, 20 Aug 2022 16:20:22 +0530 Subject: [PATCH] Update settings page --- app/build.gradle | 5 +- .../android/activities/SettingsActivity.java | 208 ------------------ .../android/activities/SettingsActivity.kt | 46 ++++ .../settings/FragmentSettingsCategories.kt | 73 ++++++ app/src/main/res/anim/enter.xml | 5 +- app/src/main/res/anim/exit.xml | 5 +- app/src/main/res/anim/pop_enter.xml | 5 +- app/src/main/res/anim/pop_exit.xml | 5 +- ...min_panel_settings_24.xml => ic_admin.xml} | 6 +- .../res/drawable/ic_baseline_language_24.xml | 10 - app/src/main/res/drawable/ic_language.xml | 10 + app/src/main/res/drawable/ic_shield.xml | 10 + app/src/main/res/drawable/ic_style.xml | 10 + app/src/main/res/drawable/ic_theming.xml | 10 + app/src/main/res/drawable/ic_timeline.xml | 10 + app/src/main/res/layout/activity_settings.xml | 164 +------------- .../main/res/menu/activity_main_drawer.xml | 4 +- app/src/main/res/menu/menu_compose.xml | 2 +- .../res/navigation/nav_graph_settings.xml | 116 ++++++++++ app/src/main/res/values/strings.xml | 10 + app/src/main/res/xml/pref_categories.xml | 70 ++++++ build.gradle | 3 +- 22 files changed, 395 insertions(+), 392 deletions(-) delete mode 100644 app/src/main/java/app/fedilab/android/activities/SettingsActivity.java create mode 100644 app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt create mode 100644 app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt rename app/src/main/res/drawable/{ic_baseline_admin_panel_settings_24.xml => ic_admin.xml} (63%) delete mode 100644 app/src/main/res/drawable/ic_baseline_language_24.xml create mode 100644 app/src/main/res/drawable/ic_language.xml create mode 100644 app/src/main/res/drawable/ic_shield.xml create mode 100644 app/src/main/res/drawable/ic_style.xml create mode 100644 app/src/main/res/drawable/ic_theming.xml create mode 100644 app/src/main/res/drawable/ic_timeline.xml create mode 100644 app/src/main/res/navigation/nav_graph_settings.xml create mode 100644 app/src/main/res/xml/pref_categories.xml diff --git a/app/build.gradle b/app/build.gradle index bbe373d1c..0db6e6c2f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'kotlin-android' + id 'androidx.navigation.safeargs.kotlin' } def flavor android { @@ -122,8 +123,8 @@ dependencies { implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' implementation 'androidx.lifecycle:lifecycle-livedata:2.4.1' implementation 'androidx.lifecycle:lifecycle-viewmodel:2.4.1' - implementation 'androidx.navigation:navigation-fragment:2.4.2' - implementation 'androidx.navigation:navigation-ui:2.4.2' + implementation 'androidx.navigation:navigation-fragment:2.5.1' + implementation 'androidx.navigation:navigation-ui:2.5.1' testImplementation 'junit:junit:' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' diff --git a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java deleted file mode 100644 index 44f24efea..000000000 --- a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java +++ /dev/null @@ -1,208 +0,0 @@ -package app.fedilab.android.activities; -/* Copyright 2022 Thomas Schneider - * - * This file is a part of Fedilab - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Fedilab; if not, - * see . */ - -import static app.fedilab.android.BaseMainActivity.currentAccount; - -import android.content.Intent; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; - -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; - -import com.google.gson.annotations.SerializedName; - -import java.util.Locale; - -import app.fedilab.android.R; -import app.fedilab.android.databinding.ActivitySettingsBinding; -import app.fedilab.android.helper.ThemeHelper; -import app.fedilab.android.ui.fragment.settings.FragmentComposeSettings; -import app.fedilab.android.ui.fragment.settings.FragmentInterfaceSettings; -import app.fedilab.android.ui.fragment.settings.FragmentLanguageSettings; -import app.fedilab.android.ui.fragment.settings.FragmentNotificationsSettings; -import app.fedilab.android.ui.fragment.settings.FragmentPrivacySettings; -import app.fedilab.android.ui.fragment.settings.FragmentThemingSettings; -import app.fedilab.android.ui.fragment.settings.FragmentTimelinesSettings; - - -public class SettingsActivity extends BaseActivity { - - private ActivitySettingsBinding binding; - private boolean canGoBack; - private Fragment currentFragment; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - ThemeHelper.applyThemeBar(this); - binding = ActivitySettingsBinding.inflate(getLayoutInflater()); - setContentView(binding.getRoot()); - - if (getSupportActionBar() != null) { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary))); - } - canGoBack = false; - - binding.setAccount.setOnClickListener(v -> displaySettings(SettingsEnum.ACCOUNT)); - binding.setTimelines.setOnClickListener(v -> displaySettings(SettingsEnum.TIMELINES)); - binding.setNotifications.setOnClickListener(v -> displaySettings(SettingsEnum.NOTIFICATIONS)); - binding.setInterface.setOnClickListener(v -> displaySettings(SettingsEnum.INTERFACE)); - binding.setCompose.setOnClickListener(v -> displaySettings(SettingsEnum.COMPOSE)); - binding.setPrivacy.setOnClickListener(v -> displaySettings(SettingsEnum.PRIVACY)); - binding.setTheming.setOnClickListener(v -> displaySettings(SettingsEnum.THEMING)); - binding.setAdministration.setOnClickListener(v -> displaySettings(SettingsEnum.ADMINISTRATION)); - binding.setLanguage.setOnClickListener(v -> displaySettings(SettingsEnum.LANGUAGE)); - if (currentAccount.admin) { - binding.setAdministration.setVisibility(View.VISIBLE); - } else { - binding.setAdministration.setVisibility(View.GONE); - } - } - - public void displaySettings(SettingsEnum settingsEnum) { - - if (settingsEnum == SettingsEnum.ACCOUNT) { - Intent intent = new Intent(SettingsActivity.this, EditProfileActivity.class); - startActivity(intent); - } else { - ThemeHelper.slideViewsToLeft(binding.buttonContainer, binding.fragmentContainer, () -> { - FragmentManager fragmentManager = getSupportFragmentManager(); - FragmentTransaction fragmentTransaction = - fragmentManager.beginTransaction(); - String category = ""; - switch (settingsEnum) { - case TIMELINES: - FragmentTimelinesSettings fragmentTimelinesSettings = new FragmentTimelinesSettings(); - fragmentTransaction.replace(R.id.fragment_container, fragmentTimelinesSettings); - currentFragment = fragmentTimelinesSettings; - category = getString(R.string.settings_category_label_timelines); - break; - case NOTIFICATIONS: - FragmentNotificationsSettings fragmentNotificationsSettings = new FragmentNotificationsSettings(); - fragmentTransaction.replace(R.id.fragment_container, fragmentNotificationsSettings); - currentFragment = fragmentNotificationsSettings; - category = getString(R.string.notifications); - break; - case INTERFACE: - FragmentInterfaceSettings fragmentInterfaceSettings = new FragmentInterfaceSettings(); - fragmentTransaction.replace(R.id.fragment_container, fragmentInterfaceSettings); - currentFragment = fragmentInterfaceSettings; - category = getString(R.string.settings_category_label_interface); - break; - case COMPOSE: - FragmentComposeSettings fragmentComposeSettings = new FragmentComposeSettings(); - fragmentTransaction.replace(R.id.fragment_container, fragmentComposeSettings); - currentFragment = fragmentComposeSettings; - category = getString(R.string.compose); - break; - case PRIVACY: - FragmentPrivacySettings fragmentPrivacySettings = new FragmentPrivacySettings(); - fragmentTransaction.replace(R.id.fragment_container, fragmentPrivacySettings); - currentFragment = fragmentPrivacySettings; - category = getString(R.string.action_privacy); - break; - case THEMING: - FragmentThemingSettings fragmentThemingSettings = new FragmentThemingSettings(); - fragmentTransaction.replace(R.id.fragment_container, fragmentThemingSettings); - currentFragment = fragmentThemingSettings; - category = getString(R.string.theming); - break; - case LANGUAGE: - FragmentLanguageSettings fragmentLanguageSettings = new FragmentLanguageSettings(); - fragmentTransaction.replace(R.id.fragment_container, fragmentLanguageSettings); - currentFragment = fragmentLanguageSettings; - category = getString(R.string.languages); - break; - - } - String title = String.format(Locale.getDefault(), "%s - %s", getString(R.string.settings), category); - setTitle(title); - canGoBack = true; - fragmentTransaction.commit(); - }); - } - } - - - @Override - public void onBackPressed() { - if (canGoBack) { - canGoBack = false; - ThemeHelper.slideViewsToRight(binding.fragmentContainer, binding.buttonContainer, () -> { - if (currentFragment != null) { - FragmentManager fragmentManager = getSupportFragmentManager(); - FragmentTransaction fragmentTransaction = - fragmentManager.beginTransaction(); - fragmentTransaction.remove(currentFragment).commit(); - } - }); - setTitle(R.string.settings); - } else { - super.onBackPressed(); - } - - } - - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - onBackPressed(); - return true; - } - return super.onOptionsItemSelected(item); - } - - - public enum SettingsEnum { - @SerializedName("ACCOUNT") - ACCOUNT("ACCOUNT"), - @SerializedName("TIMELINES") - TIMELINES("TIMELINES"), - @SerializedName("NOTIFICATIONS") - NOTIFICATIONS("NOTIFICATIONS"), - @SerializedName("INTERFACE") - INTERFACE("INTERFACE"), - @SerializedName("COMPOSE") - COMPOSE("COMPOSE"), - @SerializedName("PRIVACY") - PRIVACY("PRIVACY"), - @SerializedName("THEMING") - THEMING("THEMING"), - @SerializedName("ADMINISTRATION") - ADMINISTRATION("ADMINISTRATION"), - @SerializedName("LANGUAGE") - LANGUAGE("LANGUAGE"); - - private final String value; - - SettingsEnum(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - } - -} diff --git a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt new file mode 100644 index 000000000..eb972cca7 --- /dev/null +++ b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt @@ -0,0 +1,46 @@ +package app.fedilab.android.activities +/* Copyright 2022 Thomas Schneider + * + * This file is a part of Fedilab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Fedilab; if not, + * see . */ + +import android.os.Bundle +import androidx.navigation.findNavController +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.navigateUp +import androidx.navigation.ui.setupActionBarWithNavController +import app.fedilab.android.R +import app.fedilab.android.databinding.ActivitySettingsBinding +import app.fedilab.android.helper.ThemeHelper + +class SettingsActivity : BaseActivity() { + private lateinit var binding: ActivitySettingsBinding + private lateinit var appBarConfiguration: AppBarConfiguration + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ThemeHelper.applyThemeBar(this) + + binding = ActivitySettingsBinding.inflate(layoutInflater) + setContentView(binding.root) + + val navController = findNavController(R.id.fragment_container) + appBarConfiguration = AppBarConfiguration(navController.graph) + setupActionBarWithNavController(navController, appBarConfiguration) + } + + override fun onSupportNavigateUp(): Boolean { + val navController = findNavController(R.id.fragment_container) + return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() + } +} diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt b/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt new file mode 100644 index 000000000..4205449a0 --- /dev/null +++ b/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt @@ -0,0 +1,73 @@ +package app.fedilab.android.ui.fragment.settings +/* Copyright 2022 Thomas Schneider + * + * This file is a part of Fedilab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Fedilab; if not, + * see . */ + +import android.os.Bundle +import androidx.navigation.fragment.findNavController +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import app.fedilab.android.BaseMainActivity.currentAccount +import app.fedilab.android.R + +class FragmentSettingsCategories : PreferenceFragmentCompat() { + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + setPreferencesFromResource(R.xml.pref_categories, rootKey) + + findPreference(getString(R.string.pref_category_key_account))?.setOnPreferenceClickListener { + findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToAccount()) + false + } + + findPreference(getString(R.string.pref_category_key_timeline))?.setOnPreferenceClickListener { + findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToTimelines()) + false + } + + findPreference(getString(R.string.pref_category_key_notifications))?.setOnPreferenceClickListener { + findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToNotifications()) + false + } + + findPreference(getString(R.string.pref_category_key_interface))?.setOnPreferenceClickListener { + findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToInterface()) + false + } + + findPreference(getString(R.string.pref_category_key_compose))?.setOnPreferenceClickListener { + findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToCompose()) + false + } + + findPreference(getString(R.string.pref_category_key_privacy))?.setOnPreferenceClickListener { + findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToPrivacy()) + false + } + + findPreference(getString(R.string.pref_category_key_theming))?.setOnPreferenceClickListener { + findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToTheming()) + false + } + + val adminPreference = findPreference(getString(R.string.pref_category_key_administration)) + adminPreference?.isVisible = currentAccount.admin + adminPreference?.setOnPreferenceClickListener { false } + + findPreference(getString(R.string.pref_category_key_languages))?.setOnPreferenceClickListener { + findNavController().navigate(FragmentSettingsCategoriesDirections.categoriesToLanguage()) + false + } + } +} diff --git a/app/src/main/res/anim/enter.xml b/app/src/main/res/anim/enter.xml index 76bfc44c3..504462f05 100644 --- a/app/src/main/res/anim/enter.xml +++ b/app/src/main/res/anim/enter.xml @@ -1,11 +1,10 @@ + android:duration="?attr/motionDurationLong1"> diff --git a/app/src/main/res/anim/exit.xml b/app/src/main/res/anim/exit.xml index 94a8bc808..7733374b8 100644 --- a/app/src/main/res/anim/exit.xml +++ b/app/src/main/res/anim/exit.xml @@ -1,11 +1,10 @@ + android:duration="?attr/motionDurationLong1"> + android:toXDelta="-50%" /> diff --git a/app/src/main/res/anim/pop_enter.xml b/app/src/main/res/anim/pop_enter.xml index 136c23d57..0d04e6879 100644 --- a/app/src/main/res/anim/pop_enter.xml +++ b/app/src/main/res/anim/pop_enter.xml @@ -1,11 +1,10 @@ + android:duration="?attr/motionDurationLong1"> diff --git a/app/src/main/res/anim/pop_exit.xml b/app/src/main/res/anim/pop_exit.xml index 1154aa610..418a0ab70 100644 --- a/app/src/main/res/anim/pop_exit.xml +++ b/app/src/main/res/anim/pop_exit.xml @@ -1,11 +1,10 @@ + android:duration="?attr/motionDurationLong1"> + android:toXDelta="50%" /> diff --git a/app/src/main/res/drawable/ic_baseline_admin_panel_settings_24.xml b/app/src/main/res/drawable/ic_admin.xml similarity index 63% rename from app/src/main/res/drawable/ic_baseline_admin_panel_settings_24.xml rename to app/src/main/res/drawable/ic_admin.xml index 6542cf6b1..9ffcfc0c4 100644 --- a/app/src/main/res/drawable/ic_baseline_admin_panel_settings_24.xml +++ b/app/src/main/res/drawable/ic_admin.xml @@ -5,9 +5,9 @@ android:viewportWidth="24" android:viewportHeight="24"> + android:fillColor="#000" + android:pathData="M17,11c0.34,0 0.67,0.04 1,0.09V7.58c0,-0.8 -0.47,-1.52 -1.2,-1.83l-5.5,-2.4c-0.51,-0.22 -1.09,-0.22 -1.6,0l-5.5,2.4C3.47,6.07 3,6.79 3,7.58v3.6c0,4.54 3.2,8.79 7.5,9.82c0.55,-0.13 1.08,-0.32 1.6,-0.55C11.41,19.47 11,18.28 11,17C11,13.69 13.69,11 17,11z" /> diff --git a/app/src/main/res/drawable/ic_baseline_language_24.xml b/app/src/main/res/drawable/ic_baseline_language_24.xml deleted file mode 100644 index b0fd1af38..000000000 --- a/app/src/main/res/drawable/ic_baseline_language_24.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_language.xml b/app/src/main/res/drawable/ic_language.xml new file mode 100644 index 000000000..87613d22d --- /dev/null +++ b/app/src/main/res/drawable/ic_language.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_shield.xml b/app/src/main/res/drawable/ic_shield.xml new file mode 100644 index 000000000..f877fd2a9 --- /dev/null +++ b/app/src/main/res/drawable/ic_shield.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_style.xml b/app/src/main/res/drawable/ic_style.xml new file mode 100644 index 000000000..34e4e31e2 --- /dev/null +++ b/app/src/main/res/drawable/ic_style.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_theming.xml b/app/src/main/res/drawable/ic_theming.xml new file mode 100644 index 000000000..0da021a27 --- /dev/null +++ b/app/src/main/res/drawable/ic_theming.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_timeline.xml b/app/src/main/res/drawable/ic_timeline.xml new file mode 100644 index 000000000..83b793a51 --- /dev/null +++ b/app/src/main/res/drawable/ic_timeline.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 117b1cf75..a084f20bc 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -1,161 +1,19 @@ - + tools:context=".activities.SettingsActivity" + tools:ignore="FragmentTagUsage"> - - - - - - - - - - - - - - - - - - - - - - - - - - - + app:defaultNavHost="true" + app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" + app:navGraph="@navigation/nav_graph_settings" /> + + diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index 21f0af4cc..553d01f4f 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -32,7 +32,7 @@ android:visible="false" /> @@ -102,4 +102,4 @@ - \ No newline at end of file + diff --git a/app/src/main/res/menu/menu_compose.xml b/app/src/main/res/menu/menu_compose.xml index 88ed2086f..7845538a8 100644 --- a/app/src/main/res/menu/menu_compose.xml +++ b/app/src/main/res/menu/menu_compose.xml @@ -13,7 +13,7 @@ app:showAsAction="ifRoom" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 65ca96432..b0845cab8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1418,4 +1418,14 @@ u+1f4cd u+1f6a9 + + pref_category_account + pref_category_timeline + pref_category_notifications + pref_category_interface + pref_category_compose + pref_category_privacy + pref_category_theming + pref_category_administration + pref_category_languages diff --git a/app/src/main/res/xml/pref_categories.xml b/app/src/main/res/xml/pref_categories.xml new file mode 100644 index 000000000..a1a10073c --- /dev/null +++ b/app/src/main/res/xml/pref_categories.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/build.gradle b/build.gradle index d2aa8244e..dcca24e08 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.0.4' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21" + classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.5.1" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -22,4 +23,4 @@ allprojects { } task clean(type: Delete) { delete rootProject.buildDir -} \ No newline at end of file +}