From dd50e8331956ec522ce16160f70f569246adfbfe Mon Sep 17 00:00:00 2001 From: neslihanturan Date: Mon, 24 Jun 2019 14:40:12 +0300 Subject: [PATCH] Fixes previous PR - FIX #2918 Add option for default language for file descriptions (#3020) * FIX #2918 Add option for default language for file descriptions * navigation menu error fixed and improvement of code quality * error language description default fixed * adapter language selected fixed * local language selected per default in description language * Use a better string and variable name as required in review 1 * Add comments * Add previously missing setValue methods so that list item will be chosen along with the summary * Add missing Javadocs * Fix capitalization * Lint and formatting issues * Rename methods so it's clearer they are to do with languages * Use default kv store instead of shared preferences variable * Make sure saved language code from settings activity is handled on init --- .../fr/free/nrw/commons/settings/Prefs.java | 1 + .../commons/settings/SettingsFragment.java | 81 ++++++++++++++++++- .../commons/upload/DescriptionsAdapter.java | 27 ++++--- .../fr/free/nrw/commons/upload/Language.java | 2 +- .../upload/SpinnerLanguagesAdapter.java | 52 ++++++++---- .../UploadMediaDetailFragment.java | 10 ++- app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/preferences.xml | 5 ++ 8 files changed, 150 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/settings/Prefs.java b/app/src/main/java/fr/free/nrw/commons/settings/Prefs.java index 9a40acc55..41889e3db 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/Prefs.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/Prefs.java @@ -8,6 +8,7 @@ public class Prefs { public static final String UPLOADS_SHOWING = "uploadsshowing"; public static final String IS_CONTRIBUTION_COUNT_CHANGED = "ccontributionCountChanged"; public static final String MANAGED_EXIF_TAGS = "managedExifTags"; + public static final String KEY_LANGUAGE_VALUE = "languageDescription"; public static class Licenses { public static final String CC_BY_SA_3 = "CC BY-SA 3.0"; diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java index 6d527c91d..176697f9a 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java @@ -1,12 +1,15 @@ package fr.free.nrw.commons.settings; import android.Manifest; +import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.MultiSelectListPreference; +import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; import android.preference.SwitchPreference; import android.text.Editable; import android.text.TextWatcher; @@ -15,10 +18,10 @@ import com.karumi.dexter.Dexter; import com.karumi.dexter.listener.PermissionGrantedResponse; import com.karumi.dexter.listener.single.BasePermissionListener; -import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; import javax.inject.Inject; import javax.inject.Named; @@ -30,6 +33,7 @@ import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.logging.CommonsLogSender; import fr.free.nrw.commons.utils.PermissionUtils; import fr.free.nrw.commons.utils.ViewUtil; +import fr.free.nrw.commons.upload.Language; public class SettingsFragment extends PreferenceFragment { @@ -38,6 +42,7 @@ public class SettingsFragment extends PreferenceFragment { JsonKvStore defaultKvStore; @Inject CommonsLogSender commonsLogSender; + private ListPreference listPreference; @Override public void onCreate(Bundle savedInstanceState) { @@ -108,6 +113,8 @@ public class SettingsFragment extends PreferenceFragment { } }); + listPreference = (ListPreference) findPreference("descriptionDefaultLanguagePref"); + prepareLanguages(); Preference betaTesterPreference = findPreference("becomeBetaTester"); betaTesterPreference.setOnPreferenceClickListener(preference -> { Utils.handleWebUrl(getActivity(), Uri.parse(getResources().getString(R.string.beta_opt_in_link))); @@ -133,6 +140,74 @@ public class SettingsFragment extends PreferenceFragment { } } + /** + * Prepares language summary and language codes list and adds them to list preference as pairs. + * Uses previously saved language if there is any, if not uses phone local as initial language. + * Adds preference changed listener and saves value choosen by user to shared preferences + * to remember later + */ + private void prepareLanguages() { + List languageNamesList = new ArrayList<>(); + List languageCodesList = new ArrayList<>(); + List languages = getLanguagesSupportedByDevice(); + + for(Language language: languages) { + // Go through all languages and add them to lists + if(!languageCodesList.contains(language.getLocale().getLanguage())) { + // This if prevents us from adding same language twice + languageNamesList.add(language.getLocale().getDisplayName()); + languageCodesList.add(language.getLocale().getLanguage()); + } + } + + CharSequence[] languageNames = languageNamesList.toArray(new CharSequence[0]); + CharSequence[] languageCodes = languageCodesList.toArray(new CharSequence[0]); + // Add all languages and languages codes to lists preference as pair + listPreference.setEntries(languageNames); + listPreference.setEntryValues(languageCodes); + + // Gets current language code from shared preferences + String languageCode = getCurrentLanguageCode(); + if(languageCode.equals("")){ + // If current language code is empty, means none selected by user yet so use phone local + listPreference.setSummary(Locale.getDefault().getDisplayLanguage()); + listPreference.setValue(Locale.getDefault().getLanguage()); + } else { + // If any language is selected by user previously, use it + int prefIndex = listPreference.findIndexOfValue(languageCode); + listPreference.setSummary(listPreference.getEntries()[prefIndex]); + listPreference.setValue(languageCode); + } + + listPreference.setOnPreferenceChangeListener((preference, newValue) -> { + String userSelectedValue = (String) newValue; + int prefIndex = listPreference.findIndexOfValue(userSelectedValue); + listPreference.setSummary(listPreference.getEntries()[prefIndex]); + saveLanguageValue(userSelectedValue); + return true; + }); + } + + private void saveLanguageValue(String userSelectedValue) { + defaultKvStore.putString(Prefs.KEY_LANGUAGE_VALUE, userSelectedValue); + } + + private String getCurrentLanguageCode() { + return defaultKvStore.getString(Prefs.KEY_LANGUAGE_VALUE, ""); + } + + private List getLanguagesSupportedByDevice() { + List languages = new ArrayList<>(); + Locale[] localesArray = Locale.getAvailableLocales(); + for (Locale locale : localesArray) { + languages.add(new Language(locale)); + } + + Collections.sort(languages, (language, t1) -> language.getLocale().getDisplayName() + .compareTo(t1.getLocale().getDisplayName())); + return languages; + } + /** * First checks for external storage permissions and then sends logs via email */ diff --git a/app/src/main/java/fr/free/nrw/commons/upload/DescriptionsAdapter.java b/app/src/main/java/fr/free/nrw/commons/upload/DescriptionsAdapter.java index a24a791bf..badcd48f8 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/DescriptionsAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/DescriptionsAdapter.java @@ -32,10 +32,12 @@ public class DescriptionsAdapter extends RecyclerView.Adapter selectedLanguages; + private String savedLanguageValue; - public DescriptionsAdapter() { + public DescriptionsAdapter(String savedLanguageValue) { descriptions = new ArrayList<>(); selectedLanguages = new BiMap<>(); + this.savedLanguageValue = savedLanguageValue; } public void setCallback(Callback callback) { @@ -143,14 +145,15 @@ public class DescriptionsAdapter extends RecyclerView.Adapter adapterView, View view, int position, - long l) { + long l) { description.setSelectedLanguageIndex(position); String languageCode = ((SpinnerLanguagesAdapter) adapterView.getAdapter()) .getLanguageCode(position); @@ -159,22 +162,28 @@ public class DescriptionsAdapter extends RecyclerView.Adapter adapterView) { - } }); if (description.getSelectedLanguageIndex() == -1) { - if (position == 0) { - int defaultLocaleIndex = languagesAdapter - .getIndexOfUserDefaultLocale(spinnerDescriptionLanguages.getContext()); - spinnerDescriptionLanguages.setSelection(defaultLocaleIndex, true); + if (savedLanguageValue != null) { + // If user has chosen a default language from settings activity savedLanguageValue is not null + spinnerDescriptionLanguages.setSelection(languagesAdapter.getIndexOfLanguageCode(savedLanguageValue)); } else { - spinnerDescriptionLanguages.setSelection(0); + if (position == 0) { + int defaultLocaleIndex = languagesAdapter + .getIndexOfUserDefaultLocale(spinnerDescriptionLanguages.getContext()); + spinnerDescriptionLanguages.setSelection(defaultLocaleIndex, true); + } else { + spinnerDescriptionLanguages.setSelection(0); + } } + } else { spinnerDescriptionLanguages.setSelection(description.getSelectedLanguageIndex()); selectedLanguages.put(spinnerDescriptionLanguages, description.getLanguageCode()); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/Language.java b/app/src/main/java/fr/free/nrw/commons/upload/Language.java index ab03a4db7..d82796a4a 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/Language.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/Language.java @@ -2,7 +2,7 @@ package fr.free.nrw.commons.upload; import java.util.Locale; -class Language { +public class Language { private Locale locale; private boolean isSet = false; diff --git a/app/src/main/java/fr/free/nrw/commons/upload/SpinnerLanguagesAdapter.java b/app/src/main/java/fr/free/nrw/commons/upload/SpinnerLanguagesAdapter.java index 346f6a4ec..f050568a8 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/SpinnerLanguagesAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/SpinnerLanguagesAdapter.java @@ -1,7 +1,9 @@ package fr.free.nrw.commons.upload; import android.content.Context; +import android.content.SharedPreferences; import android.graphics.Color; +import android.preference.PreferenceManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -16,15 +18,16 @@ import java.util.Locale; import androidx.annotation.NonNull; import androidx.annotation.Nullable; + +import org.apache.commons.lang3.StringUtils; + import butterknife.BindView; import butterknife.ButterKnife; import fr.free.nrw.commons.R; +import fr.free.nrw.commons.settings.Prefs; import fr.free.nrw.commons.utils.BiMap; import fr.free.nrw.commons.utils.LangCodeUtils; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; + public class SpinnerLanguagesAdapter extends ArrayAdapter { @@ -34,11 +37,16 @@ public class SpinnerLanguagesAdapter extends ArrayAdapter { private List languageCodesList; private final BiMap selectedLanguages; public String selectedLangCode=""; + private Context context; + private boolean dropDownClicked; + private String savedLanguageValue; public SpinnerLanguagesAdapter(@NonNull Context context, - int resource, BiMap selectedLanguages) { + int resource, + BiMap selectedLanguages, + String savedLanguageValue) { super(context, resource); this.resource = resource; this.layoutInflater = LayoutInflater.from(context); @@ -46,6 +54,9 @@ public class SpinnerLanguagesAdapter extends ArrayAdapter { languageCodesList = new ArrayList<>(); prepareLanguages(); this.selectedLanguages = selectedLanguages; + this.context = context; + this.dropDownClicked = false; + this.savedLanguageValue = savedLanguageValue; } private void prepareLanguages() { @@ -90,7 +101,9 @@ public class SpinnerLanguagesAdapter extends ArrayAdapter { convertView = layoutInflater.inflate(resource, parent, false); } ViewHolder holder = new ViewHolder(convertView); - holder.init(position, true); + holder.init(position, true, savedLanguageValue); + + dropDownClicked = true; return convertView; } @@ -105,7 +118,7 @@ public class SpinnerLanguagesAdapter extends ArrayAdapter { } else { holder = (ViewHolder) convertView.getTag(); } - holder.init(position, false); + holder.init(position, false, savedLanguageValue); return convertView; } @@ -122,17 +135,23 @@ public class SpinnerLanguagesAdapter extends ArrayAdapter { ButterKnife.bind(this, itemView); } - public void init(int position, boolean isDropDownView) { - final String languageCode = LangCodeUtils.fixLanguageCode(languageCodesList.get(position)); - final String languageName = String.format("%s%s", languageNamesList.get(position) - .substring(0, 1).toUpperCase(), languageNamesList.get(position).substring(1)); + public void init(int position, boolean isDropDownView, String savedLanguageValue) { + String languageCode = LangCodeUtils.fixLanguageCode(languageCodesList.get(position)); + final String languageName = StringUtils.capitalize(languageNamesList.get(position)); + + if(savedLanguageValue.equals("")){ + savedLanguageValue = Locale.getDefault().getLanguage(); + } + if (!isDropDownView) { + if( !dropDownClicked){ + languageCode = LangCodeUtils.fixLanguageCode(savedLanguageValue); + } view.setVisibility(View.GONE); - if(languageCode.length()>2) - tvLanguage.setText(languageCode.subSequence(0,2)); + if (languageCode.length() > 2) + tvLanguage.setText(languageCode.substring(0, 2)); else tvLanguage.setText(languageCode); - } else { view.setVisibility(View.VISIBLE); if (languageCodesList.get(position).isEmpty()) { @@ -141,7 +160,7 @@ public class SpinnerLanguagesAdapter extends ArrayAdapter { } else { tvLanguage.setText( String.format("%s [%s]", languageName, languageCode)); - if(selectedLanguages.containsKey(languageCodesList.get(position))&& + if (selectedLanguages.containsKey(languageCodesList.get(position)) && !languageCodesList.get(position).equals(selectedLangCode)) { tvLanguage.setTextColor(Color.GRAY); } @@ -158,4 +177,7 @@ public class SpinnerLanguagesAdapter extends ArrayAdapter { return languageCodesList.indexOf(context.getResources().getConfiguration().locale.getLanguage()); } + int getIndexOfLanguageCode(String languageCode) { + return languageCodesList.indexOf(languageCode); + } } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java index 0b589fc77..3c7c96bbe 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Locale; import javax.inject.Inject; +import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; @@ -39,8 +40,10 @@ import butterknife.OnClick; import fr.free.nrw.commons.R; import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.filepicker.UploadableFile; +import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.nearby.Place; +import fr.free.nrw.commons.settings.Prefs; import fr.free.nrw.commons.upload.Description; import fr.free.nrw.commons.upload.DescriptionsAdapter; import fr.free.nrw.commons.upload.SimilarImageDialogFragment; @@ -86,6 +89,11 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements @Inject UploadMediaDetailsContract.UserActionListener presenter; + + @Inject + @Named("default_preferences") + JsonKvStore defaultKvStore; + private UploadableFile uploadableFile; private String source; private Place place; @@ -214,7 +222,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements * init the recycler veiw */ private void initRecyclerView() { - descriptionsAdapter = new DescriptionsAdapter(); + descriptionsAdapter = new DescriptionsAdapter(defaultKvStore.getString(Prefs.KEY_LANGUAGE_VALUE,"")); descriptionsAdapter.setCallback(this::showInfoAlert); rvDescriptions.setLayoutManager(new LinearLayoutManager(getContext())); rvDescriptions.setAdapter(descriptionsAdapter); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0c6ba28f0..ac9d2e736 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -558,4 +558,5 @@ Upload your first media by tapping on the add button. Cancelled Upload There is no data for previous image\'s title or description Why should %1$s be deleted? + Default description language diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 9ab4d5f5f..cdeaa8366 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -29,6 +29,11 @@ android:inputType="number" android:maxLength="3" /> + +