mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
* 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
This commit is contained in:
parent
2837748540
commit
dd50e83319
8 changed files with 150 additions and 29 deletions
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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<String> languageNamesList = new ArrayList<>();
|
||||
List<String> languageCodesList = new ArrayList<>();
|
||||
List<Language> 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<Language> getLanguagesSupportedByDevice() {
|
||||
List<Language> 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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -32,10 +32,12 @@ public class DescriptionsAdapter extends RecyclerView.Adapter<DescriptionsAdapte
|
|||
private Callback callback;
|
||||
|
||||
private BiMap<AdapterView, String> 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,7 +145,8 @@ public class DescriptionsAdapter extends RecyclerView.Adapter<DescriptionsAdapte
|
|||
private void initLanguageSpinner(int position, Description description) {
|
||||
SpinnerLanguagesAdapter languagesAdapter = new SpinnerLanguagesAdapter(
|
||||
spinnerDescriptionLanguages.getContext(),
|
||||
R.layout.row_item_languages_spinner, selectedLanguages);
|
||||
R.layout.row_item_languages_spinner, selectedLanguages,
|
||||
savedLanguageValue);
|
||||
languagesAdapter.notifyDataSetChanged();
|
||||
spinnerDescriptionLanguages.setAdapter(languagesAdapter);
|
||||
|
||||
|
|
@ -159,15 +162,19 @@ public class DescriptionsAdapter extends RecyclerView.Adapter<DescriptionsAdapte
|
|||
selectedLanguages.put(adapterView, languageCode);
|
||||
((SpinnerLanguagesAdapter) adapterView
|
||||
.getAdapter()).selectedLangCode = languageCode;
|
||||
Timber.d("Description language code is: "+languageCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
if (description.getSelectedLanguageIndex() == -1) {
|
||||
if (savedLanguageValue != null) {
|
||||
// If user has chosen a default language from settings activity savedLanguageValue is not null
|
||||
spinnerDescriptionLanguages.setSelection(languagesAdapter.getIndexOfLanguageCode(savedLanguageValue));
|
||||
} else {
|
||||
if (position == 0) {
|
||||
int defaultLocaleIndex = languagesAdapter
|
||||
.getIndexOfUserDefaultLocale(spinnerDescriptionLanguages.getContext());
|
||||
|
|
@ -175,6 +182,8 @@ public class DescriptionsAdapter extends RecyclerView.Adapter<DescriptionsAdapte
|
|||
} else {
|
||||
spinnerDescriptionLanguages.setSelection(0);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
spinnerDescriptionLanguages.setSelection(description.getSelectedLanguageIndex());
|
||||
selectedLanguages.put(spinnerDescriptionLanguages, description.getLanguageCode());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String> languageCodesList;
|
||||
private final BiMap<AdapterView, String> selectedLanguages;
|
||||
public String selectedLangCode="";
|
||||
private Context context;
|
||||
private boolean dropDownClicked;
|
||||
private String savedLanguageValue;
|
||||
|
||||
|
||||
|
||||
public SpinnerLanguagesAdapter(@NonNull Context context,
|
||||
int resource, BiMap<AdapterView, String> selectedLanguages) {
|
||||
int resource,
|
||||
BiMap<AdapterView, String> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -558,4 +558,5 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="upload_cancelled">Cancelled Upload</string>
|
||||
<string name="previous_image_title_description_not_found">There is no data for previous image\'s title or description</string>
|
||||
<string name="dialog_box_text_nomination">Why should %1$s be deleted?</string>
|
||||
<string name="default_description_language">Default description language</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@
|
|||
android:inputType="number"
|
||||
android:maxLength="3" />
|
||||
|
||||
<fr.free.nrw.commons.ui.LongTitlePreferences.LongTitleListPreference
|
||||
android:key="descriptionDefaultLanguagePref"
|
||||
android:title= "@string/default_description_language"
|
||||
android:summary="English" />
|
||||
|
||||
<fr.free.nrw.commons.ui.LongTitlePreferences.LongTitleSwitchPreference
|
||||
android:key="useAuthorName"
|
||||
android:title="@string/preference_author_name_toggle"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue