Use language provided by system (#914)

Pr tries to implement support for usage of system language.

Currently work in progress.

- [x] add option to use system language
- [x] use this by default
- [x] fix other usages of db value "locale"
- [X] fix usages of `Locale.getDefault()` (except [here](https://codeberg.org/gitnex/GitNex/src/branch/main/app/src/main/java/org/mian/gitnex/helpers/ssl/MemorizingTrustManager.java#L429))
- [ ] get language list programmaticaly
- [X] localize language names (related to #101)
- [X] move languages list to ~~Hashmap~~ TreeMap (it seems that HashMaps sort everything in a random order)

I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).
<br>
Fixes #899

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/914
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
This commit is contained in:
qwerty287 2021-05-29 18:21:48 +02:00 committed by opyale
parent cc70fe9a68
commit 547e7c705d
22 changed files with 83 additions and 111 deletions

View File

@ -8,6 +8,7 @@ import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.notifications.Notifications;
import java.util.Locale;
/**
* Author M M Arif
@ -77,7 +78,13 @@ public abstract class BaseActivity extends AppCompatActivity {
}
AppUtil.setAppLocale(getResources(), tinyDB.getString("locale"));
String locale = tinyDB.getString("locale");
if (locale.isEmpty()) {
AppUtil.setAppLocale(getResources(), Locale.getDefault().getLanguage());
}
else {
AppUtil.setAppLocale(getResources(), locale);
}
Notifications.startWorker(appCtx);
}

View File

@ -569,7 +569,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
}
TinyDB tinyDb = TinyDB.getInstance(appCtx);
final String locale = tinyDb.getString("locale");
final String locale = getResources().getConfiguration().locale.getLanguage();
final String timeFormat = tinyDb.getString("dateFormat");
tinyDb.putString("issueState", singleIssue.getState());
tinyDb.putString("issueTitle", singleIssue.getTitle());

View File

@ -11,6 +11,9 @@ import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsTranslationBinding;
import org.mian.gitnex.helpers.Toasty;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.TreeMap;
/**
* Author M M Arif
@ -20,8 +23,6 @@ public class SettingsTranslationActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private static String[] langList = {"English", "Arabic", "Chinese", "Czech", "Finnish", "French", "German", "Italian", "Latvian", "Persian",
"Polish", "Portuguese/Brazilian", "Russian", "Serbian", "Spanish", "Turkish", "Ukrainian"};
private static int langSelectedChoice = 0;
@Override
@ -29,6 +30,12 @@ public class SettingsTranslationActivity extends BaseActivity {
super.onCreate(savedInstanceState);
LinkedHashMap<String, String> langs = new LinkedHashMap<>();
langs.put("", getString(R.string.settingsLanguageSystem));
for(String langCode : getResources().getStringArray(R.array.languages)) {
langs.put(langCode, getLanguageDisplayName(langCode));
}
ActivitySettingsTranslationBinding activitySettingsTranslationBinding = ActivitySettingsTranslationBinding.inflate(getLayoutInflater());
setContentView(activitySettingsTranslationBinding.getRoot());
@ -52,15 +59,9 @@ public class SettingsTranslationActivity extends BaseActivity {
});
if(!tinyDB.getString("localeStr").isEmpty()) {
tvLanguageSelected.setText(tinyDB.getString("localeStr"));
tvLanguageSelected.setText(tinyDB.getString("localeStr"));
}
if(langSelectedChoice == 0) {
langSelectedChoice = tinyDB.getInt("langId");
}
langSelectedChoice = tinyDB.getInt("langId");
// language dialog
langFrame.setOnClickListener(view -> {
@ -70,89 +71,18 @@ public class SettingsTranslationActivity extends BaseActivity {
lBuilder.setTitle(R.string.settingsLanguageSelectorDialogTitle);
lBuilder.setCancelable(langSelectedChoice != -1);
lBuilder.setSingleChoiceItems(langList, langSelectedChoice, (dialogInterface, i) -> {
lBuilder.setSingleChoiceItems(langs.values().toArray(new String[0]), langSelectedChoice, (dialogInterface, i) -> {
langSelectedChoice = i;
tvLanguageSelected.setText(langList[i]);
tinyDB.putString("localeStr", langList[i]);
String selectedLanguage = langs.keySet().toArray(new String[0])[i];
tinyDB.putString("localeStr", langs.get(selectedLanguage));
tinyDB.putInt("langId", i);
switch(langList[i]) {
case "Arabic":
tinyDB.putString("locale", "ar");
break;
case "Chinese":
tinyDB.putString("locale", "zh");
break;
case "Czech":
tinyDB.putString("locale", "cs");
break;
case "Finnish":
tinyDB.putString("locale", "fi");
break;
case "French":
tinyDB.putString("locale", "fr");
break;
case "German":
tinyDB.putString("locale", "de");
break;
case "Italian":
tinyDB.putString("locale", "it");
break;
case "Latvian":
tinyDB.putString("locale", "lv");
break;
case "Persian":
tinyDB.putString("locale", "fa");
break;
case "Polish":
tinyDB.putString("locale", "pl");
break;
case "Portuguese/Brazilian":
tinyDB.putString("locale", "pt");
break;
case "Russian":
tinyDB.putString("locale", "ru");
break;
case "Serbian":
tinyDB.putString("locale", "sr");
break;
case "Spanish":
tinyDB.putString("locale", "es");
break;
case "Turkish":
tinyDB.putString("locale", "tr");
break;
case "Ukrainian":
tinyDB.putString("locale", "uk");
break;
default:
tinyDB.putString("locale", "en");
break;
}
tinyDB.putString("locale", selectedLanguage);
tinyDB.putBoolean("refreshParent", true);
this.recreate();
this.overridePendingTransition(0, 0);
dialogInterface.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
this.recreate();
});
lBuilder.setNeutralButton(getString(R.string.cancelButton), null);
@ -167,4 +97,10 @@ public class SettingsTranslationActivity extends BaseActivity {
onClickListener = view -> finish();
}
private static String getLanguageDisplayName(String langCode) {
Locale english = new Locale("en");
Locale translated = new Locale(langCode);
return String.format("%s (%s)", translated.getDisplayName(translated), translated.getDisplayName(english));
}
}

View File

@ -44,7 +44,7 @@ public class AdminCronTasksAdapter extends RecyclerView.Adapter<AdminCronTasksAd
super(itemView);
Context ctx = itemView.getContext();
final String locale = tinyDb.getString("locale");
final String locale = ctx.getResources().getConfiguration().locale.getLanguage();
final String timeFormat = tinyDb.getString("dateFormat");
ImageView runTask = itemView.findViewById(R.id.runTask);

View File

@ -106,7 +106,7 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
void bindData(Commits commitsModel) {
final TinyDB tinyDb = TinyDB.getInstance(context);
final String locale = tinyDb.getString("locale");
String locale = context.getResources().getConfiguration().locale.getLanguage();
final String timeFormat = tinyDb.getString("dateFormat");
commitTitle.setText(EmojiParser.parseToUnicode(commitsModel.getCommit().getMessage()));

View File

@ -183,7 +183,7 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
String locale = tinyDb.getString("locale");
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
@ -212,20 +212,20 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;

View File

@ -338,13 +338,13 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
if(timeFormat.equals("pretty")) {
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), Locale.getDefault(), "pretty", context));
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), context.getResources().getConfiguration().locale, "pretty", context));
holder.information.setOnClickListener(v -> TimeHelper.customDateFormatForToastDateFormat(issueComment.getCreated_at()));
}
else if(timeFormat.equals("normal")) {
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), Locale.getDefault(), "normal", context));
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), context.getResources().getConfiguration().locale, "normal", context));
}
if(!issueComment.getCreated_at().equals(issueComment.getUpdated_at())) {

View File

@ -135,7 +135,7 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
void bindData(Issues issue) {
TinyDB tinyDb = TinyDB.getInstance(context);
String locale = tinyDb.getString("locale");
String locale = context.getResources().getConfiguration().locale.getLanguage();
String timeFormat = tinyDb.getString("dateFormat");
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);

View File

@ -148,7 +148,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
this.milestones = dataModel;
final TinyDB tinyDb = TinyDB.getInstance(context);
final String locale = tinyDb.getString("locale");
final String locale = context.getResources().getConfiguration().locale.getLanguage();
final String timeFormat = tinyDb.getString("dateFormat");
Markdown.render(context, dataModel.getTitle(), msTitle);

View File

@ -190,7 +190,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
String locale = tinyDb.getString("locale");
String locale = context.getResources().getConfiguration().locale.getLanguage();
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);

View File

@ -147,7 +147,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
void bindData(PullRequests pullRequest) {
TinyDB tinyDb = TinyDB.getInstance(context);
String locale = tinyDb.getString("locale");
String locale = context.getResources().getConfiguration().locale.getLanguage();
String timeFormat = tinyDb.getString("dateFormat");
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);

View File

@ -89,7 +89,7 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
public void onBindViewHolder(@NonNull ReleasesAdapter.ReleasesViewHolder holder, int position) {
final TinyDB tinyDb = TinyDB.getInstance(context);
final String locale = tinyDb.getString("locale");
final String locale = context.getResources().getConfiguration().locale.getLanguage();
final String timeFormat = tinyDb.getString("dateFormat");
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);

View File

@ -132,7 +132,7 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
TinyDB tinyDb = TinyDB.getInstance(context);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
String locale = tinyDb.getString("locale");
String locale = context.getResources().getConfiguration().locale.getLanguage();
String timeFormat = tinyDb.getString("dateFormat");
this.userRepositories = forksModel;
orgName.setText(forksModel.getFullName().split("/")[0]);

View File

@ -189,7 +189,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
String locale = tinyDb.getString("locale");
String locale = context.getResources().getConfiguration().locale.getLanguage();
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);

View File

@ -186,7 +186,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
String locale = tinyDb.getString("locale");
String locale = context.getResources().getConfiguration().locale.getLanguage();
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);

View File

@ -125,7 +125,7 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapte
Issues currentItem = searchedList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
String locale = tinyDb.getString("locale");
String locale = context.getResources().getConfiguration().locale.getLanguage();
String timeFormat = tinyDb.getString("dateFormat");
PicassoService.getInstance(context).get()

View File

@ -187,7 +187,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
String locale = tinyDb.getString("locale");
String locale = context.getResources().getConfiguration().locale.getLanguage();
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);

View File

@ -152,5 +152,10 @@ public class MainApplication extends Application {
tinyDB.putInt("homeScreenId", 0);
}
if(tinyDB.getString("localeStr").isEmpty()) {
tinyDB.putString("localeStr", getString(R.string.settingsLanguageSystem));
tinyDB.putInt("langId", 0);
}
}
}

View File

@ -84,7 +84,7 @@ public class RepoInfoFragment extends Fragment {
binding.repoMetaFrame.setVisibility(View.GONE);
getRepoInfo(Authorization.get(getContext()), repoOwner, repoName, tinyDb.getString("locale"), tinyDb.getString("dateFormat"));
getRepoInfo(Authorization.get(getContext()), repoOwner, repoName, getResources().getConfiguration().locale, tinyDb.getString("dateFormat"));
getFileContents(Authorization.get(getContext()), repoOwner, repoName, getResources().getString(R.string.defaultFilename));
if(isExpandViewVisible()) {
@ -173,7 +173,7 @@ public class RepoInfoFragment extends Fragment {
return binding.repoMetaFrame.getVisibility() == View.VISIBLE;
}
private void getRepoInfo(String token, final String owner, String repo, final String locale, final String timeFormat) {
private void getRepoInfo(String token, final String owner, String repo, final Locale locale, final String timeFormat) {
final TinyDB tinyDb = TinyDB.getInstance(getContext());
@ -217,12 +217,12 @@ public class RepoInfoFragment extends Fragment {
binding.repoMetaWatchers.setText(repoInfo.getWatchers_count());
binding.repoMetaSize.setText(FileUtils.byteCountToDisplaySize((int) repoInfo.getSize() * 1024));
binding.repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx));
binding.repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), locale, timeFormat, ctx));
if(timeFormat.equals("pretty")) {
binding.repoMetaCreatedAt.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), ctx));
}
String repoMetaUpdatedAt = TimeHelper.formatTime(repoInfo.getUpdated_at(), new Locale(locale), timeFormat, ctx);
String repoMetaUpdatedAt = TimeHelper.formatTime(repoInfo.getUpdated_at(), locale, timeFormat, ctx);
String website = (repoInfo.getWebsite().isEmpty()) ? getResources().getString(R.string.noDataWebsite) : repoInfo.getWebsite();
binding.repoMetaWebsite.setText(website);

View File

@ -43,7 +43,7 @@ public class TimeHelper {
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(Locale.getDefault());
PrettyTime prettyTime = new PrettyTime(locale);
return prettyTime.format(date);
}

View File

@ -0,0 +1,23 @@
<resources>
<string-array name="languages">
<item>en</item>
<item>ar</item>
<item>zh</item>
<item>cs</item>
<item>fi</item>
<item>fr</item>
<item>de</item>
<item>it</item>
<item>lv</item>
<item>fa</item>
<item>pl</item>
<item>pt</item>
<item>ru</item>
<item>ru</item>
<item>sr</item>
<item>es</item>
<item>tr</item>
<item>uk</item>
</string-array>
</resources>

View File

@ -223,6 +223,7 @@
<!-- settings -->
<string name="settingsLanguageHeaderText">Translation</string>
<string name="settingsLanguageSystem">System</string>
<string name="settingsSecurityHeader">Security</string>
<string name="settingsCertsSelectorHeader">Delete Trusted Certificates</string>
<string name="settingsCertsPopupTitle">Delete Trusted Certificates?</string>