Move settings data to db and other improvements (#1332)

Closes #1331

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1332
Co-authored-by: M M Arif <mmarif@swatian.com>
Co-committed-by: M M Arif <mmarif@swatian.com>
This commit is contained in:
M M Arif 2024-03-18 05:12:24 +00:00 committed by M M Arif
parent 36e7cfeddb
commit e6365b9d74
69 changed files with 3604 additions and 1073 deletions

View File

@ -10,7 +10,7 @@ steps:
branch: main
push:
image: crowdin/cli:3.7.8
image: crowdin/cli:3.16.0
commands:
- crowdin push
when:
@ -19,7 +19,7 @@ steps:
path: [ app/src/main/res/values/strings.xml, fastlane/metadata/android/en-US/*.txt, fastlane/metadata/android/en-US/changelogs/*.txt ]
pull:
image: crowdin/cli:3.7.8
image: crowdin/cli:3.16.0
# we do not need to update the config file again since it persists
commands:
- crowdin pull

View File

@ -10,6 +10,7 @@ import java.util.Locale;
import java.util.concurrent.Executor;
import org.mian.gitnex.R;
import org.mian.gitnex.core.MainApplication;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
@ -34,7 +35,8 @@ public abstract class BaseActivity extends AppCompatActivity {
this.appCtx = getApplicationContext();
this.tinyDB = TinyDB.getInstance(appCtx);
switch (tinyDB.getInt("themeId", 6)) {
switch (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(ctx, AppDatabaseSettings.APP_THEME_KEY))) {
case 0:
setTheme(R.style.AppTheme);
break;
@ -43,10 +45,18 @@ public abstract class BaseActivity extends AppCompatActivity {
break;
case 2:
if (TimeHelper.timeBetweenHours(
tinyDB.getInt("darkThemeTimeHour", 18),
tinyDB.getInt("lightThemeTimeHour", 6),
tinyDB.getInt("darkThemeTimeMinute", 0),
tinyDB.getInt("lightThemeTimeMinute", 0))) {
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_HOUR_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_HOUR_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_MIN_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_MIN_KEY)))) {
setTheme(R.style.AppTheme);
} else {
@ -59,10 +69,18 @@ public abstract class BaseActivity extends AppCompatActivity {
break;
case 4:
if (TimeHelper.timeBetweenHours(
tinyDB.getInt("darkThemeTimeHour", 18),
tinyDB.getInt("lightThemeTimeHour", 6),
tinyDB.getInt("darkThemeTimeMinute", 0),
tinyDB.getInt("lightThemeTimeMinute", 0))) {
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_HOUR_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_HOUR_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_MIN_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_MIN_KEY)))) {
setTheme(R.style.AppTheme);
} else {
@ -87,11 +105,14 @@ public abstract class BaseActivity extends AppCompatActivity {
break;
}
String locale = tinyDB.getString("locale");
if (locale.isEmpty()) {
String[] locale =
AppDatabaseSettings.getSettingsValue(ctx, AppDatabaseSettings.APP_LOCALE_KEY)
.split("\\|");
if (locale[0].equals("0")) {
AppUtil.setAppLocale(getResources(), Locale.getDefault().getLanguage());
} else {
AppUtil.setAppLocale(getResources(), locale);
AppUtil.setAppLocale(getResources(), locale[1]);
}
Notifications.startWorker(ctx);
@ -100,8 +121,12 @@ public abstract class BaseActivity extends AppCompatActivity {
public void onResume() {
super.onResume();
if (tinyDB.getBoolean("biometricStatus", false)
&& !tinyDB.getBoolean("biometricLifeCycle")) {
if (Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_BIOMETRIC_KEY))
&& !Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_BIOMETRIC_LIFE_CYCLE_KEY))) {
Executor executor = ContextCompat.getMainExecutor(this);
@ -126,7 +151,10 @@ public abstract class BaseActivity extends AppCompatActivity {
public void onAuthenticationSucceeded(
@NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
tinyDB.putBoolean("biometricLifeCycle", true);
AppDatabaseSettings.updateSettingsValue(
getApplicationContext(),
"true",
AppDatabaseSettings.APP_BIOMETRIC_LIFE_CYCLE_KEY);
}
// Authentication failed, close the app

View File

@ -13,6 +13,7 @@ import java.util.Map;
import org.mian.gitnex.R;
import org.mian.gitnex.core.MainGrammarLocator;
import org.mian.gitnex.databinding.ActivityCodeEditorBinding;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.codeeditor.CustomCodeViewAdapter;
import org.mian.gitnex.helpers.codeeditor.SourcePositionListener;
import org.mian.gitnex.helpers.codeeditor.languages.Language;
@ -73,9 +74,14 @@ public class CodeEditorActivity extends BaseActivity {
binding.codeView.setLineNumberTextSize(32f);
// Setup Auto indenting feature
if (tinyDB.getInt("ceIndentationId") == 0) {
if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_CE_INDENTATION_KEY))
== 0) {
binding.codeView.setEnableAutoIndentation(true);
switch (tinyDB.getInt("ceIndentationTabsId")) {
switch (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_CE_TABS_WIDTH_KEY))) {
case 0:
binding.codeView.setTabLength(2);
break;

View File

@ -50,6 +50,7 @@ import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.SnackBar;
@ -315,6 +316,10 @@ public class CreateIssueActivity extends BaseActivity
builder.setTitleText(R.string.newIssueDueDateTitle);
MaterialDatePicker<Long> materialDatePicker = builder.build();
String[] locale_ =
AppDatabaseSettings.getSettingsValue(ctx, AppDatabaseSettings.APP_LOCALE_KEY)
.split("\\|");
viewBinding.newIssueDueDate.setOnClickListener(
v -> materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER"));
@ -323,8 +328,7 @@ public class CreateIssueActivity extends BaseActivity
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(selection);
SimpleDateFormat format =
new SimpleDateFormat(
"yyyy-MM-dd", new Locale(tinyDB.getString("locale")));
new SimpleDateFormat("yyyy-MM-dd", new Locale(locale_[1]));
String formattedDate = format.format(calendar.getTime());
viewBinding.newIssueDueDate.setText(formattedDate);
});

View File

@ -21,6 +21,7 @@ import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateMilestoneBinding;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
@ -109,6 +110,10 @@ public class CreateMilestoneActivity extends BaseActivity {
builder.setTitleText(R.string.newIssueDueDateTitle);
MaterialDatePicker<Long> materialDatePicker = builder.build();
String[] locale_ =
AppDatabaseSettings.getSettingsValue(ctx, AppDatabaseSettings.APP_LOCALE_KEY)
.split("\\|");
binding.milestoneDueDate.setOnClickListener(
v -> materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER"));
@ -117,8 +122,7 @@ public class CreateMilestoneActivity extends BaseActivity {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(selection);
SimpleDateFormat format =
new SimpleDateFormat(
"yyyy-MM-dd", new Locale(tinyDB.getString("locale")));
new SimpleDateFormat("yyyy-MM-dd", new Locale(locale_[1]));
String formattedDate = format.format(calendar.getTime());
binding.milestoneDueDate.setText(formattedDate);
});

View File

@ -47,6 +47,7 @@ import org.mian.gitnex.databinding.BottomSheetAttachmentsBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.SnackBar;
@ -429,6 +430,10 @@ public class CreatePullRequestActivity extends BaseActivity
builder.setTitleText(R.string.newIssueDueDateTitle);
MaterialDatePicker<Long> materialDatePicker = builder.build();
String[] locale_ =
AppDatabaseSettings.getSettingsValue(ctx, AppDatabaseSettings.APP_LOCALE_KEY)
.split("\\|");
viewBinding.prDueDate.setOnClickListener(
v -> materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER"));
@ -437,8 +442,7 @@ public class CreatePullRequestActivity extends BaseActivity
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(selection);
SimpleDateFormat format =
new SimpleDateFormat(
"yyyy-MM-dd", new Locale(tinyDB.getString("locale")));
new SimpleDateFormat("yyyy-MM-dd", new Locale(locale_[1]));
String formattedDate = format.format(calendar.getTime());
viewBinding.prDueDate.setText(formattedDate);
});

View File

@ -23,6 +23,7 @@ import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.databinding.ActivityDeeplinksBinding;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
@ -675,7 +676,9 @@ public class DeepLinksActivity extends BaseActivity {
private void showNoActionButtons() {
viewBinding.progressBar.setVisibility(View.GONE);
switch (tinyDB.getInt("defaultScreenId")) {
switch (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_LINK_HANDLER_KEY))) {
case 1: // repos
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
ctx.startActivity(mainIntent);
@ -708,7 +711,10 @@ public class DeepLinksActivity extends BaseActivity {
viewBinding.repository.setOnClickListener(
repository -> {
tinyDB.putInt("defaultScreenId", 1);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(1),
AppDatabaseSettings.APP_LINK_HANDLER_KEY);
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
ctx.startActivity(mainIntent);
finish();
@ -716,7 +722,10 @@ public class DeepLinksActivity extends BaseActivity {
viewBinding.organization.setOnClickListener(
organization -> {
tinyDB.putInt("defaultScreenId", 2);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(2),
AppDatabaseSettings.APP_LINK_HANDLER_KEY);
mainIntent.putExtra("launchFragmentByLinkHandler", "org");
ctx.startActivity(mainIntent);
finish();
@ -724,7 +733,10 @@ public class DeepLinksActivity extends BaseActivity {
viewBinding.notification.setOnClickListener(
notification -> {
tinyDB.putInt("defaultScreenId", 3);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(3),
AppDatabaseSettings.APP_LINK_HANDLER_KEY);
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
ctx.startActivity(mainIntent);
finish();
@ -732,7 +744,10 @@ public class DeepLinksActivity extends BaseActivity {
viewBinding.explore.setOnClickListener(
explore -> {
tinyDB.putInt("defaultScreenId", 4);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(4),
AppDatabaseSettings.APP_LINK_HANDLER_KEY);
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
ctx.startActivity(mainIntent);
finish();
@ -740,7 +755,10 @@ public class DeepLinksActivity extends BaseActivity {
viewBinding.launchApp2.setOnClickListener(
launchApp2 -> {
tinyDB.putInt("defaultScreenId", 0);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(0),
AppDatabaseSettings.APP_LINK_HANDLER_KEY);
ctx.startActivity(mainIntent);
finish();
});

View File

@ -33,6 +33,7 @@ import org.mian.gitnex.databinding.ActivityEditIssueBinding;
import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.SnackBar;
@ -247,6 +248,10 @@ public class EditIssueActivity extends BaseActivity {
builder.setTitleText(R.string.newIssueDueDateTitle);
MaterialDatePicker<Long> materialDatePicker = builder.build();
String[] locale_ =
AppDatabaseSettings.getSettingsValue(ctx, AppDatabaseSettings.APP_LOCALE_KEY)
.split("\\|");
binding.editIssueDueDate.setOnClickListener(
v -> materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER"));
@ -255,8 +260,7 @@ public class EditIssueActivity extends BaseActivity {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(selection);
SimpleDateFormat format =
new SimpleDateFormat(
"yyyy-MM-dd", new Locale(tinyDB.getString("locale")));
new SimpleDateFormat("yyyy-MM-dd", new Locale(locale_[1]));
String formattedDate = format.format(calendar.getTime());
binding.editIssueDueDate.setText(formattedDate);
});

View File

@ -73,6 +73,7 @@ import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.fragments.BottomSheetSingleIssueFragment;
import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.ColorInverter;
@ -857,18 +858,34 @@ public class IssueDetailActivity extends BaseActivity
} else { // open
viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request);
if (tinyDB.getInt("themeId") == 3) {
if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_KEY))
== 3) {
ImageViewCompat.setImageTintList(
viewBinding.issuePrState,
ColorStateList.valueOf(
ctx.getResources()
.getColor(R.color.retroThemeColorPrimary, null)));
} else if (tinyDB.getInt("themeId") == 4) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_KEY))
== 4) {
if (TimeHelper.timeBetweenHours(
tinyDB.getInt("darkThemeTimeHour", 18),
tinyDB.getInt("lightThemeTimeHour", 6),
tinyDB.getInt("darkThemeTimeMinute", 0),
tinyDB.getInt("lightThemeTimeMinute", 0))) {
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_HOUR_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx,
AppDatabaseSettings.APP_THEME_AUTO_LIGHT_HOUR_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_MIN_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx,
AppDatabaseSettings.APP_THEME_AUTO_LIGHT_MIN_KEY)))) {
ImageViewCompat.setImageTintList(
viewBinding.issuePrState,
ColorStateList.valueOf(
@ -880,7 +897,10 @@ public class IssueDetailActivity extends BaseActivity
ctx.getResources()
.getColor(R.color.retroThemeColorPrimary, null)));
}
} else if (tinyDB.getInt("themeId") == 8) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_KEY))
== 8) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
ImageViewCompat.setImageTintList(
viewBinding.issuePrState,
@ -908,17 +928,31 @@ public class IssueDetailActivity extends BaseActivity
loadingFinishedPr = true;
updateMenuState();
viewBinding.issuePrState.setImageResource(R.drawable.ic_issue);
if (tinyDB.getInt("themeId") == 3) {
if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_KEY))
== 3) {
ImageViewCompat.setImageTintList(
viewBinding.issuePrState,
ColorStateList.valueOf(
ctx.getResources().getColor(R.color.retroThemeColorPrimary, null)));
} else if (tinyDB.getInt("themeId") == 4) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_KEY))
== 4) {
if (TimeHelper.timeBetweenHours(
tinyDB.getInt("darkThemeTimeHour", 18),
tinyDB.getInt("lightThemeTimeHour", 6),
tinyDB.getInt("darkThemeTimeMinute", 0),
tinyDB.getInt("lightThemeTimeMinute", 0))) {
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_HOUR_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_HOUR_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_MIN_KEY)),
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_MIN_KEY)))) {
ImageViewCompat.setImageTintList(
viewBinding.issuePrState,
ColorStateList.valueOf(
@ -930,7 +964,10 @@ public class IssueDetailActivity extends BaseActivity
ctx.getResources()
.getColor(R.color.retroThemeColorPrimary, null)));
}
} else if (tinyDB.getInt("themeId") == 8) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_KEY))
== 8) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
ImageViewCompat.setImageTintList(
viewBinding.issuePrState,

View File

@ -10,6 +10,7 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
@ -54,6 +55,7 @@ import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.fragments.StarredRepositoriesFragment;
import org.mian.gitnex.fragments.WatchedRepositoriesFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ChangeLog;
import org.mian.gitnex.helpers.RoundedTransformation;
@ -228,7 +230,7 @@ public class MainActivity extends BaseActivity
.observe(
(AppCompatActivity) ctx,
userAccounts -> {
if (userAccounts.size() > 0) {
if (!userAccounts.isEmpty()) {
userAccountsList.clear();
userAccountsList.addAll(userAccounts);
navRecyclerViewUserAccounts.setAdapter(
@ -246,15 +248,15 @@ public class MainActivity extends BaseActivity
String userFullNameNav = getAccount().getFullName();
String userAvatarNav = getAccount().getUserInfo().getAvatarUrl();
if (!userEmailNav.equals("")) {
if (!userEmailNav.isEmpty()) {
userEmail.setText(userEmailNav);
}
if (!userFullNameNav.equals("")) {
if (!userFullNameNav.isEmpty()) {
userFullName.setText(Html.fromHtml(userFullNameNav));
}
if (!userAvatarNav.equals("")) {
if (!userAvatarNav.isEmpty()) {
int avatarRadius = AppUtil.getPixelsFromDensity(ctx, 60);
@ -400,13 +402,9 @@ public class MainActivity extends BaseActivity
if (savedInstanceState == null) {
if (!getAccount().requiresVersion("1.12.3")) {
if (tinyDB.getInt("homeScreenId", 0) == 7) {
tinyDB.putInt("homeScreenId", 0);
}
}
switch (tinyDB.getInt("homeScreenId", 0)) {
switch (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_HOME_SCREEN_KEY))) {
case 1:
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
getSupportFragmentManager()
@ -566,6 +564,17 @@ public class MainActivity extends BaseActivity
ChangeLog changelogDialog = new ChangeLog(this);
changelogDialog.showDialog();
}
OnBackPressedCallback onBackPressedCallback =
new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
}
};
getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback);
}
@Override
@ -639,18 +648,6 @@ public class MainActivity extends BaseActivity
}
}
@Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {

View File

@ -28,6 +28,7 @@ import org.mian.gitnex.fragments.OrganizationLabelsFragment;
import org.mian.gitnex.fragments.OrganizationMembersFragment;
import org.mian.gitnex.fragments.OrganizationRepositoriesFragment;
import org.mian.gitnex.fragments.OrganizationTeamsFragment;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ViewPager2Transformers;
import org.mian.gitnex.structs.BottomSheetListener;
@ -129,7 +130,10 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
viewPager.setAdapter(new OrganizationDetailActivity.ViewPagerAdapter(this));
ViewPager2Transformers.returnSelectedTransformer(
viewPager, tinyDB.getInt("fragmentTabsAnimationId", 0));
viewPager,
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_TABS_ANIMATION_KEY)));
List<String> tabsList = new ArrayList<>();
tabsList.add(getResources().getString(R.string.tabTextInfo));

View File

@ -14,6 +14,7 @@ import org.mian.gitnex.databinding.ActivityOrgTeamInfoBinding;
import org.mian.gitnex.fragments.OrganizationTeamInfoMembersFragment;
import org.mian.gitnex.fragments.OrganizationTeamInfoPermissionsFragment;
import org.mian.gitnex.fragments.OrganizationTeamInfoReposFragment;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.ViewPager2Transformers;
/**
@ -37,6 +38,7 @@ public class OrganizationTeamInfoActivity extends BaseActivity {
team = (Team) getIntent().getSerializableExtra("team");
assert team != null;
if (team.getName() != null && !team.getName().isEmpty()) {
binding.toolbarTitle.setText(team.getName());
} else {
@ -68,7 +70,10 @@ public class OrganizationTeamInfoActivity extends BaseActivity {
});
ViewPager2Transformers.returnSelectedTransformer(
binding.pager, tinyDB.getInt("fragmentTabsAnimationId", 0));
binding.pager,
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_TABS_ANIMATION_KEY)));
new TabLayoutMediator(
binding.tabs,

View File

@ -26,6 +26,7 @@ import org.mian.gitnex.fragments.profile.FollowingFragment;
import org.mian.gitnex.fragments.profile.OrganizationsFragment;
import org.mian.gitnex.fragments.profile.RepositoriesFragment;
import org.mian.gitnex.fragments.profile.StarredRepositoriesFragment;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.ViewPager2Transformers;
@ -76,7 +77,10 @@ public class ProfileActivity extends BaseActivity implements BottomSheetListener
viewPager.setAdapter(new ViewPagerAdapter(this));
ViewPager2Transformers.returnSelectedTransformer(
viewPager, tinyDB.getInt("fragmentTabsAnimationId", 0));
viewPager,
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_TABS_ANIMATION_KEY)));
String[] tabTitles = {
ctx.getResources().getString(R.string.tabTextInfo),

View File

@ -50,6 +50,7 @@ import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.fragments.ReleasesFragment;
import org.mian.gitnex.fragments.RepoInfoFragment;
import org.mian.gitnex.fragments.WikiFragment;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.ViewPager2Transformers;
@ -539,7 +540,10 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
viewPager.setAdapter(new ViewPagerAdapter(this));
ViewPager2Transformers.returnSelectedTransformer(
viewPager, tinyDB.getInt("fragmentTabsAnimationId", 0));
viewPager,
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_TABS_ANIMATION_KEY)));
String[] tabTitles = {
ctx.getResources().getString(R.string.tabTextInfo),
@ -578,7 +582,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
}
}
if (tinyDB.getBoolean("enableCounterBadges", true)) {
if (Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(ctx, AppDatabaseSettings.APP_COUNTER_KEY))) {
@SuppressLint("InflateParams")
View tabHeader2 = LayoutInflater.from(ctx).inflate(R.layout.badge_issue, null);
if (textViewBadgeIssue == null) {

View File

@ -2,6 +2,7 @@ package org.mian.gitnex.activities;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.timepicker.MaterialTimePicker;
@ -10,10 +11,10 @@ import java.util.Locale;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsAppearanceBinding;
import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.TinyDB;
/**
* @author M M Arif
@ -21,12 +22,12 @@ import org.mian.gitnex.helpers.TinyDB;
public class SettingsAppearanceActivity extends BaseActivity {
private static String[] customFontList;
private static int customFontSelectedChoice = 0;
private static int customFontSelectedChoice;
private static String[] themeList;
private static int themeSelectedChoice = 0;
private static int langSelectedChoice = 0;
private static int themeSelectedChoice;
private static int langSelectedChoice;
private static String[] fragmentTabsAnimationList;
private static int fragmentTabsAnimationSelectedChoice = 0;
private static int fragmentTabsAnimationSelectedChoice;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -38,7 +39,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
setContentView(activitySettingsAppearanceBinding.getRoot());
LinkedHashMap<String, String> lang = new LinkedHashMap<>();
lang.put("", getString(R.string.settingsLanguageSystem));
lang.put("sys", getString(R.string.settingsLanguageSystem));
for (String langCode : getResources().getStringArray(R.array.languages)) {
lang.put(langCode, getLanguageDisplayName(langCode));
}
@ -55,8 +56,14 @@ public class SettingsAppearanceActivity extends BaseActivity {
activitySettingsAppearanceBinding.topAppBar.setNavigationOnClickListener(v -> finish());
String lightMinute = String.valueOf(tinyDB.getInt("lightThemeTimeMinute"));
String lightHour = String.valueOf(tinyDB.getInt("lightThemeTimeHour"));
String lightMinute =
String.valueOf(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_MIN_KEY));
String lightHour =
String.valueOf(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_HOUR_KEY));
if (lightMinute.length() == 1) {
lightMinute = "0" + lightMinute;
}
@ -64,8 +71,14 @@ public class SettingsAppearanceActivity extends BaseActivity {
lightHour = "0" + lightHour;
}
String darkMinute = String.valueOf(tinyDB.getInt("darkThemeTimeMinute"));
String darkHour = String.valueOf(tinyDB.getInt("darkThemeTimeHour"));
String darkMinute =
String.valueOf(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_MIN_KEY));
String darkHour =
String.valueOf(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_HOUR_KEY));
if (darkMinute.length() == 1) {
darkMinute = "0" + darkMinute;
}
@ -73,9 +86,18 @@ public class SettingsAppearanceActivity extends BaseActivity {
darkHour = "0" + darkHour;
}
fragmentTabsAnimationSelectedChoice = tinyDB.getInt("fragmentTabsAnimationId", 0);
customFontSelectedChoice = tinyDB.getInt("customFontId", 1);
themeSelectedChoice = tinyDB.getInt("themeId", 6); // use system theme as default
fragmentTabsAnimationSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_TABS_ANIMATION_KEY));
customFontSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_FONT_KEY));
themeSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_KEY));
activitySettingsAppearanceBinding.lightThemeSelectedTime.setText(
ctx.getResources()
@ -100,12 +122,15 @@ public class SettingsAppearanceActivity extends BaseActivity {
}
activitySettingsAppearanceBinding.switchCounterBadge.setChecked(
tinyDB.getBoolean("enableCounterBadges", true));
Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_COUNTER_KEY)));
// counter badge switcher
activitySettingsAppearanceBinding.switchCounterBadge.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
tinyDB.putBoolean("enableCounterBadges", isChecked);
AppDatabaseSettings.updateSettingsValue(
ctx, String.valueOf(isChecked), AppDatabaseSettings.APP_COUNTER_KEY);
SnackBar.success(
ctx,
findViewById(android.R.id.content),
@ -118,11 +143,16 @@ public class SettingsAppearanceActivity extends BaseActivity {
// show labels in lists(issues, pr) - default is color dots
activitySettingsAppearanceBinding.switchLabelsInListBadge.setChecked(
tinyDB.getBoolean("showLabelsInList", false));
Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_LABELS_IN_LIST_KEY)));
activitySettingsAppearanceBinding.switchLabelsInListBadge.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
tinyDB.putBoolean("showLabelsInList", isChecked);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(isChecked),
AppDatabaseSettings.APP_LABELS_IN_LIST_KEY);
SnackBar.success(
ctx,
findViewById(android.R.id.content),
@ -147,7 +177,10 @@ public class SettingsAppearanceActivity extends BaseActivity {
themeSelectedChoice = i;
activitySettingsAppearanceBinding.themeSelected
.setText(themeList[i]);
tinyDB.putInt("themeId", i);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings.APP_THEME_KEY);
SettingsFragment.refreshParent = true;
this.recreate();
@ -182,13 +215,26 @@ public class SettingsAppearanceActivity extends BaseActivity {
customFontSelectedChoice = i;
activitySettingsAppearanceBinding.customFontSelected
.setText(customFontList[i]);
tinyDB.putInt("customFontId", i);
AppUtil.typeface = null; // reset typeface
FontsOverride.setDefaultFont(this);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings.APP_FONT_KEY);
new Handler()
.postDelayed(
() -> {
AppUtil.typeface =
null; // reset typeface
FontsOverride.setDefaultFont(
this);
SettingsFragment.refreshParent =
true;
this.recreate();
this.overridePendingTransition(
0, 0);
},
1000);
SettingsFragment.refreshParent = true;
this.recreate();
this.overridePendingTransition(0, 0);
dialogInterfaceCustomFont.dismiss();
SnackBar.success(
ctx,
@ -209,19 +255,20 @@ public class SettingsAppearanceActivity extends BaseActivity {
.setSingleChoiceItems(
fragmentTabsAnimationList,
fragmentTabsAnimationSelectedChoice,
(dialogInterfaceCustomFont, i) -> {
(dialogInterfaceTabsAnimation, i) -> {
fragmentTabsAnimationSelectedChoice = i;
activitySettingsAppearanceBinding
.fragmentTabsAnimationFrameSelected.setText(
fragmentTabsAnimationList[i]);
tinyDB.putInt("fragmentTabsAnimationId", i);
AppUtil.typeface = null; // reset typeface
FontsOverride.setDefaultFont(this);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings.APP_TABS_ANIMATION_KEY);
SettingsFragment.refreshParent = true;
this.recreate();
this.overridePendingTransition(0, 0);
dialogInterfaceCustomFont.dismiss();
dialogInterfaceTabsAnimation.dismiss();
SnackBar.success(
ctx,
findViewById(android.R.id.content),
@ -237,7 +284,10 @@ public class SettingsAppearanceActivity extends BaseActivity {
AppUtil.openUrlInBrowser(
this, getResources().getString(R.string.crowdInLink)));
langSelectedChoice = tinyDB.getInt("langId");
String[] locale =
AppDatabaseSettings.getSettingsValue(ctx, AppDatabaseSettings.APP_LOCALE_KEY)
.split("\\|");
langSelectedChoice = Integer.parseInt(locale[0]);
activitySettingsAppearanceBinding.tvLanguageSelected.setText(
lang.get(lang.keySet().toArray(new String[0])[langSelectedChoice]));
@ -255,8 +305,10 @@ public class SettingsAppearanceActivity extends BaseActivity {
(dialogInterface, i) -> {
String selectedLanguage =
lang.keySet().toArray(new String[0])[i];
tinyDB.putInt("langId", i);
tinyDB.putString("locale", selectedLanguage);
AppDatabaseSettings.updateSettingsValue(
ctx,
i + "|" + selectedLanguage,
AppDatabaseSettings.APP_LOCALE_KEY);
SettingsFragment.refreshParent = true;
this.overridePendingTransition(0, 0);
@ -274,18 +326,28 @@ public class SettingsAppearanceActivity extends BaseActivity {
public void lightTimePicker() {
TinyDB db = TinyDB.getInstance(ctx);
int hour = db.getInt("lightThemeTimeHour");
int minute = db.getInt("lightThemeTimeMinute");
int hour =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_HOUR_KEY));
int minute =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_LIGHT_MIN_KEY));
MaterialTimePicker materialTimePicker =
new MaterialTimePicker.Builder().setHour(hour).setMinute(minute).build();
materialTimePicker.addOnPositiveButtonClickListener(
selection -> {
db.putInt("lightThemeTimeHour", materialTimePicker.getHour());
db.putInt("lightThemeTimeMinute", materialTimePicker.getMinute());
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(materialTimePicker.getHour()),
AppDatabaseSettings.APP_THEME_AUTO_LIGHT_HOUR_KEY);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(materialTimePicker.getMinute()),
AppDatabaseSettings.APP_THEME_AUTO_LIGHT_MIN_KEY);
SettingsFragment.refreshParent = true;
overridePendingTransition(0, 0);
SnackBar.success(
@ -300,18 +362,28 @@ public class SettingsAppearanceActivity extends BaseActivity {
public void darkTimePicker() {
TinyDB db = TinyDB.getInstance(ctx);
int hour = db.getInt("darkThemeTimeHour");
int minute = db.getInt("darkThemeTimeMinute");
int hour =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_HOUR_KEY));
int minute =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_THEME_AUTO_DARK_MIN_KEY));
MaterialTimePicker materialTimePicker =
new MaterialTimePicker.Builder().setHour(hour).setMinute(minute).build();
materialTimePicker.addOnPositiveButtonClickListener(
selection -> {
db.putInt("darkThemeTimeHour", materialTimePicker.getHour());
db.putInt("darkThemeTimeMinute", materialTimePicker.getMinute());
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(materialTimePicker.getHour()),
AppDatabaseSettings.APP_THEME_AUTO_DARK_HOUR_KEY);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(materialTimePicker.getMinute()),
AppDatabaseSettings.APP_THEME_AUTO_DARK_MIN_KEY);
SettingsFragment.refreshParent = true;
overridePendingTransition(0, 0);
SnackBar.success(
@ -326,7 +398,17 @@ public class SettingsAppearanceActivity extends BaseActivity {
private static String getLanguageDisplayName(String langCode) {
Locale english = new Locale("en");
Locale translated = new Locale(langCode);
String[] multiCodeLang = langCode.split("-");
String countryCode;
if (langCode.contains("-")) {
langCode = multiCodeLang[0];
countryCode = multiCodeLang[1];
} else {
countryCode = "";
}
Locale translated = new Locale(langCode, countryCode);
return String.format(
"%s (%s)",
translated.getDisplayName(translated), translated.getDisplayName(english));

View File

@ -6,6 +6,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsCodeEditorBinding;
import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.SnackBar;
/**
@ -14,11 +15,11 @@ import org.mian.gitnex.helpers.SnackBar;
public class SettingsCodeEditorActivity extends BaseActivity {
private static String[] colorList;
private static int colorSelectedChoice = 0;
private static int colorSelectedChoice;
private static String[] indentationList;
private static int indentationSelectedChoice = 0;
private static int indentationSelectedChoice;
private static String[] indentationTabsList;
private static int indentationTabsSelectedChoice = 0;
private static int indentationTabsSelectedChoice;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -33,7 +34,10 @@ public class SettingsCodeEditorActivity extends BaseActivity {
// color selector dialog
colorList = getResources().getStringArray(R.array.ceColors);
colorSelectedChoice = tinyDB.getInt("ceColorId");
colorSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_CE_SYNTAX_HIGHLIGHT_KEY));
activitySettingsCodeEditorBinding.ceColorSelected.setText(colorList[colorSelectedChoice]);
activitySettingsCodeEditorBinding.ceColorSelectionFrame.setOnClickListener(
@ -48,7 +52,11 @@ public class SettingsCodeEditorActivity extends BaseActivity {
colorSelectedChoice = i;
activitySettingsCodeEditorBinding.ceColorSelected
.setText(colorList[i]);
tinyDB.putInt("ceColorId", i);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings
.APP_CE_SYNTAX_HIGHLIGHT_KEY);
SettingsFragment.refreshParent = true;
this.recreate();
@ -65,7 +73,10 @@ public class SettingsCodeEditorActivity extends BaseActivity {
// indentation selector dialog
indentationList = getResources().getStringArray(R.array.ceIndentation);
indentationSelectedChoice = tinyDB.getInt("ceIndentationId");
indentationSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_CE_INDENTATION_KEY));
activitySettingsCodeEditorBinding.indentationSelected.setText(
indentationList[indentationSelectedChoice]);
@ -82,7 +93,10 @@ public class SettingsCodeEditorActivity extends BaseActivity {
activitySettingsCodeEditorBinding
.indentationSelected.setText(
indentationList[i]);
tinyDB.putInt("ceIndentationId", i);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings.APP_CE_INDENTATION_KEY);
SettingsFragment.refreshParent = true;
this.recreate();
@ -107,7 +121,10 @@ public class SettingsCodeEditorActivity extends BaseActivity {
}
indentationTabsList = getResources().getStringArray(R.array.ceIndentationTabsWidth);
indentationTabsSelectedChoice = tinyDB.getInt("ceIndentationTabsId");
indentationTabsSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_CE_TABS_WIDTH_KEY));
activitySettingsCodeEditorBinding.indentationTabsSelected.setText(
indentationTabsList[indentationTabsSelectedChoice]);
@ -124,7 +141,10 @@ public class SettingsCodeEditorActivity extends BaseActivity {
activitySettingsCodeEditorBinding
.indentationTabsSelected.setText(
indentationTabsList[i]);
tinyDB.putInt("ceIndentationTabsId", i);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings.APP_CE_TABS_WIDTH_KEY);
SettingsFragment.refreshParent = true;
this.recreate();

View File

@ -7,6 +7,7 @@ import java.util.Arrays;
import java.util.List;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsGeneralBinding;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.SnackBar;
/**
@ -14,11 +15,9 @@ import org.mian.gitnex.helpers.SnackBar;
*/
public class SettingsGeneralActivity extends BaseActivity {
private static int homeScreenSelectedChoice = 0;
private static int defaultLinkHandlerScreenSelectedChoice = 0;
private static int homeScreenSelectedChoice;
private static int defaultLinkHandlerScreenSelectedChoice;
private ActivitySettingsGeneralBinding viewBinding;
private List<String> homeScreenList;
private List<String> linkHandlerDefaultScreen;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -31,73 +30,15 @@ public class SettingsGeneralActivity extends BaseActivity {
viewBinding.topAppBar.setNavigationOnClickListener(v -> finish());
// home screen
String[] appHomeDefaultScreen = getResources().getStringArray(R.array.appDefaultHomeScreen);
String[] appHomeDefaultScreenNew =
String[] appHomeDefaultScreen =
getResources().getStringArray(R.array.appDefaultHomeScreenNew);
if (getAccount().requiresVersion("1.12.3")) {
homeScreenSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_HOME_SCREEN_KEY));
appHomeDefaultScreen = appHomeDefaultScreenNew;
}
homeScreenList = new ArrayList<>(Arrays.asList(appHomeDefaultScreen));
if (!getAccount().requiresVersion("1.14.0")) {
homeScreenList.remove(8);
}
String[] homeScreenArray = new String[homeScreenList.size()];
homeScreenList.toArray(homeScreenArray);
if (homeScreenSelectedChoice == 0) {
homeScreenSelectedChoice = tinyDB.getInt("homeScreenId", 0);
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.navMyRepos));
}
if (homeScreenSelectedChoice == 1) {
viewBinding.homeScreenSelected.setText(
getResources().getString(R.string.pageTitleStarredRepos));
} else if (homeScreenSelectedChoice == 2) {
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.navOrg));
} else if (homeScreenSelectedChoice == 3) {
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.navRepos));
} else if (homeScreenSelectedChoice == 4) {
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.navAccount));
} else if (homeScreenSelectedChoice == 5) {
viewBinding.homeScreenSelected.setText(
getResources().getString(R.string.pageTitleExplore));
} else if (homeScreenSelectedChoice == 6) {
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.titleDrafts));
} else if (homeScreenSelectedChoice == 7) {
viewBinding.homeScreenSelected.setText(
getResources().getString(R.string.pageTitleNotifications));
} else if (homeScreenSelectedChoice == 8) {
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.navMyIssues));
} else if (homeScreenSelectedChoice == 9) {
viewBinding.homeScreenSelected.setText(
getResources().getString(R.string.navMostVisited));
} else if (homeScreenSelectedChoice == 10) {
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.navNotes));
} else if (homeScreenSelectedChoice == 11) {
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.dashboard));
} else if (homeScreenSelectedChoice == 12) {
viewBinding.homeScreenSelected.setText(
getResources().getString(R.string.navWatchedRepositories));
}
viewBinding.homeScreenSelected.setText(appHomeDefaultScreen[homeScreenSelectedChoice]);
viewBinding.homeScreenFrame.setOnClickListener(
setDefaultHomeScreen -> {
@ -106,13 +47,17 @@ public class SettingsGeneralActivity extends BaseActivity {
.setTitle(R.string.settingsHomeScreenSelectorDialogTitle)
.setCancelable(homeScreenSelectedChoice != -1)
.setSingleChoiceItems(
homeScreenArray,
appHomeDefaultScreen,
homeScreenSelectedChoice,
(dialogInterfaceHomeScreen, i) -> {
homeScreenSelectedChoice = i;
viewBinding.homeScreenSelected.setText(
homeScreenArray[i]);
tinyDB.putInt("homeScreenId", i);
appHomeDefaultScreen[i]);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings.APP_HOME_SCREEN_KEY);
dialogInterfaceHomeScreen.dismiss();
SnackBar.success(
@ -128,12 +73,16 @@ public class SettingsGeneralActivity extends BaseActivity {
// link handler
String[] linkHandlerDefaultScreenList =
getResources().getStringArray(R.array.linkHandlerDefaultScreen);
linkHandlerDefaultScreen = new ArrayList<>(Arrays.asList(linkHandlerDefaultScreenList));
List<String> linkHandlerDefaultScreen =
new ArrayList<>(Arrays.asList(linkHandlerDefaultScreenList));
String[] linksArray = new String[linkHandlerDefaultScreen.size()];
linkHandlerDefaultScreen.toArray(linksArray);
defaultLinkHandlerScreenSelectedChoice = tinyDB.getInt("defaultScreenId");
defaultLinkHandlerScreenSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_LINK_HANDLER_KEY));
viewBinding.generalDeepLinkSelected.setText(
linksArray[defaultLinkHandlerScreenSelectedChoice]);
@ -150,7 +99,11 @@ public class SettingsGeneralActivity extends BaseActivity {
defaultLinkHandlerScreenSelectedChoice = i;
viewBinding.generalDeepLinkSelected.setText(
linksArray[i]);
tinyDB.putInt("defaultScreenId", i);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings.APP_LINK_HANDLER_KEY);
dialogInterfaceHomeScreen.dismiss();
SnackBar.success(
@ -163,11 +116,17 @@ public class SettingsGeneralActivity extends BaseActivity {
});
// link handler
// custom tabs
viewBinding.switchTabs.setChecked(tinyDB.getBoolean("useCustomTabs"));
// custom tabs switcher
viewBinding.switchTabs.setChecked(
Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_CUSTOM_BROWSER_KEY)));
viewBinding.switchTabs.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
tinyDB.putBoolean("useCustomTabs", isChecked);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(isChecked),
AppDatabaseSettings.APP_CUSTOM_BROWSER_KEY);
SnackBar.success(
ctx,
findViewById(android.R.id.content),
@ -175,16 +134,19 @@ public class SettingsGeneralActivity extends BaseActivity {
});
viewBinding.customTabsFrame.setOnClickListener(
v -> viewBinding.switchTabs.setChecked(!viewBinding.switchTabs.isChecked()));
// custom tabs
// custom tabs switcher
// enable drafts deletion
// drafts deletion switcher
viewBinding.commentsDeletionSwitch.setChecked(
tinyDB.getBoolean("draftsCommentsDeletionEnabled", true));
// delete comments on submit switcher
Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_DRAFTS_DELETION_KEY)));
viewBinding.commentsDeletionSwitch.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
tinyDB.putBoolean("draftsCommentsDeletionEnabled", isChecked);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(isChecked),
AppDatabaseSettings.APP_DRAFTS_DELETION_KEY);
SnackBar.success(
ctx,
findViewById(android.R.id.content),
@ -194,12 +156,19 @@ public class SettingsGeneralActivity extends BaseActivity {
v ->
viewBinding.commentsDeletionSwitch.setChecked(
!viewBinding.commentsDeletionSwitch.isChecked()));
// enable drafts deletion
// drafts deletion switcher
// crash reports switcher
viewBinding.crashReportsSwitch.setChecked(
Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_CRASH_REPORTS_KEY)));
viewBinding.crashReportsSwitch.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
tinyDB.putBoolean("crashReportingEnabled", isChecked);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(isChecked),
AppDatabaseSettings.APP_CRASH_REPORTS_KEY);
SnackBar.success(
ctx,
findViewById(android.R.id.content),

View File

@ -6,6 +6,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding;
import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.notifications.Notifications;
@ -18,7 +19,7 @@ public class SettingsNotificationsActivity extends BaseActivity {
private ActivitySettingsNotificationsBinding viewBinding;
private static String[] pollingDelayList;
private static int pollingDelayListSelectedChoice = 0;
private static int pollingDelayListSelectedChoice;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -31,7 +32,9 @@ public class SettingsNotificationsActivity extends BaseActivity {
viewBinding.topAppBar.setNavigationOnClickListener(v -> finish());
viewBinding.enableNotificationsMode.setChecked(
tinyDB.getBoolean("notificationsEnabled", true));
Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_NOTIFICATIONS_KEY)));
if (!viewBinding.enableNotificationsMode.isChecked()) {
AppUtil.setMultiVisibility(View.GONE, viewBinding.pollingDelayFrame);
@ -39,7 +42,10 @@ public class SettingsNotificationsActivity extends BaseActivity {
viewBinding.enableNotificationsMode.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
tinyDB.putBoolean("notificationsEnabled", isChecked);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(isChecked),
AppDatabaseSettings.APP_NOTIFICATIONS_KEY);
if (isChecked) {
Notifications.startWorker(ctx);
@ -61,7 +67,10 @@ public class SettingsNotificationsActivity extends BaseActivity {
// polling delay
pollingDelayList = getResources().getStringArray(R.array.notificationsPollingDelay);
pollingDelayListSelectedChoice = tinyDB.getInt("notificationsPollingDelayId");
pollingDelayListSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY));
viewBinding.pollingDelaySelected.setText(pollingDelayList[pollingDelayListSelectedChoice]);
viewBinding.pollingDelayFrame.setOnClickListener(
@ -77,7 +86,12 @@ public class SettingsNotificationsActivity extends BaseActivity {
viewBinding.pollingDelaySelected.setText(
pollingDelayList[
pollingDelayListSelectedChoice]);
tinyDB.putInt("notificationsPollingDelayId", i);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings
.APP_NOTIFICATIONS_DELAY_KEY);
Notifications.stopWorker(ctx);
Notifications.startWorker(ctx);

View File

@ -13,6 +13,7 @@ import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsSecurityBinding;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
@ -23,9 +24,9 @@ import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
public class SettingsSecurityActivity extends BaseActivity {
private static String[] cacheSizeDataList;
private static int cacheSizeDataSelectedChoice = 0;
private static int cacheSizeDataSelectedChoice;
private static String[] cacheSizeImagesList;
private static int cacheSizeImagesSelectedChoice = 0;
private static int cacheSizeImagesSelectedChoice;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -41,26 +42,24 @@ public class SettingsSecurityActivity extends BaseActivity {
cacheSizeDataList = getResources().getStringArray(R.array.cacheSizeList);
cacheSizeImagesList = getResources().getStringArray(R.array.cacheSizeList);
cacheSizeDataSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_DATA_CACHE_KEY));
cacheSizeImagesSelectedChoice =
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_IMAGES_CACHE_KEY));
activitySettingsSecurityBinding.cacheSizeDataSelected.setText(
tinyDB.getString(
"cacheSizeStr", getString(R.string.cacheSizeDataSelectionSelectedText)));
cacheSizeDataList[cacheSizeDataSelectedChoice]);
activitySettingsSecurityBinding.cacheSizeImagesSelected.setText(
tinyDB.getString(
"cacheSizeImagesStr",
getString(R.string.cacheSizeImagesSelectionSelectedText)));
if (cacheSizeDataSelectedChoice == 0) {
cacheSizeDataSelectedChoice = tinyDB.getInt("cacheSizeId");
}
if (cacheSizeImagesSelectedChoice == 0) {
cacheSizeImagesSelectedChoice = tinyDB.getInt("cacheSizeImagesId");
}
cacheSizeImagesList[cacheSizeImagesSelectedChoice]);
activitySettingsSecurityBinding.switchBiometric.setChecked(
tinyDB.getBoolean("biometricStatus", false));
Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_BIOMETRIC_KEY)));
// biometric switcher
activitySettingsSecurityBinding.switchBiometric.setOnCheckedChangeListener(
@ -76,7 +75,8 @@ public class SettingsSecurityActivity extends BaseActivity {
switch (biometricManager.canAuthenticate(
BIOMETRIC_STRONG | DEVICE_CREDENTIAL)) {
case BiometricManager.BIOMETRIC_SUCCESS:
tinyDB.putBoolean("biometricStatus", true);
AppDatabaseSettings.updateSettingsValue(
ctx, "true", AppDatabaseSettings.APP_BIOMETRIC_KEY);
SnackBar.success(
ctx,
findViewById(android.R.id.content),
@ -86,7 +86,8 @@ public class SettingsSecurityActivity extends BaseActivity {
case BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED:
case BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED:
case BiometricManager.BIOMETRIC_STATUS_UNKNOWN:
tinyDB.putBoolean("biometricStatus", false);
AppDatabaseSettings.updateSettingsValue(
ctx, "false", AppDatabaseSettings.APP_BIOMETRIC_KEY);
activitySettingsSecurityBinding.switchBiometric.setChecked(
false);
SnackBar.error(
@ -95,7 +96,8 @@ public class SettingsSecurityActivity extends BaseActivity {
getString(R.string.biometricNotSupported));
break;
case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
tinyDB.putBoolean("biometricStatus", false);
AppDatabaseSettings.updateSettingsValue(
ctx, "false", AppDatabaseSettings.APP_BIOMETRIC_KEY);
activitySettingsSecurityBinding.switchBiometric.setChecked(
false);
SnackBar.error(
@ -104,7 +106,8 @@ public class SettingsSecurityActivity extends BaseActivity {
getString(R.string.biometricNotAvailable));
break;
case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
tinyDB.putBoolean("biometricStatus", false);
AppDatabaseSettings.updateSettingsValue(
ctx, "false", AppDatabaseSettings.APP_BIOMETRIC_KEY);
activitySettingsSecurityBinding.switchBiometric.setChecked(
false);
SnackBar.info(
@ -115,7 +118,8 @@ public class SettingsSecurityActivity extends BaseActivity {
}
} else {
tinyDB.putBoolean("biometricStatus", true);
AppDatabaseSettings.updateSettingsValue(
ctx, "true", AppDatabaseSettings.APP_BIOMETRIC_KEY);
SnackBar.success(
ctx,
findViewById(android.R.id.content),
@ -123,7 +127,8 @@ public class SettingsSecurityActivity extends BaseActivity {
}
} else {
tinyDB.putBoolean("biometricStatus", false);
AppDatabaseSettings.updateSettingsValue(
ctx, "false", AppDatabaseSettings.APP_BIOMETRIC_KEY);
SnackBar.success(
ctx,
findViewById(android.R.id.content),
@ -186,10 +191,16 @@ public class SettingsSecurityActivity extends BaseActivity {
activitySettingsSecurityBinding
.cacheSizeImagesSelected.setText(
cacheSizeImagesList[i]);
tinyDB.putString(
"cacheSizeImagesStr",
cacheSizeImagesList[i]);
tinyDB.putInt("cacheSizeImagesId", i);
AppDatabaseSettings.updateSettingsValue(
ctx,
cacheSizeImagesList[i],
AppDatabaseSettings
.APP_IMAGES_CACHE_SIZE_KEY);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings.APP_IMAGES_CACHE_KEY);
dialogInterfaceTheme.dismiss();
SnackBar.success(
@ -216,9 +227,16 @@ public class SettingsSecurityActivity extends BaseActivity {
activitySettingsSecurityBinding
.cacheSizeDataSelected.setText(
cacheSizeDataList[i]);
tinyDB.putString(
"cacheSizeStr", cacheSizeDataList[i]);
tinyDB.putInt("cacheSizeId", i);
AppDatabaseSettings.updateSettingsValue(
ctx,
cacheSizeDataList[i],
AppDatabaseSettings
.APP_DATA_CACHE_SIZE_KEY);
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(i),
AppDatabaseSettings.APP_DATA_CACHE_KEY);
dialogInterfaceTheme.dismiss();
SnackBar.success(

View File

@ -27,6 +27,7 @@ import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.ColorInverter;
@ -239,7 +240,9 @@ public class ExploreIssuesAdapter extends RecyclerView.Adapter<RecyclerView.View
if (issue.getLabels() != null) {
if (!tinyDb.getBoolean("showLabelsInList", false)) { // default
if (!Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_LABELS_IN_LIST_KEY))) {
labelsScrollViewWithText.setVisibility(View.GONE);
labelsScrollViewDots.setVisibility(View.VISIBLE);

View File

@ -29,6 +29,7 @@ import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.ColorInverter;
@ -212,7 +213,9 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
if (issue.getLabels() != null) {
if (!tinyDb.getBoolean("showLabelsInList", false)) { // default
if (!Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_LABELS_IN_LIST_KEY))) {
labelsScrollViewWithText.setVisibility(View.GONE);
labelsScrollViewDots.setVisibility(View.VISIBLE);

View File

@ -31,6 +31,7 @@ import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.ColorInverter;
@ -206,7 +207,9 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
if (pullRequest.getLabels() != null) {
if (!tinyDb.getBoolean("showLabelsInList", false)) { // default
if (!Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_LABELS_IN_LIST_KEY))) {
labelsScrollViewWithText.setVisibility(View.GONE);
labelsScrollViewDots.setVisibility(View.VISIBLE);

View File

@ -34,11 +34,10 @@ import org.gitnex.tea4j.v2.apis.custom.OTPApi;
import org.gitnex.tea4j.v2.apis.custom.WebApi;
import org.gitnex.tea4j.v2.auth.ApiKeyAuth;
import org.jetbrains.annotations.NotNull;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FilesData;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import retrofit2.Converter;
import retrofit2.Retrofit;
@ -60,8 +59,6 @@ public class RetrofitClient {
String token,
File cacheFile) {
TinyDB tinyDB = TinyDB.getInstance(context);
// HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// logging.setLevel(HttpLoggingInterceptor.Level.BODY);
@ -88,11 +85,9 @@ public class RetrofitClient {
int cacheSize =
FilesData.returnOnlyNumberFileSize(
tinyDB.getString(
"cacheSizeStr",
context.getString(
R.string
.cacheSizeDataSelectionSelectedText)))
AppDatabaseSettings.getSettingsValue(
context,
AppDatabaseSettings.APP_DATA_CACHE_SIZE_KEY))
* 1024
* 1024;
Cache cache = new Cache(cacheFile, cacheSize);

View File

@ -13,6 +13,7 @@ import org.acra.config.NotificationConfigurationBuilder;
import org.acra.data.StringFormat;
import org.mian.gitnex.R;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.TinyDB;
@ -37,7 +38,15 @@ public class MainApplication extends Application {
currentAccount = AccountContext.fromId(tinyDB.getInt("currentActiveAccountId", 0), appCtx);
tinyDB.putBoolean("biometricLifeCycle", false);
AppDatabaseSettings.initDefaultSettings(getApplicationContext());
if (Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(getApplicationContext(), "prefsMigration"))) {
AppDatabaseSettings.prefsMigration(getApplicationContext());
}
AppDatabaseSettings.updateSettingsValue(
getApplicationContext(), "false", AppDatabaseSettings.APP_BIOMETRIC_LIFE_CYCLE_KEY);
FontsOverride.setDefaultFont(getBaseContext());
@ -52,7 +61,9 @@ public class MainApplication extends Application {
tinyDB = TinyDB.getInstance(context);
if (tinyDB.getBoolean("crashReportingEnabled", true)) {
if (Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_CRASH_REPORTS_KEY))) {
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder();

View File

@ -0,0 +1,72 @@
package org.mian.gitnex.database.api;
import android.content.Context;
import androidx.lifecycle.LiveData;
import java.util.List;
import org.mian.gitnex.database.dao.AppSettingsDao;
import org.mian.gitnex.database.models.AppSettings;
/**
* @author M M Arif
*/
public class AppSettingsApi extends BaseApi {
private final AppSettingsDao appSettingsDao;
AppSettingsApi(Context context) {
super(context);
appSettingsDao = gitnexDatabase.appSettingsDao();
}
public long insertNewSetting(String settingKey, String settingValue, String settingDefault) {
AppSettings appSettings = new AppSettings();
appSettings.setSettingKey(settingKey);
appSettings.setSettingValue(settingValue);
appSettings.setSettingDefault(settingDefault);
return insertSettingAsyncTask(appSettings);
}
public long insertSettingAsyncTask(AppSettings appSettings) {
return appSettingsDao.insertNewSetting(appSettings);
}
public LiveData<List<AppSettings>> fetchAllSettings() {
return appSettingsDao.fetchAllSettings();
}
public AppSettings fetchSettingById(int settingId) {
return appSettingsDao.fetchSettingById(settingId);
}
public AppSettings fetchSettingByKey(String settingKey) {
return appSettingsDao.fetchSettingByKey(settingKey);
}
public Integer fetchTotalSettingsCount() {
return appSettingsDao.fetchTotalSettingsCount();
}
public Integer fetchSettingCountByKey(String settingKey) {
return appSettingsDao.fetchSettingCountByKey(settingKey);
}
public void updateSettingValueByKey(String settingValue, String settingKey) {
executorService.execute(
() -> appSettingsDao.updateSettingValueByKey(settingValue, settingKey));
}
public void updateSettingDefaultByKey(String settingDefault, String settingKey) {
executorService.execute(
() -> appSettingsDao.updateSettingDefaultByKey(settingDefault, settingKey));
}
public void deleteBySettingKey(final String settingKey) {
final AppSettings appSettings = appSettingsDao.fetchSettingByKey(settingKey);
if (appSettings != null) {
executorService.execute(() -> appSettingsDao.deleteBySettingKey(settingKey));
}
}
}

View File

@ -0,0 +1,42 @@
package org.mian.gitnex.database.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import java.util.List;
import org.mian.gitnex.database.models.AppSettings;
/**
* @author M M Arif
*/
@Dao
public interface AppSettingsDao {
@Insert
long insertNewSetting(AppSettings appSettings);
@Query("SELECT * FROM AppSettings")
LiveData<List<AppSettings>> fetchAllSettings();
@Query("SELECT * FROM AppSettings WHERE settingId = :settingId")
AppSettings fetchSettingById(int settingId);
@Query("SELECT * FROM AppSettings WHERE settingKey = :settingKey")
AppSettings fetchSettingByKey(String settingKey);
@Query("SELECT count(settingId) FROM AppSettings")
Integer fetchTotalSettingsCount();
@Query("SELECT count(settingId) FROM AppSettings WHERE settingKey = :settingKey")
Integer fetchSettingCountByKey(String settingKey);
@Query("UPDATE AppSettings SET settingValue = :settingValue WHERE settingKey = :settingKey")
void updateSettingValueByKey(String settingValue, String settingKey);
@Query("UPDATE AppSettings SET settingDefault = :settingDefault WHERE settingKey = :settingKey")
void updateSettingDefaultByKey(String settingDefault, String settingKey);
@Query("DELETE FROM AppSettings WHERE settingKey = :settingKey")
void deleteBySettingKey(String settingKey);
}

View File

@ -7,10 +7,12 @@ import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
import org.mian.gitnex.database.dao.AppSettingsDao;
import org.mian.gitnex.database.dao.DraftsDao;
import org.mian.gitnex.database.dao.NotesDao;
import org.mian.gitnex.database.dao.RepositoriesDao;
import org.mian.gitnex.database.dao.UserAccountsDao;
import org.mian.gitnex.database.models.AppSettings;
import org.mian.gitnex.database.models.Draft;
import org.mian.gitnex.database.models.Notes;
import org.mian.gitnex.database.models.Repository;
@ -20,8 +22,14 @@ import org.mian.gitnex.database.models.UserAccount;
* @author M M Arif
*/
@Database(
entities = {Draft.class, Repository.class, UserAccount.class, Notes.class},
version = 7,
entities = {
Draft.class,
Repository.class,
UserAccount.class,
Notes.class,
AppSettings.class
},
version = 8,
exportSchema = false)
public abstract class GitnexDatabase extends RoomDatabase {
@ -79,6 +87,16 @@ public abstract class GitnexDatabase extends RoomDatabase {
"CREATE TABLE IF NOT EXISTS 'Notes' ('noteId' INTEGER NOT NULL, 'content' TEXT, 'datetime' INTEGER, 'modified' INTEGER, PRIMARY KEY('noteid'))");
}
};
private static final Migration MIGRATION_7_8 =
new Migration(7, 8) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL(
"CREATE TABLE IF NOT EXISTS 'appSettings' ('settingId' INTEGER NOT NULL, 'settingKey' TEXT, 'settingValue' TEXT, 'settingDefault' TEXT, PRIMARY KEY('settingId'))");
}
};
private static volatile GitnexDatabase gitnexDatabase;
public static GitnexDatabase getDatabaseInstance(Context context) {
@ -97,7 +115,8 @@ public abstract class GitnexDatabase extends RoomDatabase {
MIGRATION_3_4,
MIGRATION_4_5,
MIGRATION_5_6,
MIGRATION_6_7)
MIGRATION_6_7,
MIGRATION_7_8)
.build();
}
}
@ -113,4 +132,6 @@ public abstract class GitnexDatabase extends RoomDatabase {
public abstract UserAccountsDao userAccountsDao();
public abstract NotesDao notesDao();
public abstract AppSettingsDao appSettingsDao();
}

View File

@ -0,0 +1,52 @@
package org.mian.gitnex.database.models;
import androidx.annotation.Nullable;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import java.io.Serializable;
/**
* @author M M Arif
*/
@Entity(tableName = "appSettings")
public class AppSettings implements Serializable {
@PrimaryKey(autoGenerate = true)
private int settingId;
private String settingKey;
private String settingValue;
@Nullable private String settingDefault;
public int getSettingId() {
return settingId;
}
public void setSettingId(int settingId) {
this.settingId = settingId;
}
@Nullable public String getSettingKey() {
return settingKey;
}
public void setSettingKey(@Nullable String settingKey) {
this.settingKey = settingKey;
}
public String getSettingValue() {
return settingValue;
}
public void setSettingValue(String settingValue) {
this.settingValue = settingValue;
}
public String getSettingDefault() {
return settingDefault;
}
public void setSettingDefault(String settingDefault) {
this.settingDefault = settingDefault;
}
}

View File

@ -17,8 +17,8 @@ import com.google.android.material.tabs.TabLayoutMediator;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.ViewPager2Transformers;
import org.mian.gitnex.helpers.contexts.AccountContext;
@ -31,7 +31,6 @@ public class AccountSettingsFragment extends Fragment {
private Context ctx;
private View view;
private Typeface myTypeface;
private TinyDB tinyDB;
@Nullable @Override
public View onCreateView(
@ -40,7 +39,6 @@ public class AccountSettingsFragment extends Fragment {
@Nullable Bundle savedInstanceState) {
ctx = getContext();
tinyDB = TinyDB.getInstance(ctx);
view = inflater.inflate(R.layout.fragment_account_settings, container, false);
setHasOptionsMenu(false);
@ -76,7 +74,10 @@ public class AccountSettingsFragment extends Fragment {
viewPager.setAdapter(new ViewPagerAdapter(this));
ViewPager2Transformers.returnSelectedTransformer(
viewPager, tinyDB.getInt("fragmentTabsAnimationId", 0));
viewPager,
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_TABS_ANIMATION_KEY)));
String[] tabTitles = {
ctx.getResources().getString(R.string.accountEmails),

View File

@ -31,6 +31,7 @@ import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.databinding.BottomSheetReplyLayoutBinding;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
@ -202,9 +203,12 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
getString(R.string.commentSuccess));
if (draftId != 0
&& tinyDB.getBoolean(
"draftsCommentsDeletionEnabled",
true)) {
&& Boolean.parseBoolean(
AppDatabaseSettings
.getSettingsValue(
getContext(),
AppDatabaseSettings
.APP_DRAFTS_DELETION_KEY))) {
draftsApi.deleteSingleDraft((int) draftId);
}
@ -238,9 +242,12 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
if (status == ActionResult.Status.SUCCESS) {
if (draftId != 0
&& tinyDB.getBoolean(
"draftsCommentsDeletionEnabled",
true)) {
&& Boolean.parseBoolean(
AppDatabaseSettings
.getSettingsValue(
getContext(),
AppDatabaseSettings
.APP_DRAFTS_DELETION_KEY))) {
draftsApi.deleteSingleDraft((int) draftId);
}

View File

@ -16,6 +16,7 @@ import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.ViewPager2Transformers;
@ -49,7 +50,10 @@ public class ExploreFragment extends Fragment {
viewPager.setAdapter(new ViewPagerAdapter(this));
ViewPager2Transformers.returnSelectedTransformer(
viewPager, tinyDB.getInt("fragmentTabsAnimationId", 0));
viewPager,
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_TABS_ANIMATION_KEY)));
String[] tabTitles = {
getResources().getString(R.string.navRepos),

View File

@ -10,7 +10,7 @@ import androidx.viewpager2.adapter.FragmentStateAdapter;
import com.google.android.material.tabs.TabLayoutMediator;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.FragmentPrChangesBinding;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.ViewPager2Transformers;
/**
@ -21,7 +21,6 @@ public class PullRequestChangesFragment extends Fragment {
private final DiffFilesFragment diffFilesFragment = DiffFilesFragment.newInstance();
private final PullRequestCommitsFragment pullRequestCommitsFragment =
PullRequestCommitsFragment.newInstance();
private FragmentPrChangesBinding binding;
public PullRequestChangesFragment() {}
@ -33,9 +32,8 @@ public class PullRequestChangesFragment extends Fragment {
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentPrChangesBinding.inflate(inflater, container, false);
TinyDB tinyDB = TinyDB.getInstance(getContext());
FragmentPrChangesBinding binding =
FragmentPrChangesBinding.inflate(inflater, container, false);
binding.close.setOnClickListener(v -> requireActivity().finish());
@ -62,7 +60,10 @@ public class PullRequestChangesFragment extends Fragment {
new String[] {getString(R.string.tabTextFiles), getString(R.string.commits)};
ViewPager2Transformers.returnSelectedTransformer(
binding.container, tinyDB.getInt("fragmentTabsAnimationId", 0));
binding.container,
Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
getContext(), AppDatabaseSettings.APP_TABS_ANIMATION_KEY)));
new TabLayoutMediator(
binding.tabs,

View File

@ -0,0 +1,395 @@
package org.mian.gitnex.helpers;
import android.content.Context;
import android.util.Log;
import org.mian.gitnex.database.api.AppSettingsApi;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.models.AppSettings;
/**
* @author M M Arif
*/
public class AppDatabaseSettings {
public static String APP_THEME_KEY = "app_theme";
public static String APP_THEME_DEFAULT = "6";
public static String APP_THEME_AUTO_LIGHT_HOUR_KEY = "app_theme_auto_light_hour";
public static String APP_THEME_AUTO_LIGHT_HOUR_DEFAULT = "6";
public static String APP_THEME_AUTO_LIGHT_MIN_KEY = "app_theme_auto_light_min";
public static String APP_THEME_AUTO_LIGHT_MIN_DEFAULT = "0";
public static String APP_THEME_AUTO_DARK_HOUR_KEY = "app_theme_auto_dark_hour";
public static String APP_THEME_AUTO_DARK_HOUR_DEFAULT = "18";
public static String APP_THEME_AUTO_DARK_MIN_KEY = "app_theme_auto_dark_min";
public static String APP_THEME_AUTO_DARK_MIN_DEFAULT = "0";
public static String APP_FONT_KEY = "app_font";
public static String APP_FONT_DEFAULT = "3";
public static String APP_TABS_ANIMATION_KEY = "app_tabs_animation";
public static String APP_TABS_ANIMATION_DEFAULT = "0";
public static String APP_LOCALE_KEY = "app_locale";
public static String APP_LOCALE_KEY_DEFAULT = "0|sys";
public static String APP_COUNTER_KEY = "app_counter_badges";
public static String APP_COUNTER_DEFAULT = "true";
public static String APP_LABELS_IN_LIST_KEY = "app_labels_in_list";
public static String APP_LABELS_IN_LIST_DEFAULT = "false";
public static String APP_LINK_HANDLER_KEY = "app_link_handler";
public static String APP_LINK_HANDLER_DEFAULT = "0";
public static String APP_HOME_SCREEN_KEY = "app_home_screen";
public static String APP_HOME_SCREEN_DEFAULT = "3";
public static String APP_CUSTOM_BROWSER_KEY = "app_custom_browser_tab";
public static String APP_CUSTOM_BROWSER_DEFAULT = "true";
public static String APP_DRAFTS_DELETION_KEY = "app_drafts_deletion";
public static String APP_DRAFTS_DELETION_DEFAULT = "true";
public static String APP_CRASH_REPORTS_KEY = "app_crash_reports";
public static String APP_CRASH_REPORTS_DEFAULT = "false";
public static String APP_CE_SYNTAX_HIGHLIGHT_KEY = "app_ce_syntax_highlight";
public static String APP_CE_SYNTAX_HIGHLIGHT_DEFAULT = "0";
public static String APP_CE_INDENTATION_KEY = "app_ce_indentation";
public static String APP_CE_INDENTATION_DEFAULT = "0";
public static String APP_CE_TABS_WIDTH_KEY = "app_ce_tabs_width";
public static String APP_CE_TABS_WIDTH_DEFAULT = "1";
public static String APP_NOTIFICATIONS_KEY = "app_notifications";
public static String APP_NOTIFICATIONS_DEFAULT = "true";
public static String APP_NOTIFICATIONS_DELAY_KEY = "app_notifications_delay";
public static String APP_NOTIFICATIONS_DELAY_DEFAULT = "0";
public static String APP_BIOMETRIC_KEY = "app_biometric";
public static String APP_BIOMETRIC_DEFAULT = "false";
public static String APP_BIOMETRIC_LIFE_CYCLE_KEY = "app_biometric_life_cycle";
public static String APP_BIOMETRIC_LIFE_CYCLE_DEFAULT = "false";
public static String APP_DATA_CACHE_KEY = "app_data_cache";
public static String APP_DATA_CACHE_DEFAULT = "1";
public static String APP_DATA_CACHE_SIZE_KEY = "app_data_cache_size";
public static String APP_DATA_CACHE_SIZE_DEFAULT = "100 MB";
public static String APP_IMAGES_CACHE_KEY = "app_images_cache";
public static String APP_IMAGES_CACHE_DEFAULT = "1";
public static String APP_IMAGES_CACHE_SIZE_KEY = "app_images_cache_size";
public static String APP_IMAGES_CACHE_SIZE_DEFAULT = "100 MB";
public static void initDefaultSettings(Context ctx) {
AppSettingsApi appSettingsApi = BaseApi.getInstance(ctx, AppSettingsApi.class);
assert appSettingsApi != null;
if (appSettingsApi.fetchSettingCountByKey(APP_THEME_KEY) == 0) {
appSettingsApi.insertNewSetting(APP_THEME_KEY, APP_THEME_DEFAULT, APP_THEME_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_THEME_AUTO_LIGHT_HOUR_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_THEME_AUTO_LIGHT_HOUR_KEY,
APP_THEME_AUTO_LIGHT_HOUR_DEFAULT,
APP_THEME_AUTO_LIGHT_HOUR_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_THEME_AUTO_LIGHT_MIN_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_THEME_AUTO_LIGHT_MIN_KEY,
APP_THEME_AUTO_LIGHT_MIN_DEFAULT,
APP_THEME_AUTO_LIGHT_MIN_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_THEME_AUTO_DARK_HOUR_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_THEME_AUTO_DARK_HOUR_KEY,
APP_THEME_AUTO_DARK_HOUR_DEFAULT,
APP_THEME_AUTO_DARK_HOUR_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_THEME_AUTO_DARK_MIN_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_THEME_AUTO_DARK_MIN_KEY,
APP_THEME_AUTO_DARK_MIN_DEFAULT,
APP_THEME_AUTO_DARK_MIN_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_FONT_KEY) == 0) {
appSettingsApi.insertNewSetting(APP_FONT_KEY, APP_FONT_DEFAULT, APP_FONT_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_TABS_ANIMATION_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_TABS_ANIMATION_KEY, APP_TABS_ANIMATION_DEFAULT, APP_TABS_ANIMATION_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_LOCALE_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_LOCALE_KEY, APP_LOCALE_KEY_DEFAULT, APP_LOCALE_KEY_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_COUNTER_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_COUNTER_KEY, APP_COUNTER_DEFAULT, APP_COUNTER_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_LABELS_IN_LIST_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_LABELS_IN_LIST_KEY, APP_LABELS_IN_LIST_DEFAULT, APP_LABELS_IN_LIST_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_LINK_HANDLER_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_LINK_HANDLER_KEY, APP_LINK_HANDLER_DEFAULT, APP_LINK_HANDLER_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_HOME_SCREEN_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_HOME_SCREEN_KEY, APP_HOME_SCREEN_DEFAULT, APP_HOME_SCREEN_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_CUSTOM_BROWSER_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_CUSTOM_BROWSER_KEY, APP_CUSTOM_BROWSER_DEFAULT, APP_CUSTOM_BROWSER_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_DRAFTS_DELETION_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_DRAFTS_DELETION_KEY,
APP_DRAFTS_DELETION_DEFAULT,
APP_DRAFTS_DELETION_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_CRASH_REPORTS_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_CRASH_REPORTS_KEY, APP_CRASH_REPORTS_DEFAULT, APP_CRASH_REPORTS_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_CE_SYNTAX_HIGHLIGHT_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_CE_SYNTAX_HIGHLIGHT_KEY,
APP_CE_SYNTAX_HIGHLIGHT_DEFAULT,
APP_CE_SYNTAX_HIGHLIGHT_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_CE_INDENTATION_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_CE_INDENTATION_KEY, APP_CE_INDENTATION_DEFAULT, APP_CE_INDENTATION_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_CE_TABS_WIDTH_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_CE_TABS_WIDTH_KEY, APP_CE_TABS_WIDTH_DEFAULT, APP_CE_TABS_WIDTH_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_NOTIFICATIONS_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_NOTIFICATIONS_KEY, APP_NOTIFICATIONS_DEFAULT, APP_NOTIFICATIONS_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_NOTIFICATIONS_DELAY_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_NOTIFICATIONS_DELAY_KEY,
APP_NOTIFICATIONS_DELAY_DEFAULT,
APP_NOTIFICATIONS_DELAY_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_BIOMETRIC_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_BIOMETRIC_KEY, APP_BIOMETRIC_DEFAULT, APP_BIOMETRIC_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_BIOMETRIC_LIFE_CYCLE_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_BIOMETRIC_LIFE_CYCLE_KEY,
APP_BIOMETRIC_LIFE_CYCLE_DEFAULT,
APP_BIOMETRIC_LIFE_CYCLE_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_DATA_CACHE_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_DATA_CACHE_KEY, APP_DATA_CACHE_DEFAULT, APP_DATA_CACHE_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_DATA_CACHE_SIZE_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_DATA_CACHE_SIZE_KEY,
APP_DATA_CACHE_SIZE_DEFAULT,
APP_DATA_CACHE_SIZE_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_IMAGES_CACHE_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_IMAGES_CACHE_KEY, APP_IMAGES_CACHE_DEFAULT, APP_IMAGES_CACHE_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey(APP_IMAGES_CACHE_SIZE_KEY) == 0) {
appSettingsApi.insertNewSetting(
APP_IMAGES_CACHE_SIZE_KEY,
APP_IMAGES_CACHE_SIZE_DEFAULT,
APP_IMAGES_CACHE_SIZE_DEFAULT);
}
if (appSettingsApi.fetchSettingCountByKey("prefsMigration") == 0) {
appSettingsApi.insertNewSetting("prefsMigration", "true", "true");
}
}
public static String getSettingsValue(Context ctx, String key) {
AppSettingsApi appSettingsApi = BaseApi.getInstance(ctx, AppSettingsApi.class);
assert appSettingsApi != null;
AppSettings appSettings = appSettingsApi.fetchSettingByKey(key);
return appSettings.getSettingValue();
}
public static void updateSettingsValue(Context ctx, String val, String key) {
AppSettingsApi appSettingsApi = BaseApi.getInstance(ctx, AppSettingsApi.class);
assert appSettingsApi != null;
appSettingsApi.updateSettingValueByKey(val, key);
}
// remove this in the upcoming releases (5.5 or up)
public static void prefsMigration(Context ctx) {
TinyDB tinyDB = TinyDB.getInstance(ctx);
Log.e("TestVal", "prefsMigration-ran");
if (tinyDB.checkForExistingPref("themeId")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("themeId")),
AppDatabaseSettings.APP_THEME_KEY);
tinyDB.remove("themeId");
}
if (tinyDB.checkForExistingPref("lightThemeTimeHour")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("lightThemeTimeHour")),
AppDatabaseSettings.APP_THEME_AUTO_LIGHT_HOUR_KEY);
tinyDB.remove("lightThemeTimeHour");
}
if (tinyDB.checkForExistingPref("lightThemeTimeMinute")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("lightThemeTimeMinute")),
AppDatabaseSettings.APP_THEME_AUTO_LIGHT_MIN_KEY);
tinyDB.remove("lightThemeTimeMinute");
}
if (tinyDB.checkForExistingPref("darkThemeTimeHour")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("darkThemeTimeHour")),
AppDatabaseSettings.APP_THEME_AUTO_DARK_HOUR_KEY);
tinyDB.remove("darkThemeTimeHour");
}
if (tinyDB.checkForExistingPref("darkThemeTimeMinute")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("darkThemeTimeMinute")),
AppDatabaseSettings.APP_THEME_AUTO_DARK_MIN_KEY);
tinyDB.remove("darkThemeTimeMinute");
}
if (tinyDB.checkForExistingPref("customFontId")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("customFontId")),
AppDatabaseSettings.APP_FONT_KEY);
tinyDB.remove("customFontId");
}
if (tinyDB.checkForExistingPref("fragmentTabsAnimationId")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("fragmentTabsAnimationId")),
AppDatabaseSettings.APP_TABS_ANIMATION_KEY);
tinyDB.remove("fragmentTabsAnimationId");
}
if (tinyDB.checkForExistingPref("locale")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
tinyDB.getInt("langId") + "|" + tinyDB.getString("locale"),
AppDatabaseSettings.APP_LOCALE_KEY);
tinyDB.remove("locale");
tinyDB.remove("langId");
}
if (tinyDB.checkForExistingPref("ceColorId")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("ceColorId")),
AppDatabaseSettings.APP_CE_SYNTAX_HIGHLIGHT_KEY);
tinyDB.remove("ceColorId");
}
if (tinyDB.checkForExistingPref("ceIndentationId")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("ceIndentationId")),
AppDatabaseSettings.APP_CE_INDENTATION_KEY);
tinyDB.remove("ceIndentationId");
}
if (tinyDB.checkForExistingPref("ceIndentationTabsId")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("ceIndentationTabsId")),
AppDatabaseSettings.APP_CE_TABS_WIDTH_KEY);
tinyDB.remove("ceIndentationTabsId");
}
if (tinyDB.checkForExistingPref("homeScreenId")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("homeScreenId")),
AppDatabaseSettings.APP_HOME_SCREEN_KEY);
tinyDB.remove("homeScreenId");
}
if (tinyDB.checkForExistingPref("defaultScreenId")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("defaultScreenId")),
AppDatabaseSettings.APP_LINK_HANDLER_KEY);
tinyDB.remove("defaultScreenId");
}
if (tinyDB.checkForExistingPref("enableCounterBadges")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getBoolean("enableCounterBadges")),
AppDatabaseSettings.APP_COUNTER_KEY);
tinyDB.remove("enableCounterBadges");
}
if (tinyDB.checkForExistingPref("showLabelsInList")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getBoolean("showLabelsInList")),
AppDatabaseSettings.APP_LABELS_IN_LIST_KEY);
tinyDB.remove("showLabelsInList");
}
if (tinyDB.checkForExistingPref("notificationsEnabled")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getBoolean("notificationsEnabled")),
AppDatabaseSettings.APP_NOTIFICATIONS_KEY);
tinyDB.remove("notificationsEnabled");
}
if (tinyDB.checkForExistingPref("notificationsPollingDelayId")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getInt("notificationsPollingDelayId")),
AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY);
tinyDB.remove("notificationsPollingDelayId");
}
if (tinyDB.checkForExistingPref("biometricStatus")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getBoolean("biometricStatus")),
AppDatabaseSettings.APP_BIOMETRIC_KEY);
tinyDB.remove("biometricStatus");
}
if (tinyDB.checkForExistingPref("biometricLifeCycle")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getBoolean("biometricLifeCycle")),
AppDatabaseSettings.APP_BIOMETRIC_LIFE_CYCLE_KEY);
tinyDB.remove("biometricLifeCycle");
}
if (tinyDB.checkForExistingPref("useCustomTabs")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getBoolean("useCustomTabs")),
AppDatabaseSettings.APP_CUSTOM_BROWSER_KEY);
tinyDB.remove("useCustomTabs");
}
if (tinyDB.checkForExistingPref("crashReportingEnabled")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getBoolean("crashReportingEnabled")),
AppDatabaseSettings.APP_CRASH_REPORTS_KEY);
tinyDB.remove("crashReportingEnabled");
}
if (tinyDB.checkForExistingPref("draftsCommentsDeletionEnabled")) {
AppDatabaseSettings.updateSettingsValue(
ctx,
String.valueOf(tinyDB.getBoolean("draftsCommentsDeletionEnabled")),
AppDatabaseSettings.APP_DRAFTS_DELETION_KEY);
tinyDB.remove("draftsCommentsDeletionEnabled");
}
AppDatabaseSettings.updateSettingsValue(ctx, "false", "prefsMigration");
}
}

View File

@ -316,16 +316,27 @@ public class AppUtil {
public static void setAppLocale(Resources resource, String locCode) {
String[] multiCodeLang = locCode.split("-");
String countryCode;
if (locCode.contains("-")) {
locCode = multiCodeLang[0];
countryCode = multiCodeLang[1];
} else {
countryCode = "";
}
DisplayMetrics dm = resource.getDisplayMetrics();
Configuration config = resource.getConfiguration();
config.setLocale(new Locale(locCode.toLowerCase()));
config.setLocale(new Locale(locCode.toLowerCase(), countryCode));
resource.updateConfiguration(config, dm);
}
public static String getTimestampFromDate(Context context, Date date) {
TinyDB tinyDB = TinyDB.getInstance(context);
Locale locale = new Locale(tinyDB.getString("locale"));
String[] locale_ =
AppDatabaseSettings.getSettingsValue(context, AppDatabaseSettings.APP_LOCALE_KEY)
.split("\\|");
Locale locale = new Locale(locale_[1]);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", locale).format(date);
@ -394,7 +405,7 @@ public class AppUtil {
public static String encodeBase64(String str) {
String base64Str = str;
if (!str.equals("")) {
if (!str.isEmpty()) {
byte[] data = str.getBytes(StandardCharsets.UTF_8);
base64Str = Base64.encodeToString(data, Base64.DEFAULT);
}
@ -529,10 +540,10 @@ public class AppUtil {
public static void openUrlInBrowser(Context context, String url) {
TinyDB tinyDB = TinyDB.getInstance(context);
Intent i;
if (tinyDB.getBoolean("useCustomTabs")) {
if (Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_CUSTOM_BROWSER_KEY))) {
i =
new CustomTabsIntent.Builder()
.setDefaultColorSchemeParams(
@ -593,8 +604,11 @@ public class AppUtil {
}
public static Typeface getTypeface(Context context) {
if (typeface == null) {
switch (TinyDB.getInstance(context).getInt("customFontId", -1)) {
switch (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_FONT_KEY))) {
case 0:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/roboto.ttf");
break;

View File

@ -211,7 +211,12 @@ public class Markdown {
if (tf == null) {
tf = AppUtil.getTypeface(textView.getContext());
}
if (tinyDB.getInt("themeId") == 8) {
if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context,
AppDatabaseSettings
.APP_THEME_KEY))
== 8) {
if (!isNightModeThemeDynamic(context)) {
textView.setTextColor(
AppUtil.dynamicColorResource(context));
@ -375,7 +380,12 @@ public class Markdown {
if (tf == null) {
tf = AppUtil.getTypeface(context);
}
if (tinyDB.getInt("themeId") == 8) {
if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context,
AppDatabaseSettings
.APP_THEME_KEY))
== 8) {
if (!isNightModeThemeDynamic(context)) {
textView.setTextColor(
AppUtil.dynamicColorResource(context));

View File

@ -15,7 +15,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import org.mian.gitnex.R;
/**
* @author opyale
@ -34,14 +33,10 @@ public class PicassoCache implements Cache {
public PicassoCache(File cachePath, Context ctx) throws IOException, ClassNotFoundException {
TinyDB tinyDb = TinyDB.getInstance(ctx);
CACHE_SIZE =
FilesData.returnOnlyNumberFileSize(
tinyDb.getString(
"cacheSizeImagesStr",
ctx.getString(
R.string.cacheSizeImagesSelectionSelectedText)))
AppDatabaseSettings.getSettingsValue(
ctx, AppDatabaseSettings.APP_IMAGES_CACHE_SIZE_KEY))
* 1024
* 1024;
this.cachePath = cachePath;

View File

@ -327,4 +327,8 @@ public class TinyDB {
throw new NullPointerException();
}
}
public boolean checkForExistingPref(String key) {
return preferences.contains(key);
}
}

View File

@ -3,8 +3,8 @@ package org.mian.gitnex.helpers.codeeditor.theme;
import android.content.Context;
import androidx.annotation.ColorRes;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement;
/**
@ -19,8 +19,10 @@ public interface Theme {
BlueMoonDarkTheme BLUE_MOON_DARK_THEME = new BlueMoonDarkTheme();
static Theme getDefaultTheme(Context context) {
TinyDB tinyDB = TinyDB.getInstance(context);
if (tinyDB.getInt("ceColorId") == 0) {
if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_CE_SYNTAX_HIGHLIGHT_KEY))
== 0) {
return AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1
? FIVE_COLORS_DARK
: FIVE_COLORS;

View File

@ -16,6 +16,7 @@ import androidx.work.WorkManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.concurrent.TimeUnit;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.TinyDB;
@ -72,22 +73,34 @@ public class Notifications {
public static void startWorker(Context context) {
TinyDB tinyDB = TinyDB.getInstance(context);
int delay;
if (tinyDB.getInt("notificationsPollingDelayId") == 0) {
if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY))
== 0) {
delay = 15;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 1) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY))
== 1) {
delay = 30;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 2) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY))
== 2) {
delay = 45;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 3) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY))
== 3) {
delay = 60;
} else {
delay = Constants.defaultPollingDelay;
}
if (tinyDB.getBoolean("notificationsEnabled", true)) {
if (Boolean.parseBoolean(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_NOTIFICATIONS_KEY))) {
if (!NotificationManagerCompat.from(context).areNotificationsEnabled()) {
MaterialAlertDialogBuilder materialAlertDialogBuilder =

View File

@ -28,8 +28,8 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Version;
import retrofit2.Call;
import retrofit2.Response;
@ -49,18 +49,29 @@ public class NotificationsWorker extends Worker {
UserAccountsApi userAccountsApi = BaseApi.getInstance(context, UserAccountsApi.class);
this.context = context;
TinyDB tinyDB = TinyDB.getInstance(context);
assert userAccountsApi != null;
this.userAccounts = new HashMap<>(userAccountsApi.getCount());
int delay;
if (tinyDB.getInt("notificationsPollingDelayId") == 0) {
if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY))
== 0) {
delay = 15;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 1) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY))
== 1) {
delay = 30;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 2) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY))
== 2) {
delay = 45;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 3) {
} else if (Integer.parseInt(
AppDatabaseSettings.getSettingsValue(
context, AppDatabaseSettings.APP_NOTIFICATIONS_DELAY_KEY))
== 3) {
delay = 60;
} else {
delay = Constants.defaultPollingDelay;

View File

@ -106,7 +106,7 @@
android:id="@+id/cacheSizeDataSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cacheSizeDataSelectionSelectedText"
android:text="@string/cacheSizeDataDialogHeader"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
@ -131,7 +131,7 @@
android:id="@+id/cacheSizeImagesSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cacheSizeImagesSelectionSelectedText"
android:text="@string/cacheSizeImagesDialogHeader"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />

View File

@ -0,0 +1,775 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- menu items -->
<string name="navMyRepos">Miaj Deponejoj</string>
<string name="navStarredRepos">Steligitaj Deponejoj</string>
<string name="navRepos">Deponejoj</string>
<string name="navProfile">Profilo</string>
<string name="navSettings">Agordoj</string>
<string name="navOrg">Organizoj</string>
<string name="navAbout">Pri</string>
<string name="navRate">Rangi GitNex</string>
<string name="navLogout">Elsaluti</string>
<string name="navAdministration">Administrado de Instanco</string>
<string name="navMyIssues">Miaj Problemoj</string>
<string name="navMostVisited">Plej Vizititaj Deponejoj</string>
<string name="navNotes">Notoj</string>
<string name="navAccount">Agordoj de Konto</string>
<string name="navWatchedRepositories">Rigarditajn Deponejojn</string>
<!-- menu items -->
<!-- page titles -->
<string name="pageTitleNewRepo">Nova Deponejo</string>
<string name="pageTitleIssues">Problemoj</string>
<string name="pageTitleCreateOrganization">Nova Organizo</string>
<string name="pageTitleCreateMilestone">Nova Mejloŝtono</string>
<string name="pageTitleCreateNewIssue">Nova Problemo</string>
<string name="pageTitleCreateLabel">Nova Etikedo</string>
<string name="pageTitleCredits">Agnoskoj</string>
<string name="pageTitleChooseBranch">Elekti Branĉon</string>
<string name="pageTitleLabelUpdate">Ĝisdatigi Etikedon</string>
<string name="pageTitleStarredRepos">Steligitaj Deponejoj</string>
<string name="pageTitleCreateTeam">Nova Teamo</string>
<string name="pageTitleAddEmail">Aldoni Retpoŝtadreson</string>
<string name="pageTitleNewFile">Nova Dosiero</string>
<string name="pageTitleExplore">Esplori</string>
<string name="pageTitleAdministration">Administrado</string>
<string name="pageTitleNewPullRequest">Nova Tiro-Peto</string>
<string name="pageTitleUsers">Uzantoj</string>
<string name="pageTitleAddRepository">Aldoni Deponejon</string>
<!-- page titles -->
<string name="repoName">Demonstra deponejo</string>
<string name="repoDescription">Demonstra priskribo</string>
<string name="orgName">Demonstra organizo</string>
<string name="newCreateButtonCopy">Krei</string>
<string name="newUpdateButtonCopy">Ĝisdatigi</string>
<string name="newRepoTintCopy">Nomo de la Deponejo</string>
<string name="newRepoDescTintCopy">Priskribo de la Deponejo</string>
<string name="newRepoPrivateCopy">Privata</string>
<string name="newRepoOwner">Proprulo</string>
<string name="newRepoIssueLabels">Issue Labels</string>
<string name="setAsTemplate">Make repository a template</string>
<string name="newOrgTintCopy">Nomo de la Organizo</string>
<string name="newOrgDescTintCopy">Priskribo de la Organizo</string>
<string name="organizationFullname">%1$s - %2$s</string>
<string name="userName">Uzantnomo</string>
<string name="passWord">Pasvorto</string>
<string name="btnLogin">ENSALUTI</string>
<string name="instanceUrl">URL de la Instanco</string>
<string name="navigationDrawerOpen">Malfermi Navigan Tirkeston</string>
<string name="navigationDrawerClose">Fermi Navigan Tirkeston</string>
<string name="protocol">Protocol</string>
<string name="urlInfoTooltip">1- Choose the correct protocol(https or http). \n2- Enter instance url e.g: try.gitea.io. \n3- If you have enabled 2FA for your account, enter the code in the OTP Code field. \n4- For HTTP basic auth use USERNAME@DOMAIN.COM in the URL field.</string>
<string name="malformedUrl">Couldn\'t connect to host. Please check your URL or port for any errors</string>
<string name="protocolError">It is not recommended to use HTTP protocol unless you are testing on local network</string>
<string name="malformedJson">Malformed JSON was received. Server response was not successful</string>
<string name="emptyFieldURL">Instance URL is required</string>
<string name="emptyFieldUsername">Username is required</string>
<string name="emptyFieldPassword">Password is required</string>
<string name="protocolEmptyError">Protocol is required</string>
<string name="instanceHelperText">Enter URL without http or https. Example: codeberg.org</string>
<string name="checkNetConnection">Cannot access network, please check your Internet connection</string>
<string name="repoNameErrorEmpty">Repository name is empty</string>
<string name="repoNameErrorInvalid">Repository name is not valid. [a&#8211;z A&#8211;Z 0&#8211;9 &#8211; _]</string>
<string name="repoNameErrorReservedName">Repository name is reserved</string>
<string name="repoNameErrorReservedPatterns">Repository name contains reserved keywords</string>
<string name="repoDescError">Repository description exceeds the max 255 characters limit</string>
<string name="repoCreated">Repository created successfully</string>
<string name="repoExistsError">Repository of this name already exists under selected Owner</string>
<string name="repoOwnerError">Select owner for the repository</string>
<string name="repoDefaultBranchError">The default branch must not be empty</string>
<string name="orgNameErrorEmpty">Organization name is empty</string>
<string name="orgNameErrorInvalid">Organization name is not valid, [a&#8211;z A&#8211;Z 0&#8211;9 &#8211; _]</string>
<string name="orgDescError">Organization description exceeds the max 255 characters limit</string>
<string name="orgCreated">Organization created successfully</string>
<string name="orgExistsError">Organization already exists</string>
<string name="diffStatistics">%1$s addition(s) and %2$s deletion(s)</string>
<string name="processingText">Processing</string>
<string name="search">Search</string>
<string name="close">Close</string>
<string name="addNewContent">Add</string>
<string name="orgContentAvatar">Org</string>
<string name="repoContentAvatar">Repo</string>
<string name="privateAvatar">Pri</string>
<string name="removeContent">Remove</string>
<string name="genericApiError">Instance has returned an error. Code %d</string>
<string name="tabTextInfo">Details</string>
<string name="tabTextFiles">Files</string>
<string name="tabTextMl">Milestones</string>
<string name="tabTextReleases">Releases</string>
<string name="tabTextBranches">Branches</string>
<string name="tabTextCollaborators">Collaborators</string>
<string name="tabPullRequests">Pull Requests</string>
<string name="pullRequest">Pull Request</string>
<string name="infoTabRepoSize">Size</string>
<string name="infoTabRepoDefaultBranch">Default Branch</string>
<string name="infoTabRepoSshUrl">SSH URL</string>
<string name="infoTabRepoCloneUrl">Clone URL</string>
<string name="infoTabRepoRepoUrl">Repo URL</string>
<string name="infoTabRepoForksCount">Forks</string>
<string name="infoTabRepoCreatedAt">Created</string>
<string name="infoTabRepoUpdatedAt">Last Updated</string>
<string name="infoMoreInformation">Pliaj Informoj</string>
<string name="timeAtText">ĉe</string>
<string name="issueMilestone">Mejloŝtono %1$s</string>
<string name="dueDate">Pagenda %1$s</string>
<string name="assignedTo">Asignita al: %1$s</string>
<string name="assignedToMe">Asignita al Mi</string>
<string name="commentButtonText">Komento</string>
<string name="commentEmptyError">Bonvolu skribi vian komenton</string>
<string name="commentSuccess">Komento afiŝita</string>
<string name="featureDeprecated">Ĉi tiu funkcio estos forigita estonte</string>
<string name="generalImgContentText">Bildo</string>
<string name="commitAuthor">Aŭtoro de la Enmeto: %1$s</string>
<string name="releaseDownloadText">Elŝutaĵoj</string>
<string name="releasePublishedBy">Eldonita de @%1$s</string>
<string name="noReleaseBodyContent">Eldonaj notoj ne estas provizitaj de la eldonisto.</string>
<string name="newMilestoneTitle">Titolo</string>
<string name="newMilestoneDescription">Priskribo</string>
<string name="newMilestoneDueDate">Limdato</string>
<string name="milestoneNameErrorEmpty">Milestone title is empty</string>
<string name="milestoneDescError">Milestone description exceeds the max 255 characters limit</string>
<string name="milestoneCreated">Milestone created successfully</string>
<string name="milestoneDateEmpty">Please choose due date</string>
<string name="milestoneNoDueDate">No due date</string>
<string name="milestoneNoDescription">No description</string>
<string name="milestoneIssueStatusOpen">%1$d Open</string>
<string name="milestoneIssueStatusClosed">%1$d Closed</string>
<string name="selectMilestone">Select Milestone</string>
<string name="newIssueSelectAssigneesListTitle">Select Assignees</string>
<string name="newIssueSelectLabelsListTitle">Select Labels</string>
<string name="newIssueTitle">Title</string>
<string name="newIssueAssigneesListTitle">Assignees</string>
<string name="newIssueDescriptionTitle">Description</string>
<string name="newIssueDueDateTitle">Due Date</string>
<string name="newIssueMilestoneTitle">Milestone</string>
<string name="newIssueLabelsTitle">Labels</string>
<string name="issueTitleEmpty">Issue title is empty</string>
<string name="issueDescriptionEmpty">Issue description is empty</string>
<string name="issueCreated">New issue created successfully</string>
<string name="issueCreatedNoMilestone">No milestone</string>
<string name="noAssigneesFound">No assignees found</string>
<!-- 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>
<string name="settingsCertsPopupMessage">Are you sure to delete any manually trusted certificate or hostname? \n\nYou will also be logged out.</string>
<string name="settingsSave">Settings saved</string>
<string name="settingsLanguageSelectorHeader">Language</string>
<string name="settingsLanguageSelectedHeaderDefault">English</string>
<string name="settingsAppearanceHeader">Appearance</string>
<string name="settingsLanguageSelectorDialogTitle">Choose Language</string>
<string name="settingsLightThemeTimeSelectorHeader">Light Theme Switch Time</string>
<string name="settingsDarkThemeTimeSelectorHeader">Dark Theme Switch Time</string>
<string name="settingsTimeSelectorDialogTitle">Choose Time Format</string>
<string name="settingsHelpTranslateText">Translate GitNex via Crowdin</string>
<string name="codeBlockHeaderText">Code Block Color</string>
<string name="settingsCodeBlockSelectorDialogTitle">Code Block Color Selector</string>
<string name="settingsHomeScreenHeaderText">Home Screen</string>
<string name="settingsHomeScreenSelectedText">My Repositories</string>
<string name="settingsHomeScreenSelectorDialogTitle">Select Home Screen</string>
<string name="settingsCustomFontHeaderText">Font</string>
<string name="settingsCustomFontSelectorDialogTitle">Choose Font</string>
<string name="themeSelectorDialogTitle">Select App Theme</string>
<string name="themeSelectionHeaderText">Theme</string>
<string name="settingsCounterBadges">Counter Badges</string>
<string name="settingsFileViewerSourceCodeHeaderText">Source Code Theme</string>
<string name="cacheSizeDataDialogHeader">Data Cache Size</string>
<string name="cacheSizeDataSelectionHeaderText">Data Cache Size</string>
<string name="cacheSizeImagesDialogHeader">Images Cache Size</string>
<string name="cacheSizeImagesSelectionHeaderText">Images Cache Size</string>
<string name="clearCacheSelectionHeaderText">Clear Cache</string>
<string name="clearCacheDialogHeader">Clear Cache?</string>
<string name="clearCacheDialogMessage">This will delete all the cache data including files and images.\n\nProceed with deletion?</string>
<string name="draftsHeader">Drafts</string>
<string name="draftsHintText">Comments draft</string>
<string name="settingsEnableCommentsDeletionText">Enable Drafts Deletion</string>
<string name="settingsEnableCommentsDeletionHintText">Delete comment draft when comment is posted</string>
<string name="settingsGeneralHeader">General</string>
<string name="generalHintText">Home screen, drafts, crash reports</string>
<string name="generalDeepLinkDefaultScreen">Default Link Handler</string>
<string name="generalDeepLinkDefaultScreenHintText">Choose what screen should be loaded if the app cannot handle external links. It will redirect you automatically.</string>
<string name="linkSelectorDialogTitle">Select Default Link Handler Screen</string>
<string name="settingsBiometricHeader">Biometric Support</string>
<string name="settingsLabelsInListHeader">Labels With Text Support</string>
<string name="settingsLabelsInListHint">Enabling this will show labels with text in issues and pr lists, default are color dots</string>
<string name="ceSyntaxHighlightColor">Syntax Highlighting Color</string>
<string name="ceIndentation">Indentation</string>
<string name="ceIndentationTabsWidth">Tabs Width</string>
<string name="system_font">System Default Font</string>
<string name="fragmentTabsAnimationHeader">Tabs Animation</string>
<string name="fadeOut">Fade Out</string>
<string name="zoomOut">Zoom Out</string>
<!-- settings -->
<string name="noMoreData">No more data available</string>
<string name="createLabel">New Label</string>
<string name="menuTitleText">Repo Menu</string>
<string name="labelName">Label Name</string>
<string name="labelColor">Label Color</string>
<string name="labelEmptyError">Label name is empty</string>
<string name="labelNameError">Label name is not valid</string>
<string name="labelCreated">Label created</string>
<string name="labelUpdated">Label updated</string>
<string name="labelMenuContentDesc">Desc</string>
<string name="labelDeleteText">Label deleted</string>
<string name="selectBranchError">Select a branch for release</string>
<string name="alertDialogTokenRevokedTitle">Authorization Error</string>
<string name="alertDialogTokenRevokedMessage">It seems that the Access Token is revoked OR your are not allowed to see these contents.\n\nIn case of revoked Token, please logout and login again</string>
<string name="labelDeleteMessage">Do you really want to delete this label?</string>
<!-- org tabbed layout str -->
<string name="orgTabTeams">Teams</string>
<string name="orgTabMembers">Members</string>
<string name="teamTitle">Team name</string>
<string name="teamDescription">Team desc</string>
<string name="teamPermissions">Permissions</string>
<string name="teamPermissionNone">• Members of this team do not have any permissions.</string>
<string name="teamPermissionRead">• Members of this team can view team repositories.</string>
<string name="teamPermissionWrite">• Members of this team can view and push to team repositories.</string>
<string name="teamPermissionAdmin">• Members of this team can push to and from team repositories and add collaborators.</string>
<string name="teamPermissionOwner">• Members of this team have owner permissions.</string>
<string name="teamShowAll">show all</string>
<string name="orgMember">Org members</string>
<string name="orgTeamMembers">Organization team members</string>
<string name="removeTeamMember">Remove %s</string>
<string name="addTeamMember">Add %s</string>
<string name="addTeamMemberMessage">Do you want to add this user to the team?</string>
<string name="removeTeamMemberMessage">Do you want to remove this user from the team?</string>
<string name="memberAddedMessage">Member added to the team successfully</string>
<string name="memberRemovedMessage">Member removed from the team successfully</string>
<string name="repoAddedMessage">Repository added to the team successfully</string>
<string name="repoRemovedMessage">Repository removed from the team successfully</string>
<string name="repoAddToTeamMessage">Add repository %1$s to organization %2$s team %3$s</string>
<string name="repoRemoveTeamMessage">Remove repository %1$s from team %2$s</string>
<string name="addRemoveMember">Add / Remove Member</string>
<!-- org tabbed layout str -->
<!-- create team -->
<string name="newTeamTitle">Team Name</string>
<string name="newTeamDesc">Description</string>
<string name="newTeamPermission">Permission</string>
<string name="newTeamAccessControls">Access Controls</string>
<string name="newTeamPermissionRead">Members can view and clone team repositories</string>
<string name="newTeamPermissionWrite">Members can read and push to team repositories</string>
<string name="newTeamPermissionAdmin">Members can pull and push to team repositories and add collaborators to them</string>
<string name="teamNameEmpty">Please enter team name</string>
<string name="teamNameError">Team name should contain only alphanumeric, dash (-), underscore (_) and dot (.) characters</string>
<string name="teamPermissionEmpty">Please select permission</string>
<string name="teamDescError">Team description have illegal characters</string>
<string name="teamDescLimit">Team description have more than 100 characters</string>
<string name="teamCreated">Team created successfully</string>
<!-- create team -->
<!-- issue comments -->
<string name="editCommentTitle">Edit Comment</string>
<string name="editCommentUpdatedText">Comment updated</string>
<string name="issueCommentShare">Share Comment</string>
<string name="deleteCommentSuccess">Comment deleted successfully</string>
<string name="copyCommentText">Copy Comment</string>
<!-- issue comments -->
<!-- add collaborator -->
<string name="addCollaboratorSearchHint">Search users</string>
<string name="addCollaboratorViewUserDesc">Username</string>
<string name="removeCollaboratorDialogTitle">Remove %s?</string>
<string name="removeCollaboratorMessage">Do you want to remove this user from the repository?</string>
<string name="removeCollaboratorToastText">User removed from the repository.</string>
<string name="addCollaboratorToastText">User added to the repository.</string>
<!-- add collaborator -->
<!-- profile section -->
<string name="profileTabFollowers">Followers</string>
<string name="profileTabFollowing">Following</string>
<!-- profile section -->
<!-- account settings -->
<string name="accountEmails">Emails</string>
<string name="accountEmailTitle">Email Address</string>
<string name="emailAddedText">New email added successfully</string>
<string name="emailErrorEmpty">Email address is empty</string>
<string name="emailErrorInvalid">Email address is not valid</string>
<string name="emailErrorInUse">Email address is already in use</string>
<string name="emailTypeText">Primary</string>
<string name="sshKeys">SSH Keys</string>
<!-- account settings -->
<!-- single issue section -->
<string name="singleIssueEditLabels">Add / Remove Labels</string>
<string name="labelsUpdated">Labels updated</string>
<string name="closeIssue">Close Issue</string>
<string name="editIssue">Edit Issue</string>
<string name="reOpenIssue">Reopen Issue</string>
<string name="issueStateClosed">Issue closed</string>
<string name="issueStateReopened">Issue reopened</string>
<string name="addRemoveAssignees">Add / Remove Assignees</string>
<string name="assigneesUpdated">Assignees updated</string>
<string name="singleIssueSubscribe">Subscribe</string>
<string name="singleIssueUnSubscribe">Unsubscribe</string>
<!-- single issue section -->
<string name="repoMetaData">Repository Meta</string>
<!-- admin -->
<string name="adminCreateNewUser">New User</string>
<string name="adminUsers">System Users</string>
<string name="userRoleAdmin">Admin</string>
<string name="adminCron">Cron Tasks</string>
<string name="adminCronScheduleHeader">Schedule</string>
<string name="adminCronNextRunHeader">Next Run</string>
<string name="adminCronLastRunHeader">Last Run</string>
<string name="adminCronExecutionHeader">Executions</string>
<string name="adminCronTaskSuccessMsg">Task %1$s is initiated successfully</string>
<!-- admin -->
<!-- create user -->
<string name="userFullNameText">Full Name</string>
<string name="userEmail">Email</string>
<string name="userUserName">Username</string>
<string name="userPassword">Password</string>
<string name="userInvalidFullName">Invalid Full Name</string>
<string name="userInvalidUserName">Invalid Username</string>
<string name="userInvalidEmail">Invalid Email</string>
<string name="userCreatedText">New user added successfully</string>
<string name="userExistsError">User already exists</string>
<!-- create user -->
<!-- edit issue -->
<string name="editIssueNavHeader">Edit Issue #%1$s</string>
<string name="editIssueSuccessMessage">Issue updated</string>
<!-- edit issue -->
<!-- release -->
<string name="createRelease">New Release</string>
<string name="releaseTagNameText">Tag Name</string>
<string name="releaseTitleText">Title</string>
<string name="releaseContentText">Content</string>
<string name="releaseTypeText">Mark as Pre-Release</string>
<string name="releaseBranchText">Select Branch</string>
<string name="releaseDraftText">Draft</string>
<string name="tagNameErrorEmpty">Tag name is empty</string>
<string name="titleErrorEmpty">Title is empty</string>
<string name="releaseCreatedText">New release created</string>
<string name="deleteReleaseConfirmation">Do you really want to delete this release?</string>
<string name="releaseDeleted">Release deleted</string>
<!-- release -->
<string name="loginOTPTypeError">OTP code should be numbers</string>
<string name="loginOTP">OTP Code (Optional)</string>
<string name="otpMessage">Enter otp code if 2FA is enabled</string>
<string name="openWebRepo">Open in Browser</string>
<string name="repoStargazersInMenu">Stargazers</string>
<string name="repoWatchersInMenu">Watchers</string>
<string name="noDataWebsite">No website found</string>
<string name="noDataDescription">No description found</string>
<string name="noDataLocation">No location found</string>
<string name="starMember">Star</string>
<string name="watcherMember">Watcher</string>
<string name="zipArchiveDownloadReleasesTab">Source code (ZIP)</string>
<string name="tarArchiveDownloadReleasesTab">Source code (TAR.GZ)</string>
<!-- new file -->
<string name="newFileNameTintCopy">File Name</string>
<string name="newFileBranchTintCopy">New Branch Name</string>
<string name="newFileContentTintCopy">File Content</string>
<string name="newFileButtonCopy">Create New File</string>
<string name="newFileNameHintMessage">with folder: app/test.md</string>
<string name="newFileMessageTintCopy">Commit Message</string>
<string name="newFileInvalidBranchName">Invalid branch name, may only contain &#8211;, a&#8211;z, 0&#8211;9</string>
<string name="newFileCommitMessageError">Commit message is too long</string>
<string name="newFileSuccessMessage">New file created</string>
<string name="newFileBranches">Select or create a branch</string>
<string name="newFileRequiredFields">Fields like filename, content and commit message are required</string>
<string name="newFileEmptyBranchMessage">Leave blank to push to the default branch</string>
<string name="newFileRequiredFieldNewBranchName">New branch name cannot be empty if current branch is not selected</string>
<string name="strFilter">Filter</string>
<string name="strSwitchBranches">Branches</string>
<string name="strMarkdown">Markdown</string>
<string name="copyIssueUrl">Copy Issue URL</string>
<string name="copyIssueUrlToastMsg">URL copied to clipboard</string>
<string name="copyIssueCommentToastMsg">Comment copied to clipboard</string>
<string name="copyShaToastMsg">SHA copied to clipboard</string>
<string name="milestoneCompletion">%1$d\uFF05 completed</string>
<!-- files -->
<string name="filesGenericError">Sorry this file cannot be viewed as API returned an error</string>
<string name="fileTypeCannotBeEdited">Files of this type cannot be edited</string>
<string name="notSupported">Not supported</string>
<!-- generic copy -->
<string name="okButton">OK</string>
<string name="doneButton">Done</string>
<string name="cancelButton">Cancel</string>
<string name="genericError">Something went wrong, please try again</string>
<string name="apiNotFound">This request needs higher version than the one installed. Please upgrade your instance to the latest version.</string>
<string name="noDataFound">🌟 Nothing in here 🌟</string>
<string name="addButton">Add</string>
<string name="removeButton">Remove</string>
<string name="authorizeError">You are not authorized to perform this action.</string>
<string name="menuContentDesc">Menu</string>
<string name="menuEditText">Edit</string>
<string name="menuDeleteText">Delete</string>
<string name="menuCopyText">Copy</string>
<string name="menuQuoteText">Quote Reply</string>
<string name="modifiedText">edited</string>
<string name="saveButton">Save</string>
<string name="websiteText">Website</string>
<string name="locationText">Location</string>
<string name="characters255Limit">Max 255 characters</string>
<string name="emptyFields">All fields are required</string>
<string name="textContinue">Continue</string>
<string name="copyToken">Token</string>
<string name="viewInBrowser">View in Browser</string>
<string name="isOpen">Open</string>
<string name="isClosed">Closed</string>
<string name="genericServerResponseError">We cannot reach the server at the moment, please check your server status and try again</string>
<string name="genericCopyUrl">Copy URL</string>
<string name="genericWaitFor">Hold on ☕</string>
<string name="file">File</string>
<string name="issue">Issue</string>
<string name="labelTxt">Label</string>
<string name="release">Release</string>
<string name="pr">Pull Request</string>
<string name="collaborator">Collaborator</string>
<string name="unstar">Unstar</string>
<string name="watch">Watch</string>
<string name="unwatch">Unwatch</string>
<string name="share">Share</string>
<string name="repository">Repository</string>
<string name="team">Team</string>
<string name="organization">Organization</string>
<string name="addRemove">Add / Remove</string>
<string name="download">Download</string>
<string name="reopen">Reopen</string>
<string name="openInBrowser">Open in Browser</string>
<string name="deleteGenericTitle">Delete %s</string>
<string name="reset">Reset</string>
<string name="beta">BETA</string>
<string name="none">None</string>
<string name="main">main</string>
<string name="license">License</string>
<!-- generic copy -->
<string name="exploreUsers">Explore users</string>
<string name="exploreIssues">Explore issues</string>
<string name="exploreTextBoxHint">Explore repositories</string>
<string name="starRepositorySuccess">Repository added to starred list</string>
<string name="unStarRepositorySuccess">Repository removed from starred list</string>
<string name="watchRepositorySuccess">Repository added to watch list</string>
<string name="unWatchRepositorySuccess">Repository removed from watch list</string>
<string name="titleDrafts">Drafts</string>
<string name="versionUnsupportedOld">Unsupported old version(%1$s) of Gitea detected. Please update to latest stable version. If you continue, some features may not work.</string>
<string name="versionUnsupportedNew">New Gitea version detected! Please UPDATE GitNex!</string>
<string name="versionUnknown">No Gitea detected!</string>
<string name="versionAlertDialogHeader">Unsupported Version of Gitea</string>
<string name="loginViaPassword">Basic Auth</string>
<string name="unauthorizedApiError">Instance has returned an error - Unauthorized. Check your credentials and try again</string>
<string name="loginTokenError">Token is required</string>
<string name="prDeletedFork">Deleted Fork</string>
<string name="editPrNavHeader">Edit Pull Request #%1$s</string>
<string name="editPrSuccessMessage">Pull Request updated</string>
<string name="fileDiffViewHeader">%1$s Files Changed</string>
<string name="fileDiffViewHeaderSingle">%1$s File Changed</string>
<string name="updatePullRequestText">Update Pull Request</string>
<string name="openFileDiffText">Show Changed Files</string>
<string name="mergePullRequestText">Merge Pull Request</string>
<string name="deleteBranchSuccess">Branch deleted successfully</string>
<string name="deleteBranchError">Could not delete branch</string>
<string name="deleteBranchErrorNotFound">Branch does not exist</string>
<string name="mergePullRequestButtonText">Merge</string>
<string name="deleteBranchAfterMerge">Delete branch after merge</string>
<string name="mergeNoteText">Merge may fail if you are not authorized to merge this Pull Request.</string>
<string name="mergeInfoDisabledMessage">Disabled Merge button means that there are conflicts OR other things to fix before Merge</string>
<string name="deleteBranchForkInfo">This branch belong to a forked repository</string>
<string name="mergeCommentText">Merge comment</string>
<string name="mergePRSuccessMsg">Pull Request was merged successfully</string>
<string name="mergePR404ErrorMsg">Pull Request is not available for merge</string>
<string name="mergeOptionMerge">Merge Pull Request</string>
<string name="mergeOptionRebase">Rebase and Merge</string>
<string name="mergeOptionRebaseCommit">Rebase and Merge (&#45;&#45;no-ff)</string>
<string name="mergeOptionSquash">Squash and Merge</string>
<string name="mergeStrategy">Merge Strategy</string>
<string name="selectMergeStrategy">Select merge strategy</string>
<string name="mergeNotAllowed">Not allowed to merge [Reason: Does not have enough approvals]</string>
<string name="deleteBranch">Delete Branch</string>
<string name="waitLoadingDownloadFile">Please wait for the file to load to memory</string>
<string name="downloadFileSaved">File saved successfully</string>
<string name="excludeFilesInFileViewer">This file type/size is not supported in file viewer. You can download it from the menu.</string>
<string name="deleteFile">Delete This File</string>
<string name="editFile">Edit This File</string>
<string name="deleteFileMessage">File is set for deletion by branch %1$s</string>
<string name="editFileText">Edit %1$s</string>
<string name="editFileMessage">File is modified by branch %1$s</string>
<string name="sizeCopy">Size</string>
<string name="shareIssue">Share Issue</string>
<string name="shareRepository">Share Repository</string>
<string name="createRepository">Create Repository</string>
<string name="commitTitle">Commits</string>
<string name="commitAuthoredByAndCommittedByWhen"><![CDATA[<b>%1$s</b> authored and <b>%2$s</b> committed %3$s]]></string>
<string name="commitCommittedByWhen"><![CDATA[<b>%1$s</b> committed %2$s]]></string>
<string name="viewCommits">View Commits</string>
<!-- Memorizing Trust Manager -->
<string name="mtmNotification">Certificate Verification</string>
<string name="mtmAcceptCert">Accept Unknown Certificate?</string>
<string name="mtmTrustAnchor">The server certificate is not signed by a known Certificate Authority</string>
<string name="mtmCertExpired">The server certificate is expired.</string>
<string name="mtmAcceptServerName">Accept Mismatching Server Name?</string>
<string name="mtmHostnameMismatch">Server could not authenticate as \&quot;%s\&quot;. The certificate is only valid for:</string>
<string name="mtmConnectAnyway">Do you want to connect anyway?</string>
<string name="mtmCertDetails">Certificate details:</string>
<string name="mtmDecisionAlways">Trust</string>
<string name="mtmDecisionAbort">Abort</string>
<string name="subscribedSuccessfully">Subscribed successfully</string>
<string name="alreadySubscribed">You have already subscribed</string>
<string name="subscriptionError">Subscription failed</string>
<string name="unsubscribedSuccessfully">Unsubscribed successfully</string>
<string name="alreadyUnsubscribed">You have already Unsubscribed</string>
<string name="unSubscriptionError">Un-Subscription failed</string>
<string name="closeMilestone">Close Milestone</string>
<string name="openMilestone">Open Milestone</string>
<string name="milestoneStatusUpdate">Milestone status updated successfully</string>
<string name="reportViewerHeader">Crash Reports</string>
<string name="settingsEnableReportsText">Enable Crash Reports</string>
<string name="crashTitle">GitNex has stopped :(</string>
<string name="setCrashReports">Crash reports</string>
<string name="crashMessage">It is encouraged to open an issue at the project repository with how to reproduce this bug. It is easier to debug and fix the problem that way.\n\nTap the OK button to send the crash report by email instead. Additional content could be added in the email.\nThank you!</string>
<string name="forceLogoutDialogHeader">Please sign in again</string>
<string name="forceLogoutDialogDescription">Due to some major changes regarding the internal functioning of the app, we require you to login again. These changes allow us to make the app more flexible in the future.\n\nThank you for your patience and sorry for the inconvenience.</string>
<string name="deleteAllDrafts">Delete All Drafts</string>
<string name="draftsListEmpty">No drafts found</string>
<string name="draftsDeleteSuccess">Drafts deleted successfully</string>
<string name="draftsSingleDeleteSuccess">Draft deleted successfully</string>
<string name="deleteAllDraftsDialogMessage">This will delete all the drafts for this account. \n\nProceed with deletion?</string>
<string name="draftSaved">Draft was saved automatically.</string>
<string name="resetMostReposCounter">Counter is reset successfully</string>
<string name="resetCounterDialogMessage">Do you want to reset counter for repository %s?</string>
<string name="resetCounterAllDialogMessage">This will reset all the counters for this account repositories.</string>
<string name="appearanceHintText">Themes, fonts, badges, translation</string>
<string name="securityHintText">Biometric authentication, SSL certificates, cache</string>
<string name="languagesHintText">Languages</string>
<string name="reportsHintText">Crash reports</string>
<string name="rateAppHintText">If you like GitNex you can give it a thumbs up</string>
<string name="aboutAppHintText">App version, build, user instance version</string>
<string name="codeEditorHintText">Syntax color, indentation</string>
<string name="archivedRepository">Archived</string>
<string name="archivedRepositoryMessage">This repo is archived. You can view files, but cannot push or open issues/pull-requests.</string>
<string name="accountDeletedMessage">Account deleted successfully</string>
<string name="removeAccountPopupTitle">Remove Account</string>
<string name="removeAccountPopupMessage">Are you sure you want to remove this account from the app?\n\nThis will remove all the data related to this account on the app only.</string>
<string name="addNewAccount">New Account</string>
<string name="addNewAccountText">Add Account</string>
<string name="accountAlreadyExistsError">Account already exists in the app</string>
<string name="accountAddedMessage">Account added successfully</string>
<string name="switchAccountSuccess">Switched to account : %1$s@%2$s</string>
<!-- Notifications -->
<string name="pageTitleNotifications">Notifications</string>
<string name="noDataNotifications">All caught up 🚀</string>
<string name="notificationsPollingHeaderText">Notifications Polling Delay</string>
<string name="pollingDelay15Minutes">15 Minutes</string>
<string name="pollingDelay30Minutes">30 Minutes</string>
<string name="pollingDelay45Minutes">45 Minutes</string>
<string name="pollingDelay1Hour">1 Hour</string>
<string name="pollingDelayDialogHeaderText">Select Polling Delay</string>
<string name="pollingDelayDialogDescriptionText">Choose a minutely delay in which GitNex tries to poll new notifications</string>
<string name="markAsRead">Mark Read</string>
<string name="markAsUnread">Mark Unread</string>
<string name="pinNotification">Pin</string>
<string name="markedNotificationsAsRead">Successfully marked all notifications as read</string>
<string name="notificationsHintText">Polling delay</string>
<string name="enableNotificationsHeaderText">Enable Notifications</string>
<string name="enableLightsHeaderText">Enable Light</string>
<string name="enableVibrationHeaderText">Enable Vibration</string>
<string name="chooseColorSelectorHeader">Choose Color</string>
<string name="newMessages">New messages for %s</string>
<string name="youHaveGotNewNotifications">You\'ve got %d new notifications.</string>
<string name="mainNotificationChannelName">Notifications</string>
<string name="mainNotificationChannelDescription">This is the main notification channel of GitNex.</string>
<plurals name="youHaveNewNotifications">
<item quantity="one">You have %s new notification</item>
<item quantity="other">You have %s new notifications</item>
</plurals>
<string name="openAppSettings">To receive notifications, you must enable notifications for GitNex. Tap Open to access your phone settings and enable notifications.</string>
<string name="isRead">Read</string>
<string name="isUnread">Unread</string>
<string name="repoSettingsTitle">Repository Settings</string>
<string name="repoSettingsEditProperties">Edit Properties</string>
<string name="repoSettingsDelete">Delete Repository</string>
<string name="repoSettingsDeleteHint">Be careful, this operation CANNOT be undone!</string>
<string name="repoPropertiesTemplate">Set as Template</string>
<string name="repoPropertiesEnableIssues">Enable Issues</string>
<string name="repoPropertiesExternalIssuesUrl">External Issue Tracker Url</string>
<string name="repoPropertiesEnableWiki">Enable Wiki</string>
<string name="repoPropertiesExternalWikiUrl">External Wiki Url</string>
<string name="repoPropertiesEnablePr">Enable Pull Requests</string>
<string name="repoPropertiesEnableTimeTracker">Enable Time Tracker</string>
<string name="repoPropertiesEnableMergeCommits">Enable Merge Commits</string>
<string name="repoPropertiesEnableRebase">Enable Rebase</string>
<string name="repoPropertiesEnableSquash">Enable Squash and Merge</string>
<string name="repoPropertiesEnableForceMerge">Enable Rebase with Merge Commits (&#8212;&#8212;no-ff)</string>
<string name="repoPropertiesSaveSuccess">Repository properties updated successfully</string>
<string name="repoSettingsDeleteDescription">Things to know before deletion:\n\n- This operation CANNOT be undone.\n- This operation will permanently delete the repository including code, issues, comments, wiki data and collaborator settings.\n\nEnter the repository name as confirmation</string>
<string name="repoSettingsDeleteError">Repository name does not match</string>
<string name="repoDeletionSuccess">Repository deleted successfully</string>
<string name="repoSettingsTransferOwnership">Transfer Ownership</string>
<string name="repoSettingsTransferOwnershipHint">Transfer this repository to a user or to an organization for which you have administrator rights</string>
<string name="repoSettingsTransferOwnershipDescription">Things to know before transfer:\n\n- You will lose access to the repository if you transfer it to an individual user.\n- You will keep access to the repository if you transfer it to an organization that you (co-)own.\n\nEnter the repository name as confirmation</string>
<string name="repoTransferText">Perform Transfer</string>
<string name="repoTransferOwnerText">New Owner</string>
<string name="repoTransferSuccess">Repository transferred successfully</string>
<string name="repoTransferOwnerError">New owner is required</string>
<string name="repoTransferError">There is a problem with the owner name. Make sure that the new owner exists</string>
<string name="exploreFilterDialogTitle">Filter Repositories</string>
<string name="exploreFilterIncludeTopic">Search ONLY in Topic</string>
<string name="exploreFilterIncludeDesc">Search in Description</string>
<string name="exploreFilterIncludeArchive">Only Archived Repositories</string>
<string name="exploreFilterIncludePrivate">Only Private Repositories</string>
<string name="exploreFilterIncludeTemplateRepos">Search in Template Repositories</string>
<string name="mergeIntoBranch">Merge Into</string>
<string name="pullFromBranch">Pull From</string>
<string name="sameBranchesError">These branches are equal. There is no need to create a pull request</string>
<string name="mergeIntoError">Merge into branch is required</string>
<string name="pullFromError">Pull from branch is required</string>
<string name="titleError">Title is required</string>
<string name="prCreateSuccess">Pull Request created successfully</string>
<string name="prAlreadyExists">A pull request between these branches already exists</string>
<string name="prClosed">Pull Request closed</string>
<string name="prReopened">Pull Request reopened</string>
<string name="prMergeInfo">Pull Request Info</string>
<string name="accountDoesNotExist">It seems that the account for URI %1$s does not exist in the app. You can add one by tapping on the Add New Account button.</string>
<string name="launchApp">Go to App</string>
<string name="noActionText">GitNex cannot handle the requested resource. You can open an issue at the project repository as an improvement, providing details of the work. Just launch a default screen for now from the buttons below; it can be changed from settings.</string>
<string name="biometricAuthTitle">Biometric Authentication</string>
<string name="biometricAuthSubTitle">Unlock using your biometric credentials</string>
<string name="biometricNotSupported">No biometric features available on this device</string>
<string name="biometricNotAvailable">Biometric features are currently unavailable</string>
<string name="enrollBiometric">Enroll biometric from phone settings</string>
<string name="copyLoginIdToClipBoard">Login ID \'%s\' copied to clipboard</string>
<!-- file viewer activity -->
<string name="fileViewerNotificationTitleStarted">Download in progress</string>
<string name="fileViewerNotificationDescriptionStarted">Downloading %s</string>
<string name="fileViewerNotificationTitleFinished">Download successful</string>
<string name="fileViewerNotificationDescriptionFinished">Downloaded %s</string>
<string name="fileViewerNotificationTitleFailed">Download failed</string>
<string name="fileViewerNotificationDescriptionFailed">Couldn\'t download %s</string>
<string name="fileViewerNotificationChannelName">Download manager</string>
<string name="fileViewerNotificationChannelDescription">Indicates the progress of ongoing downloads</string>
<string name="lastUpdatedAt">Updated %s</string>
<string name="joined">Joined</string>
<string name="userFollow">Follow</string>
<string name="unfollowUser">Unfollow</string>
<string name="unfollowedUser">Unfollowed @%s</string>
<string name="nowFollowUser">You now follow @%s</string>
<string name="unfollowingFailed">Couldn\'t unfollow user</string>
<string name="followingFailed">Couldn\'t follow user</string>
<string name="updatePrConflict">The pull request conflicts with the base branch. Please resolve the conflicts and try again.</string>
<string name="updatePrSuccess">Pull Request updated successfully</string>
<string name="updateStrategyMerge">Merge</string>
<string name="updateStrategyRebase">Rebase</string>
<string name="selectUpdateStrategy">Select Update Strategy</string>
<string name="userAvatar">Avatar</string>
<string name="tags">Tags</string>
<string name="releasesTags">Releases/Tags</string>
<string name="create_tag">Create Tag Only</string>
<string name="tagCreated">Tag created</string>
<string name="asRef">Use as reference</string>
<string name="deleteTagConfirmation">Do you really want to delete this tag?</string>
<string name="tagDeleted">Tag deleted</string>
<string name="tagDeleteError">A tag attached to a release cannot be deleted directly</string>
<string name="useCustomTabs">Use Custom Tabs</string>
<string name="browserOpenFailed">No application found to open this link. SSH URLs and URLs with another prefix the http:// or https:// are not supported by most browser</string>
<string name="logInAgain">Log in again</string>
<string name="notLoggedIn">%s \u25CF not logged in</string>
<string name="followSystem">Follow system (Light/Dark)</string>
<string name="followSystemBlack">Follow system (Light/Pitch Black)</string>
<string name="dynamicColorsFollowSystem">Dynamic colors - Follow system (Light/Dark)</string>
<string name="codebergDark">Codeberg (Dark)</string>
<string name="repoForkOf">Fork of: %s</string>
<string name="adoptRepo">Adopt</string>
<string name="repoAdopted">Adopted repository %s</string>
<string name="unadoptedRepos">Unadopted Repositories</string>
<string name="unadoptedReposMessage">- Adopt will add repository %1$s to organization/user %2$s.\n- Delete will remove it from the system.</string>
<string name="commits">Commits</string>
<!-- wiki -->
<string name="wiki">Wiki</string>
<string name="wikiAuthor"><![CDATA[<b>%1$s</b> updated %2$s]]></string>
<string name="deleteWikiPageMessage">Do you really want to delete %s?</string>
<string name="wikiPageDeleted">Wiki page deleted successfully</string>
<string name="wikiPageNameAndContentError">Page name and page content can\'t be empty</string>
<string name="createWikiPage">Create Wiki Page</string>
<string name="wikiUpdated">Wiki page updated successfully</string>
<string name="wikiCreated">Wiki page created successfully</string>
<!-- code editor -->
<string name="openInCodeEditor">Open in Code Editor</string>
<!-- notes -->
<string name="newNote">New Note</string>
<string name="editNote">Edit Note</string>
<string name="newNoteContentHint">Start taking your notes here</string>
<string name="noteDateTime">Created %s</string>
<string name="noteTimeModified">Updated %s</string>
<string name="noteDeleteDialogMessage">Do you really want to delete this note?</string>
<plurals name="noteDeleteMessage">
<item quantity="one">Note deleted successfully</item>
<item quantity="other">Notes deleted successfully</item>
</plurals>
<string name="notesAllDeletionMessage">This will delete all of your notes. This action cannot be undone.</string>
<!-- timeline -->
<string name="commitsText">commit</string>
<string name="commitText">commit</string>
<string name="timelineAddedCommit">%1$s added %2$s %3$s</string>
<!-- the | is replaced by the label -->
<string name="timelineAddedLabel">%1$s added the | label %2$s</string>
<!-- the | is replaced by the label -->
<string name="timelineRemovedLabel">%1$s removed the | label %2$s</string>
<string name="timelineAssigneesRemoved">%1$s removed their assignment %2$s</string>
<string name="timelineAssigneesUnassigned">%1$s was unassigned by %2$s %3$s</string>
<string name="timelineAssigneesSelfAssigned">%1$s self-assigned this %2$s</string>
<string name="timelineAssigneesAssigned">%1$s was assigned by %2$s %3$s</string>
<string name="timelineMilestoneAdded">%1$s added this to the %2$s milestone %3$s</string>
<string name="timelineMilestoneRemoved">%1$s removed this from the %2$s milestone %3$s</string>
<string name="timelineMilestoneDeleted">%1$s added this to a deleted milestone %2$s</string>
<string name="timelineStatusClosedIssue">%1$s closed this issue %2$s</string>
<string name="timelineStatusReopenedIssue">%1$s reopened this issue %2$s</string>
<string name="timelineStatusReopenedPr">%1$s reopened this pull request %2$s</string>
<string name="timelineStatusClosedPr">%1$s closed this pull request %2$s</string>
<string name="timelineStatusMergedPr">%1$s merged this pull request %2$s</string>
<string name="timelineStatusRefPr"><![CDATA[%1$s referenced this pull request from a <font color=\'%2$d\'>%3$s</font> %4$s]]></string>
<string name="timelineReviewRequest">%1$s requested review from %2$s %3$s</string>
<string name="timelineChangeTitle">%1$s changed title from %2$s to %3$s %4$s</string>
<string name="timelineLocked">%1$s locked as %2$s and limited conversation to collaborators %3$s</string>
<string name="timelineUnlocked">%1$s unlocked this conversation %2$s</string>
<string name="timelineDependencyAdded">%1$s added a new dependency #%2$d %3$s</string>
<string name="timelineDependencyRemoved">%1$s removed a dependency #%2$d %3$s</string>
<string name="timelineProjectAdded">%1$s added this to a project %2$s</string>
<string name="timelineProjectRemoved">%1$s removed this from a project %2$s</string>
<string name="timelineDueDateAdded">%1$s added the due date %2$s %3$s</string>
<string name="timelineDueDateModified">%1$s modified the due date to %2$s from %3$s %4$s</string>
<string name="timelineDueDateRemoved">%1$s removed the due date %2$s %3$s</string>
<string name="timelineBranchChanged">%1$s changed target branch from %2$s to %3$s %4$s</string>
<string name="timelineBranchDeleted">%1$s deleted branch %2$s %3$s</string>
<string name="timelineTimeTrackingStart">%1$s started working %2$s</string>
<string name="timelineTimeTrackingStop">%1$s stopped time tracking %2$s</string>
<string name="timelineTimeTrackingCancel">%1$s cancelled time tracking %2$s</string>
<string name="timelineTimeTrackingAddManualTime">%1$s added spent time %2$s %3$s</string>
<string name="timelineTimeTrackingDeleteManualTime">%1$s deleted spent time %2$s %3$s</string>
<string name="timelineChangeIssueRef">%1$s added reference %2$s %3$s</string>
<string name="timelineRefIssue">%1$s referenced this issue in #%2$d %3$s</string>
<string name="timelineRefPr">%1$s referenced this pull request in #%2$d %3$s</string>
<string name="timelineStatusRefIssue"><![CDATA[%1$s referenced this issue from a <font color=\'%2$d\'>%3$s</font> %4$s]]></string>
<string name="timelineReviewLeftComment">%1$s left a comment: %2$s %3$s</string>
<string name="commitStatuses">Statuses</string>
<string name="statusNoUrl">This status has no linked target URL.</string>
<string name="starredRepos">Starred Repos</string>
<string name="lang_statistics">Language Statistics</string>
<string name="dashboard">Dashboard</string>
<string name="createdRepository">created repository</string>
<string name="renamedRepository">renamed repository from %1$s to</string>
<string name="starredRepository">starred</string>
<string name="transferredRepository">transferred repository %1$s to</string>
<string name="createdBranch">created branch %1$s in</string>
<string name="pushedTo">pushed to %1$s at</string>
<string name="openedIssue">opened issue</string>
<string name="commentedOnIssue">commented on issue</string>
<string name="closedIssue">closed issue</string>
<string name="reopenedIssue">reopened issue</string>
<string name="createdPR">created pull request</string>
<string name="closedPR">closed pull request</string>
<string name="reopenedPR">reopened pull request</string>
<string name="mergedPR">merged pull request</string>
<string name="approved">approved</string>
<string name="suggestedChanges">suggested changes for</string>
<string name="commentedOnPR">commented on pull request</string>
<string name="autoMergePR">automatically merged pull request</string>
<string name="deletedBranch">deleted branch %1$s at</string>
<string name="pushedTag">pushed tag %1$s to</string>
<string name="deletedTag">deleted tag %1$s from</string>
<string name="releasedBranch">released %1$s at</string>
<string name="syncedCommits">synced commits to %1$s at</string>
<string name="syncedRefs">synced new reference %1$s to</string>
<string name="syncedDeletedRefs">synced and deleted reference %1$s at</string>
<string name="attachment">Attachment</string>
<string name="attachments">Attachments</string>
<string name="attachmentsSaveError">An issue was created but cannot process attachments at this time. Check the server logs for more details.</string>
</resources>

View File

@ -0,0 +1,773 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- menu items -->
<string name="navMyRepos">我的倉儲</string>
<string name="navStarredRepos">已按讚</string>
<string name="navRepos">倉儲列表</string>
<string name="navProfile">個人檔案</string>
<string name="navSettings">設定</string>
<string name="navOrg">組織</string>
<string name="navAbout">關於</string>
<string name="navRate">五星好評!</string>
<string name="navLogout">登出</string>
<string name="navAdministration">Instance Administration</string>
<string name="navMyIssues">我的議題</string>
<string name="navMostVisited">最常瀏覽的倉儲</string>
<string name="navNotes">Notes</string>
<string name="navAccount">帳號設定</string>
<string name="navWatchedRepositories">Watched Repositories</string>
<!-- menu items -->
<!-- page titles -->
<string name="pageTitleNewRepo">新增倉儲</string>
<string name="pageTitleIssues">議題</string>
<string name="pageTitleCreateOrganization">新增組織</string>
<string name="pageTitleCreateMilestone">新增里程碑</string>
<string name="pageTitleCreateNewIssue">新增議題</string>
<string name="pageTitleCreateLabel">新增標籤</string>
<string name="pageTitleCredits">鳴謝</string>
<string name="pageTitleChooseBranch">選擇分支</string>
<string name="pageTitleLabelUpdate">更新標籤</string>
<string name="pageTitleStarredRepos">已按讚</string>
<string name="pageTitleCreateTeam">新增團隊</string>
<string name="pageTitleAddEmail">新增電子郵件地址</string>
<string name="pageTitleNewFile">新增檔案</string>
<string name="pageTitleExplore">探索</string>
<string name="pageTitleAdministration">Administration</string>
<string name="pageTitleNewPullRequest">新增合併請求</string>
<string name="pageTitleUsers">Users</string>
<string name="pageTitleAddRepository">新增倉儲</string>
<!-- page titles -->
<string name="repoName">Demo repo</string>
<string name="repoDescription">Demo description</string>
<string name="orgName">Demo organization</string>
<string name="newCreateButtonCopy">Create</string>
<string name="newUpdateButtonCopy">更新</string>
<string name="newRepoTintCopy">倉儲名稱</string>
<string name="newRepoDescTintCopy">倉儲描述</string>
<string name="newRepoPrivateCopy">Private</string>
<string name="newRepoOwner">Owner</string>
<string name="newRepoIssueLabels">議題標籤</string>
<string name="setAsTemplate">Make repository a template</string>
<string name="newOrgTintCopy">組織名稱</string>
<string name="newOrgDescTintCopy">Organization Description</string>
<string name="organizationFullname">%1$s - %2$s</string>
<string name="userName">使用者名稱</string>
<string name="passWord">密碼</string>
<string name="btnLogin">登入</string>
<string name="instanceUrl">執行個體網址</string>
<string name="navigationDrawerOpen">Open Navigation Drawer</string>
<string name="navigationDrawerClose">Close Navigation Drawer</string>
<string name="protocol">Protocol</string>
<string name="urlInfoTooltip">1- Choose the correct protocol(https or http). \n2- Enter instance url e.g: try.gitea.io. \n3- If you have enabled 2FA for your account, enter the code in the OTP Code field. \n4- For HTTP basic auth use USERNAME@DOMAIN.COM in the URL field.</string>
<string name="malformedUrl">Couldn\'t connect to host. Please check your URL or port for any errors</string>
<string name="protocolError">It is not recommended to use HTTP protocol unless you are testing on local network</string>
<string name="malformedJson">Malformed JSON was received. Server response was not successful</string>
<string name="emptyFieldURL">Instance URL is required</string>
<string name="emptyFieldUsername">Username is required</string>
<string name="emptyFieldPassword">Password is required</string>
<string name="protocolEmptyError">Protocol is required</string>
<string name="instanceHelperText">Enter URL without http or https. Example: codeberg.org</string>
<string name="checkNetConnection">Cannot access network, please check your Internet connection</string>
<string name="repoNameErrorEmpty">Repository name is empty</string>
<string name="repoNameErrorInvalid">Repository name is not valid. [a&#8211;z A&#8211;Z 0&#8211;9 &#8211; _]</string>
<string name="repoNameErrorReservedName">Repository name is reserved</string>
<string name="repoNameErrorReservedPatterns">Repository name contains reserved keywords</string>
<string name="repoDescError">Repository description exceeds the max 255 characters limit</string>
<string name="repoCreated">Repository created successfully</string>
<string name="repoExistsError">Repository of this name already exists under selected Owner</string>
<string name="repoOwnerError">Select owner for the repository</string>
<string name="repoDefaultBranchError">The default branch must not be empty</string>
<string name="orgNameErrorEmpty">Organization name is empty</string>
<string name="orgNameErrorInvalid">Organization name is not valid, [a&#8211;z A&#8211;Z 0&#8211;9 &#8211; _]</string>
<string name="orgDescError">Organization description exceeds the max 255 characters limit</string>
<string name="orgCreated">Organization created successfully</string>
<string name="orgExistsError">Organization already exists</string>
<string name="diffStatistics">%1$s addition(s) and %2$s deletion(s)</string>
<string name="processingText">Processing</string>
<string name="search">Search</string>
<string name="close">Close</string>
<string name="addNewContent">Add</string>
<string name="orgContentAvatar">Org</string>
<string name="repoContentAvatar">Repo</string>
<string name="privateAvatar">Pri</string>
<string name="removeContent">Remove</string>
<string name="genericApiError">Instance has returned an error. Code %d</string>
<string name="tabTextInfo">Details</string>
<string name="tabTextFiles">Files</string>
<string name="tabTextMl">Milestones</string>
<string name="tabTextReleases">Releases</string>
<string name="tabTextBranches">Branches</string>
<string name="tabTextCollaborators">Collaborators</string>
<string name="tabPullRequests">Pull Requests</string>
<string name="pullRequest">Pull Request</string>
<string name="infoTabRepoSize">Size</string>
<string name="infoTabRepoDefaultBranch">Default Branch</string>
<string name="infoTabRepoSshUrl">SSH URL</string>
<string name="infoTabRepoCloneUrl">Clone URL</string>
<string name="infoTabRepoRepoUrl">Repo URL</string>
<string name="infoTabRepoForksCount">Forks</string>
<string name="infoTabRepoCreatedAt">Created</string>
<string name="infoTabRepoUpdatedAt">Last Updated</string>
<string name="infoMoreInformation">More Information</string>
<string name="timeAtText">at</string>
<string name="issueMilestone">Milestone %1$s</string>
<string name="dueDate">Due on %1$s</string>
<string name="assignedTo">Assigned to: %1$s</string>
<string name="assignedToMe">Assigned to Me</string>
<string name="commentButtonText">Comment</string>
<string name="commentEmptyError">Please write your comment</string>
<string name="commentSuccess">Comment posted</string>
<string name="featureDeprecated">This function will be removed in the future</string>
<string name="generalImgContentText">Image</string>
<string name="commitAuthor">Commit author: %1$s</string>
<string name="releaseDownloadText">Downloads</string>
<string name="releasePublishedBy">Published by @%1$s</string>
<string name="noReleaseBodyContent">Release notes are not provided by the publisher.</string>
<string name="newMilestoneTitle">Title</string>
<string name="newMilestoneDescription">Description</string>
<string name="newMilestoneDueDate">Due Date</string>
<string name="milestoneNameErrorEmpty">Milestone title is empty</string>
<string name="milestoneDescError">Milestone description exceeds the max 255 characters limit</string>
<string name="milestoneCreated">Milestone created successfully</string>
<string name="milestoneDateEmpty">Please choose due date</string>
<string name="milestoneNoDueDate">No due date</string>
<string name="milestoneNoDescription">No description</string>
<string name="milestoneIssueStatusOpen">%1$d Open</string>
<string name="milestoneIssueStatusClosed">%1$d Closed</string>
<string name="selectMilestone">Select Milestone</string>
<string name="newIssueSelectAssigneesListTitle">Select Assignees</string>
<string name="newIssueSelectLabelsListTitle">Select Labels</string>
<string name="newIssueTitle">Title</string>
<string name="newIssueAssigneesListTitle">Assignees</string>
<string name="newIssueDescriptionTitle">Description</string>
<string name="newIssueDueDateTitle">Due Date</string>
<string name="newIssueMilestoneTitle">Milestone</string>
<string name="newIssueLabelsTitle">Labels</string>
<string name="issueTitleEmpty">Issue title is empty</string>
<string name="issueDescriptionEmpty">Issue description is empty</string>
<string name="issueCreated">New issue created successfully</string>
<string name="issueCreatedNoMilestone">No milestone</string>
<string name="noAssigneesFound">No assignees found</string>
<!-- 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>
<string name="settingsCertsPopupMessage">Are you sure to delete any manually trusted certificate or hostname? \n\nYou will also be logged out.</string>
<string name="settingsSave">Settings saved</string>
<string name="settingsLanguageSelectorHeader">Language</string>
<string name="settingsLanguageSelectedHeaderDefault">English</string>
<string name="settingsAppearanceHeader">Appearance</string>
<string name="settingsLanguageSelectorDialogTitle">Choose Language</string>
<string name="settingsLightThemeTimeSelectorHeader">Light Theme Switch Time</string>
<string name="settingsDarkThemeTimeSelectorHeader">Dark Theme Switch Time</string>
<string name="settingsTimeSelectorDialogTitle">Choose Time Format</string>
<string name="settingsHelpTranslateText">Translate GitNex via Crowdin</string>
<string name="codeBlockHeaderText">Code Block Color</string>
<string name="settingsCodeBlockSelectorDialogTitle">Code Block Color Selector</string>
<string name="settingsHomeScreenHeaderText">Home Screen</string>
<string name="settingsHomeScreenSelectedText">My Repositories</string>
<string name="settingsHomeScreenSelectorDialogTitle">Select Home Screen</string>
<string name="settingsCustomFontHeaderText">Font</string>
<string name="settingsCustomFontSelectorDialogTitle">Choose Font</string>
<string name="themeSelectorDialogTitle">Select App Theme</string>
<string name="themeSelectionHeaderText">Theme</string>
<string name="settingsCounterBadges">Counter Badges</string>
<string name="settingsFileViewerSourceCodeHeaderText">Source Code Theme</string>
<string name="cacheSizeDataDialogHeader">Data Cache Size</string>
<string name="cacheSizeDataSelectionHeaderText">Data Cache Size</string>
<string name="cacheSizeImagesDialogHeader">Images Cache Size</string>
<string name="cacheSizeImagesSelectionHeaderText">Images Cache Size</string>
<string name="clearCacheSelectionHeaderText">Clear Cache</string>
<string name="clearCacheDialogHeader">Clear Cache?</string>
<string name="clearCacheDialogMessage">This will delete all the cache data including files and images.\n\nProceed with deletion?</string>
<string name="draftsHeader">Drafts</string>
<string name="draftsHintText">Comments draft</string>
<string name="settingsEnableCommentsDeletionText">Enable Drafts Deletion</string>
<string name="settingsEnableCommentsDeletionHintText">Delete comment draft when comment is posted</string>
<string name="settingsGeneralHeader">General</string>
<string name="generalHintText">Home screen, drafts, crash reports</string>
<string name="generalDeepLinkDefaultScreen">Default Link Handler</string>
<string name="generalDeepLinkDefaultScreenHintText">Choose what screen should be loaded if the app cannot handle external links. It will redirect you automatically.</string>
<string name="linkSelectorDialogTitle">Select Default Link Handler Screen</string>
<string name="settingsBiometricHeader">Biometric Support</string>
<string name="settingsLabelsInListHeader">Labels With Text Support</string>
<string name="settingsLabelsInListHint">Enabling this will show labels with text in issues and pr lists, default are color dots</string>
<string name="ceSyntaxHighlightColor">Syntax Highlighting Color</string>
<string name="ceIndentation">Indentation</string>
<string name="ceIndentationTabsWidth">Tabs Width</string>
<string name="system_font">System Default Font</string>
<string name="fragmentTabsAnimationHeader">Tabs Animation</string>
<string name="fadeOut">Fade Out</string>
<string name="zoomOut">Zoom Out</string>
<!-- settings -->
<string name="noMoreData">No more data available</string>
<string name="createLabel">New Label</string>
<string name="menuTitleText">Repo Menu</string>
<string name="labelName">Label Name</string>
<string name="labelColor">Label Color</string>
<string name="labelEmptyError">Label name is empty</string>
<string name="labelNameError">Label name is not valid</string>
<string name="labelCreated">Label created</string>
<string name="labelUpdated">Label updated</string>
<string name="labelMenuContentDesc">Desc</string>
<string name="labelDeleteText">Label deleted</string>
<string name="selectBranchError">Select a branch for release</string>
<string name="alertDialogTokenRevokedTitle">Authorization Error</string>
<string name="alertDialogTokenRevokedMessage">It seems that the Access Token is revoked OR your are not allowed to see these contents.\n\nIn case of revoked Token, please logout and login again</string>
<string name="labelDeleteMessage">Do you really want to delete this label?</string>
<!-- org tabbed layout str -->
<string name="orgTabTeams">Teams</string>
<string name="orgTabMembers">Members</string>
<string name="teamTitle">Team name</string>
<string name="teamDescription">Team desc</string>
<string name="teamPermissions">Permissions</string>
<string name="teamPermissionNone">• Members of this team do not have any permissions.</string>
<string name="teamPermissionRead">• Members of this team can view team repositories.</string>
<string name="teamPermissionWrite">• Members of this team can view and push to team repositories.</string>
<string name="teamPermissionAdmin">• Members of this team can push to and from team repositories and add collaborators.</string>
<string name="teamPermissionOwner">• Members of this team have owner permissions.</string>
<string name="teamShowAll">show all</string>
<string name="orgMember">Org members</string>
<string name="orgTeamMembers">Organization team members</string>
<string name="removeTeamMember">Remove %s</string>
<string name="addTeamMember">Add %s</string>
<string name="addTeamMemberMessage">Do you want to add this user to the team?</string>
<string name="removeTeamMemberMessage">Do you want to remove this user from the team?</string>
<string name="memberAddedMessage">Member added to the team successfully</string>
<string name="memberRemovedMessage">Member removed from the team successfully</string>
<string name="repoAddedMessage">Repository added to the team successfully</string>
<string name="repoRemovedMessage">Repository removed from the team successfully</string>
<string name="repoAddToTeamMessage">Add repository %1$s to organization %2$s team %3$s</string>
<string name="repoRemoveTeamMessage">Remove repository %1$s from team %2$s</string>
<string name="addRemoveMember">Add / Remove Member</string>
<!-- org tabbed layout str -->
<!-- create team -->
<string name="newTeamTitle">Team Name</string>
<string name="newTeamDesc">Description</string>
<string name="newTeamPermission">Permission</string>
<string name="newTeamAccessControls">Access Controls</string>
<string name="newTeamPermissionRead">Members can view and clone team repositories</string>
<string name="newTeamPermissionWrite">Members can read and push to team repositories</string>
<string name="newTeamPermissionAdmin">Members can pull and push to team repositories and add collaborators to them</string>
<string name="teamNameEmpty">Please enter team name</string>
<string name="teamNameError">Team name should contain only alphanumeric, dash (-), underscore (_) and dot (.) characters</string>
<string name="teamPermissionEmpty">Please select permission</string>
<string name="teamDescError">Team description have illegal characters</string>
<string name="teamDescLimit">Team description have more than 100 characters</string>
<string name="teamCreated">Team created successfully</string>
<!-- create team -->
<!-- issue comments -->
<string name="editCommentTitle">Edit Comment</string>
<string name="editCommentUpdatedText">Comment updated</string>
<string name="issueCommentShare">Share Comment</string>
<string name="deleteCommentSuccess">Comment deleted successfully</string>
<string name="copyCommentText">Copy Comment</string>
<!-- issue comments -->
<!-- add collaborator -->
<string name="addCollaboratorSearchHint">Search users</string>
<string name="addCollaboratorViewUserDesc">Username</string>
<string name="removeCollaboratorDialogTitle">Remove %s?</string>
<string name="removeCollaboratorMessage">Do you want to remove this user from the repository?</string>
<string name="removeCollaboratorToastText">User removed from the repository.</string>
<string name="addCollaboratorToastText">User added to the repository.</string>
<!-- add collaborator -->
<!-- profile section -->
<string name="profileTabFollowers">Followers</string>
<string name="profileTabFollowing">Following</string>
<!-- profile section -->
<!-- account settings -->
<string name="accountEmails">Emails</string>
<string name="accountEmailTitle">Email Address</string>
<string name="emailAddedText">New email added successfully</string>
<string name="emailErrorEmpty">Email address is empty</string>
<string name="emailErrorInvalid">Email address is not valid</string>
<string name="emailErrorInUse">Email address is already in use</string>
<string name="emailTypeText">Primary</string>
<string name="sshKeys">SSH Keys</string>
<!-- account settings -->
<!-- single issue section -->
<string name="singleIssueEditLabels">Add / Remove Labels</string>
<string name="labelsUpdated">Labels updated</string>
<string name="closeIssue">Close Issue</string>
<string name="editIssue">Edit Issue</string>
<string name="reOpenIssue">Reopen Issue</string>
<string name="issueStateClosed">Issue closed</string>
<string name="issueStateReopened">Issue reopened</string>
<string name="addRemoveAssignees">Add / Remove Assignees</string>
<string name="assigneesUpdated">Assignees updated</string>
<string name="singleIssueSubscribe">Subscribe</string>
<string name="singleIssueUnSubscribe">Unsubscribe</string>
<!-- single issue section -->
<string name="repoMetaData">Repository Meta</string>
<!-- admin -->
<string name="adminCreateNewUser">New User</string>
<string name="adminUsers">System Users</string>
<string name="userRoleAdmin">Admin</string>
<string name="adminCron">Cron Tasks</string>
<string name="adminCronScheduleHeader">Schedule</string>
<string name="adminCronNextRunHeader">Next Run</string>
<string name="adminCronLastRunHeader">Last Run</string>
<string name="adminCronExecutionHeader">Executions</string>
<string name="adminCronTaskSuccessMsg">Task %1$s is initiated successfully</string>
<!-- admin -->
<!-- create user -->
<string name="userFullNameText">Full Name</string>
<string name="userEmail">Email</string>
<string name="userUserName">Username</string>
<string name="userPassword">Password</string>
<string name="userInvalidFullName">Invalid Full Name</string>
<string name="userInvalidUserName">Invalid Username</string>
<string name="userInvalidEmail">Invalid Email</string>
<string name="userCreatedText">New user added successfully</string>
<string name="userExistsError">User already exists</string>
<!-- create user -->
<!-- edit issue -->
<string name="editIssueNavHeader">Edit Issue #%1$s</string>
<string name="editIssueSuccessMessage">Issue updated</string>
<!-- edit issue -->
<!-- release -->
<string name="createRelease">New Release</string>
<string name="releaseTagNameText">Tag Name</string>
<string name="releaseTitleText">Title</string>
<string name="releaseContentText">Content</string>
<string name="releaseTypeText">Mark as Pre-Release</string>
<string name="releaseBranchText">Select Branch</string>
<string name="releaseDraftText">Draft</string>
<string name="tagNameErrorEmpty">Tag name is empty</string>
<string name="titleErrorEmpty">Title is empty</string>
<string name="releaseCreatedText">New release created</string>
<string name="deleteReleaseConfirmation">Do you really want to delete this release?</string>
<string name="releaseDeleted">Release deleted</string>
<!-- release -->
<string name="loginOTPTypeError">OTP code should be numbers</string>
<string name="loginOTP">OTP Code (Optional)</string>
<string name="otpMessage">Enter otp code if 2FA is enabled</string>
<string name="openWebRepo">Open in Browser</string>
<string name="repoStargazersInMenu">Stargazers</string>
<string name="repoWatchersInMenu">Watchers</string>
<string name="noDataWebsite">No website found</string>
<string name="noDataDescription">No description found</string>
<string name="noDataLocation">No location found</string>
<string name="starMember">Star</string>
<string name="watcherMember">Watcher</string>
<string name="zipArchiveDownloadReleasesTab">Source code (ZIP)</string>
<string name="tarArchiveDownloadReleasesTab">Source code (TAR.GZ)</string>
<!-- new file -->
<string name="newFileNameTintCopy">File Name</string>
<string name="newFileBranchTintCopy">New Branch Name</string>
<string name="newFileContentTintCopy">File Content</string>
<string name="newFileButtonCopy">Create New File</string>
<string name="newFileNameHintMessage">with folder: app/test.md</string>
<string name="newFileMessageTintCopy">Commit Message</string>
<string name="newFileInvalidBranchName">Invalid branch name, may only contain &#8211;, a&#8211;z, 0&#8211;9</string>
<string name="newFileCommitMessageError">Commit message is too long</string>
<string name="newFileSuccessMessage">New file created</string>
<string name="newFileBranches">Select or create a branch</string>
<string name="newFileRequiredFields">Fields like filename, content and commit message are required</string>
<string name="newFileEmptyBranchMessage">Leave blank to push to the default branch</string>
<string name="newFileRequiredFieldNewBranchName">New branch name cannot be empty if current branch is not selected</string>
<string name="strFilter">Filter</string>
<string name="strSwitchBranches">Branches</string>
<string name="strMarkdown">Markdown</string>
<string name="copyIssueUrl">Copy Issue URL</string>
<string name="copyIssueUrlToastMsg">URL copied to clipboard</string>
<string name="copyIssueCommentToastMsg">Comment copied to clipboard</string>
<string name="copyShaToastMsg">SHA copied to clipboard</string>
<string name="milestoneCompletion">%1$d\uFF05 completed</string>
<!-- files -->
<string name="filesGenericError">Sorry this file cannot be viewed as API returned an error</string>
<string name="fileTypeCannotBeEdited">Files of this type cannot be edited</string>
<string name="notSupported">Not supported</string>
<!-- generic copy -->
<string name="okButton">OK</string>
<string name="doneButton">Done</string>
<string name="cancelButton">Cancel</string>
<string name="genericError">Something went wrong, please try again</string>
<string name="apiNotFound">This request needs higher version than the one installed. Please upgrade your instance to the latest version.</string>
<string name="noDataFound">🌟 Nothing in here 🌟</string>
<string name="addButton">Add</string>
<string name="removeButton">Remove</string>
<string name="authorizeError">You are not authorized to perform this action.</string>
<string name="menuContentDesc">Menu</string>
<string name="menuEditText">Edit</string>
<string name="menuDeleteText">Delete</string>
<string name="menuCopyText">Copy</string>
<string name="menuQuoteText">Quote Reply</string>
<string name="modifiedText">edited</string>
<string name="saveButton">Save</string>
<string name="websiteText">Website</string>
<string name="locationText">Location</string>
<string name="characters255Limit">Max 255 characters</string>
<string name="emptyFields">All fields are required</string>
<string name="textContinue">Continue</string>
<string name="copyToken">Token</string>
<string name="viewInBrowser">View in Browser</string>
<string name="isOpen">Open</string>
<string name="isClosed">Closed</string>
<string name="genericServerResponseError">We cannot reach the server at the moment, please check your server status and try again</string>
<string name="genericCopyUrl">Copy URL</string>
<string name="genericWaitFor">Hold on ☕</string>
<string name="file">File</string>
<string name="issue">Issue</string>
<string name="labelTxt">Label</string>
<string name="release">Release</string>
<string name="pr">Pull Request</string>
<string name="collaborator">Collaborator</string>
<string name="unstar">Unstar</string>
<string name="watch">Watch</string>
<string name="unwatch">Unwatch</string>
<string name="share">Share</string>
<string name="repository">Repository</string>
<string name="team">Team</string>
<string name="organization">Organization</string>
<string name="addRemove">Add / Remove</string>
<string name="download">Download</string>
<string name="reopen">Reopen</string>
<string name="openInBrowser">Open in Browser</string>
<string name="deleteGenericTitle">Delete %s</string>
<string name="reset">Reset</string>
<string name="beta">BETA</string>
<string name="none">None</string>
<string name="main">main</string>
<string name="license">License</string>
<!-- generic copy -->
<string name="exploreUsers">Explore users</string>
<string name="exploreIssues">Explore issues</string>
<string name="exploreTextBoxHint">Explore repositories</string>
<string name="starRepositorySuccess">Repository added to starred list</string>
<string name="unStarRepositorySuccess">Repository removed from starred list</string>
<string name="watchRepositorySuccess">Repository added to watch list</string>
<string name="unWatchRepositorySuccess">Repository removed from watch list</string>
<string name="titleDrafts">Drafts</string>
<string name="versionUnsupportedOld">Unsupported old version(%1$s) of Gitea detected. Please update to latest stable version. If you continue, some features may not work.</string>
<string name="versionUnsupportedNew">New Gitea version detected! Please UPDATE GitNex!</string>
<string name="versionUnknown">No Gitea detected!</string>
<string name="versionAlertDialogHeader">Unsupported Version of Gitea</string>
<string name="loginViaPassword">Basic Auth</string>
<string name="unauthorizedApiError">Instance has returned an error - Unauthorized. Check your credentials and try again</string>
<string name="loginTokenError">Token is required</string>
<string name="prDeletedFork">Deleted Fork</string>
<string name="editPrNavHeader">Edit Pull Request #%1$s</string>
<string name="editPrSuccessMessage">Pull Request updated</string>
<string name="fileDiffViewHeader">%1$s Files Changed</string>
<string name="fileDiffViewHeaderSingle">%1$s File Changed</string>
<string name="updatePullRequestText">Update Pull Request</string>
<string name="openFileDiffText">Show Changed Files</string>
<string name="mergePullRequestText">Merge Pull Request</string>
<string name="deleteBranchSuccess">Branch deleted successfully</string>
<string name="deleteBranchError">Could not delete branch</string>
<string name="deleteBranchErrorNotFound">Branch does not exist</string>
<string name="mergePullRequestButtonText">Merge</string>
<string name="deleteBranchAfterMerge">Delete branch after merge</string>
<string name="mergeNoteText">Merge may fail if you are not authorized to merge this Pull Request.</string>
<string name="mergeInfoDisabledMessage">Disabled Merge button means that there are conflicts OR other things to fix before Merge</string>
<string name="deleteBranchForkInfo">This branch belong to a forked repository</string>
<string name="mergeCommentText">Merge comment</string>
<string name="mergePRSuccessMsg">Pull Request was merged successfully</string>
<string name="mergePR404ErrorMsg">Pull Request is not available for merge</string>
<string name="mergeOptionMerge">Merge Pull Request</string>
<string name="mergeOptionRebase">Rebase and Merge</string>
<string name="mergeOptionRebaseCommit">Rebase and Merge (&#45;&#45;no-ff)</string>
<string name="mergeOptionSquash">Squash and Merge</string>
<string name="mergeStrategy">Merge Strategy</string>
<string name="selectMergeStrategy">Select merge strategy</string>
<string name="mergeNotAllowed">Not allowed to merge [Reason: Does not have enough approvals]</string>
<string name="deleteBranch">Delete Branch</string>
<string name="waitLoadingDownloadFile">Please wait for the file to load to memory</string>
<string name="downloadFileSaved">File saved successfully</string>
<string name="excludeFilesInFileViewer">This file type/size is not supported in file viewer. You can download it from the menu.</string>
<string name="deleteFile">Delete This File</string>
<string name="editFile">Edit This File</string>
<string name="deleteFileMessage">File is set for deletion by branch %1$s</string>
<string name="editFileText">Edit %1$s</string>
<string name="editFileMessage">File is modified by branch %1$s</string>
<string name="sizeCopy">Size</string>
<string name="shareIssue">Share Issue</string>
<string name="shareRepository">Share Repository</string>
<string name="createRepository">Create Repository</string>
<string name="commitTitle">Commits</string>
<string name="commitAuthoredByAndCommittedByWhen"><![CDATA[<b>%1$s</b> authored and <b>%2$s</b> committed %3$s]]></string>
<string name="commitCommittedByWhen"><![CDATA[<b>%1$s</b> committed %2$s]]></string>
<string name="viewCommits">View Commits</string>
<!-- Memorizing Trust Manager -->
<string name="mtmNotification">Certificate Verification</string>
<string name="mtmAcceptCert">Accept Unknown Certificate?</string>
<string name="mtmTrustAnchor">The server certificate is not signed by a known Certificate Authority</string>
<string name="mtmCertExpired">The server certificate is expired.</string>
<string name="mtmAcceptServerName">Accept Mismatching Server Name?</string>
<string name="mtmHostnameMismatch">Server could not authenticate as \&quot;%s\&quot;. The certificate is only valid for:</string>
<string name="mtmConnectAnyway">Do you want to connect anyway?</string>
<string name="mtmCertDetails">Certificate details:</string>
<string name="mtmDecisionAlways">Trust</string>
<string name="mtmDecisionAbort">Abort</string>
<string name="subscribedSuccessfully">Subscribed successfully</string>
<string name="alreadySubscribed">You have already subscribed</string>
<string name="subscriptionError">Subscription failed</string>
<string name="unsubscribedSuccessfully">Unsubscribed successfully</string>
<string name="alreadyUnsubscribed">You have already Unsubscribed</string>
<string name="unSubscriptionError">Un-Subscription failed</string>
<string name="closeMilestone">Close Milestone</string>
<string name="openMilestone">Open Milestone</string>
<string name="milestoneStatusUpdate">Milestone status updated successfully</string>
<string name="reportViewerHeader">Crash Reports</string>
<string name="settingsEnableReportsText">Enable Crash Reports</string>
<string name="crashTitle">GitNex has stopped :(</string>
<string name="setCrashReports">Crash reports</string>
<string name="crashMessage">It is encouraged to open an issue at the project repository with how to reproduce this bug. It is easier to debug and fix the problem that way.\n\nTap the OK button to send the crash report by email instead. Additional content could be added in the email.\nThank you!</string>
<string name="forceLogoutDialogHeader">Please sign in again</string>
<string name="forceLogoutDialogDescription">Due to some major changes regarding the internal functioning of the app, we require you to login again. These changes allow us to make the app more flexible in the future.\n\nThank you for your patience and sorry for the inconvenience.</string>
<string name="deleteAllDrafts">Delete All Drafts</string>
<string name="draftsListEmpty">No drafts found</string>
<string name="draftsDeleteSuccess">Drafts deleted successfully</string>
<string name="draftsSingleDeleteSuccess">Draft deleted successfully</string>
<string name="deleteAllDraftsDialogMessage">This will delete all the drafts for this account. \n\nProceed with deletion?</string>
<string name="draftSaved">Draft was saved automatically.</string>
<string name="resetMostReposCounter">Counter is reset successfully</string>
<string name="resetCounterDialogMessage">Do you want to reset counter for repository %s?</string>
<string name="resetCounterAllDialogMessage">This will reset all the counters for this account repositories.</string>
<string name="appearanceHintText">Themes, fonts, badges, translation</string>
<string name="securityHintText">Biometric authentication, SSL certificates, cache</string>
<string name="languagesHintText">Languages</string>
<string name="reportsHintText">Crash reports</string>
<string name="rateAppHintText">如果你也喜歡 GitNext歡迎五星好評</string>
<string name="aboutAppHintText">App version, build, user instance version</string>
<string name="codeEditorHintText">Syntax color, indentation</string>
<string name="archivedRepository">Archived</string>
<string name="archivedRepositoryMessage">This repo is archived. You can view files, but cannot push or open issues/pull-requests.</string>
<string name="accountDeletedMessage">Account deleted successfully</string>
<string name="removeAccountPopupTitle">Remove Account</string>
<string name="removeAccountPopupMessage">Are you sure you want to remove this account from the app?\n\nThis will remove all the data related to this account on the app only.</string>
<string name="addNewAccount">New Account</string>
<string name="addNewAccountText">Add Account</string>
<string name="accountAlreadyExistsError">Account already exists in the app</string>
<string name="accountAddedMessage">Account added successfully</string>
<string name="switchAccountSuccess">Switched to account : %1$s@%2$s</string>
<!-- Notifications -->
<string name="pageTitleNotifications">Notifications</string>
<string name="noDataNotifications">All caught up 🚀</string>
<string name="notificationsPollingHeaderText">Notifications Polling Delay</string>
<string name="pollingDelay15Minutes">15 Minutes</string>
<string name="pollingDelay30Minutes">30 Minutes</string>
<string name="pollingDelay45Minutes">45 Minutes</string>
<string name="pollingDelay1Hour">1 Hour</string>
<string name="pollingDelayDialogHeaderText">Select Polling Delay</string>
<string name="pollingDelayDialogDescriptionText">Choose a minutely delay in which GitNex tries to poll new notifications</string>
<string name="markAsRead">Mark Read</string>
<string name="markAsUnread">Mark Unread</string>
<string name="pinNotification">Pin</string>
<string name="markedNotificationsAsRead">Successfully marked all notifications as read</string>
<string name="notificationsHintText">Polling delay</string>
<string name="enableNotificationsHeaderText">Enable Notifications</string>
<string name="enableLightsHeaderText">Enable Light</string>
<string name="enableVibrationHeaderText">Enable Vibration</string>
<string name="chooseColorSelectorHeader">Choose Color</string>
<string name="newMessages">New messages for %s</string>
<string name="youHaveGotNewNotifications">您有 %d 則新通知</string>
<string name="mainNotificationChannelName">Notifications</string>
<string name="mainNotificationChannelDescription">This is the main notification channel of GitNex.</string>
<plurals name="youHaveNewNotifications">
<item quantity="other">You have %s new notifications</item>
</plurals>
<string name="openAppSettings">To receive notifications, you must enable notifications for GitNex. Tap Open to access your phone settings and enable notifications.</string>
<string name="isRead">Read</string>
<string name="isUnread">Unread</string>
<string name="repoSettingsTitle">Repository Settings</string>
<string name="repoSettingsEditProperties">Edit Properties</string>
<string name="repoSettingsDelete">Delete Repository</string>
<string name="repoSettingsDeleteHint">Be careful, this operation CANNOT be undone!</string>
<string name="repoPropertiesTemplate">Set as Template</string>
<string name="repoPropertiesEnableIssues">Enable Issues</string>
<string name="repoPropertiesExternalIssuesUrl">External Issue Tracker Url</string>
<string name="repoPropertiesEnableWiki">Enable Wiki</string>
<string name="repoPropertiesExternalWikiUrl">External Wiki Url</string>
<string name="repoPropertiesEnablePr">Enable Pull Requests</string>
<string name="repoPropertiesEnableTimeTracker">Enable Time Tracker</string>
<string name="repoPropertiesEnableMergeCommits">Enable Merge Commits</string>
<string name="repoPropertiesEnableRebase">Enable Rebase</string>
<string name="repoPropertiesEnableSquash">Enable Squash and Merge</string>
<string name="repoPropertiesEnableForceMerge">Enable Rebase with Merge Commits (&#8212;&#8212;no-ff)</string>
<string name="repoPropertiesSaveSuccess">Repository properties updated successfully</string>
<string name="repoSettingsDeleteDescription">Things to know before deletion:\n\n- This operation CANNOT be undone.\n- This operation will permanently delete the repository including code, issues, comments, wiki data and collaborator settings.\n\nEnter the repository name as confirmation</string>
<string name="repoSettingsDeleteError">Repository name does not match</string>
<string name="repoDeletionSuccess">Repository deleted successfully</string>
<string name="repoSettingsTransferOwnership">Transfer Ownership</string>
<string name="repoSettingsTransferOwnershipHint">Transfer this repository to a user or to an organization for which you have administrator rights</string>
<string name="repoSettingsTransferOwnershipDescription">Things to know before transfer:\n\n- You will lose access to the repository if you transfer it to an individual user.\n- You will keep access to the repository if you transfer it to an organization that you (co-)own.\n\nEnter the repository name as confirmation</string>
<string name="repoTransferText">Perform Transfer</string>
<string name="repoTransferOwnerText">New Owner</string>
<string name="repoTransferSuccess">Repository transferred successfully</string>
<string name="repoTransferOwnerError">New owner is required</string>
<string name="repoTransferError">There is a problem with the owner name. Make sure that the new owner exists</string>
<string name="exploreFilterDialogTitle">Filter Repositories</string>
<string name="exploreFilterIncludeTopic">Search ONLY in Topic</string>
<string name="exploreFilterIncludeDesc">Search in Description</string>
<string name="exploreFilterIncludeArchive">Only Archived Repositories</string>
<string name="exploreFilterIncludePrivate">Only Private Repositories</string>
<string name="exploreFilterIncludeTemplateRepos">Search in Template Repositories</string>
<string name="mergeIntoBranch">Merge Into</string>
<string name="pullFromBranch">Pull From</string>
<string name="sameBranchesError">These branches are equal. There is no need to create a pull request</string>
<string name="mergeIntoError">Merge into branch is required</string>
<string name="pullFromError">Pull from branch is required</string>
<string name="titleError">Title is required</string>
<string name="prCreateSuccess">Pull Request created successfully</string>
<string name="prAlreadyExists">A pull request between these branches already exists</string>
<string name="prClosed">Pull Request closed</string>
<string name="prReopened">Pull Request reopened</string>
<string name="prMergeInfo">Pull Request Info</string>
<string name="accountDoesNotExist">It seems that the account for URI %1$s does not exist in the app. You can add one by tapping on the Add New Account button.</string>
<string name="launchApp">Go to App</string>
<string name="noActionText">GitNex cannot handle the requested resource. You can open an issue at the project repository as an improvement, providing details of the work. Just launch a default screen for now from the buttons below; it can be changed from settings.</string>
<string name="biometricAuthTitle">Biometric Authentication</string>
<string name="biometricAuthSubTitle">Unlock using your biometric credentials</string>
<string name="biometricNotSupported">No biometric features available on this device</string>
<string name="biometricNotAvailable">Biometric features are currently unavailable</string>
<string name="enrollBiometric">Enroll biometric from phone settings</string>
<string name="copyLoginIdToClipBoard">Login ID \'%s\' copied to clipboard</string>
<!-- file viewer activity -->
<string name="fileViewerNotificationTitleStarted">Download in progress</string>
<string name="fileViewerNotificationDescriptionStarted">Downloading %s</string>
<string name="fileViewerNotificationTitleFinished">Download successful</string>
<string name="fileViewerNotificationDescriptionFinished">Downloaded %s</string>
<string name="fileViewerNotificationTitleFailed">Download failed</string>
<string name="fileViewerNotificationDescriptionFailed">Couldn\'t download %s</string>
<string name="fileViewerNotificationChannelName">Download manager</string>
<string name="fileViewerNotificationChannelDescription">Indicates the progress of ongoing downloads</string>
<string name="lastUpdatedAt">Updated %s</string>
<string name="joined">Joined</string>
<string name="userFollow">Follow</string>
<string name="unfollowUser">Unfollow</string>
<string name="unfollowedUser">Unfollowed @%s</string>
<string name="nowFollowUser">You now follow @%s</string>
<string name="unfollowingFailed">Couldn\'t unfollow user</string>
<string name="followingFailed">Couldn\'t follow user</string>
<string name="updatePrConflict">The pull request conflicts with the base branch. Please resolve the conflicts and try again.</string>
<string name="updatePrSuccess">Pull Request updated successfully</string>
<string name="updateStrategyMerge">Merge</string>
<string name="updateStrategyRebase">Rebase</string>
<string name="selectUpdateStrategy">Select Update Strategy</string>
<string name="userAvatar">Avatar</string>
<string name="tags">Tags</string>
<string name="releasesTags">Releases/Tags</string>
<string name="create_tag">Create Tag Only</string>
<string name="tagCreated">Tag created</string>
<string name="asRef">Use as reference</string>
<string name="deleteTagConfirmation">Do you really want to delete this tag?</string>
<string name="tagDeleted">Tag deleted</string>
<string name="tagDeleteError">A tag attached to a release cannot be deleted directly</string>
<string name="useCustomTabs">Use Custom Tabs</string>
<string name="browserOpenFailed">No application found to open this link. SSH URLs and URLs with another prefix the http:// or https:// are not supported by most browser</string>
<string name="logInAgain">Log in again</string>
<string name="notLoggedIn">%s \u25CF not logged in</string>
<string name="followSystem">Follow system (Light/Dark)</string>
<string name="followSystemBlack">Follow system (Light/Pitch Black)</string>
<string name="dynamicColorsFollowSystem">Dynamic colors - Follow system (Light/Dark)</string>
<string name="codebergDark">Codeberg (Dark)</string>
<string name="repoForkOf">Fork of: %s</string>
<string name="adoptRepo">Adopt</string>
<string name="repoAdopted">Adopted repository %s</string>
<string name="unadoptedRepos">Unadopted Repositories</string>
<string name="unadoptedReposMessage">- Adopt will add repository %1$s to organization/user %2$s.\n- Delete will remove it from the system.</string>
<string name="commits">Commits</string>
<!-- wiki -->
<string name="wiki">Wiki</string>
<string name="wikiAuthor"><![CDATA[<b>%1$s</b> updated %2$s]]></string>
<string name="deleteWikiPageMessage">Do you really want to delete %s?</string>
<string name="wikiPageDeleted">Wiki page deleted successfully</string>
<string name="wikiPageNameAndContentError">Page name and page content can\'t be empty</string>
<string name="createWikiPage">Create Wiki Page</string>
<string name="wikiUpdated">Wiki page updated successfully</string>
<string name="wikiCreated">Wiki page created successfully</string>
<!-- code editor -->
<string name="openInCodeEditor">Open in Code Editor</string>
<!-- notes -->
<string name="newNote">New Note</string>
<string name="editNote">Edit Note</string>
<string name="newNoteContentHint">Start taking your notes here</string>
<string name="noteDateTime">Created %s</string>
<string name="noteTimeModified">Updated %s</string>
<string name="noteDeleteDialogMessage">Do you really want to delete this note?</string>
<plurals name="noteDeleteMessage">
<item quantity="other">Notes deleted successfully</item>
</plurals>
<string name="notesAllDeletionMessage">This will delete all of your notes. This action cannot be undone.</string>
<!-- timeline -->
<string name="commitsText">commit</string>
<string name="commitText">commit</string>
<string name="timelineAddedCommit">%1$s added %2$s %3$s</string>
<!-- the | is replaced by the label -->
<string name="timelineAddedLabel">%1$s added the | label %2$s</string>
<!-- the | is replaced by the label -->
<string name="timelineRemovedLabel">%1$s removed the | label %2$s</string>
<string name="timelineAssigneesRemoved">%1$s removed their assignment %2$s</string>
<string name="timelineAssigneesUnassigned">%1$s was unassigned by %2$s %3$s</string>
<string name="timelineAssigneesSelfAssigned">%1$s self-assigned this %2$s</string>
<string name="timelineAssigneesAssigned">%1$s was assigned by %2$s %3$s</string>
<string name="timelineMilestoneAdded">%1$s added this to the %2$s milestone %3$s</string>
<string name="timelineMilestoneRemoved">%1$s removed this from the %2$s milestone %3$s</string>
<string name="timelineMilestoneDeleted">%1$s added this to a deleted milestone %2$s</string>
<string name="timelineStatusClosedIssue">%1$s closed this issue %2$s</string>
<string name="timelineStatusReopenedIssue">%1$s reopened this issue %2$s</string>
<string name="timelineStatusReopenedPr">%1$s reopened this pull request %2$s</string>
<string name="timelineStatusClosedPr">%1$s closed this pull request %2$s</string>
<string name="timelineStatusMergedPr">%1$s merged this pull request %2$s</string>
<string name="timelineStatusRefPr"><![CDATA[%1$s referenced this pull request from a <font color=\'%2$d\'>%3$s</font> %4$s]]></string>
<string name="timelineReviewRequest">%1$s requested review from %2$s %3$s</string>
<string name="timelineChangeTitle">%1$s changed title from %2$s to %3$s %4$s</string>
<string name="timelineLocked">%1$s locked as %2$s and limited conversation to collaborators %3$s</string>
<string name="timelineUnlocked">%1$s unlocked this conversation %2$s</string>
<string name="timelineDependencyAdded">%1$s added a new dependency #%2$d %3$s</string>
<string name="timelineDependencyRemoved">%1$s removed a dependency #%2$d %3$s</string>
<string name="timelineProjectAdded">%1$s added this to a project %2$s</string>
<string name="timelineProjectRemoved">%1$s removed this from a project %2$s</string>
<string name="timelineDueDateAdded">%1$s added the due date %2$s %3$s</string>
<string name="timelineDueDateModified">%1$s modified the due date to %2$s from %3$s %4$s</string>
<string name="timelineDueDateRemoved">%1$s removed the due date %2$s %3$s</string>
<string name="timelineBranchChanged">%1$s changed target branch from %2$s to %3$s %4$s</string>
<string name="timelineBranchDeleted">%1$s deleted branch %2$s %3$s</string>
<string name="timelineTimeTrackingStart">%1$s started working %2$s</string>
<string name="timelineTimeTrackingStop">%1$s stopped time tracking %2$s</string>
<string name="timelineTimeTrackingCancel">%1$s cancelled time tracking %2$s</string>
<string name="timelineTimeTrackingAddManualTime">%1$s added spent time %2$s %3$s</string>
<string name="timelineTimeTrackingDeleteManualTime">%1$s deleted spent time %2$s %3$s</string>
<string name="timelineChangeIssueRef">%1$s added reference %2$s %3$s</string>
<string name="timelineRefIssue">%1$s referenced this issue in #%2$d %3$s</string>
<string name="timelineRefPr">%1$s referenced this pull request in #%2$d %3$s</string>
<string name="timelineStatusRefIssue"><![CDATA[%1$s referenced this issue from a <font color=\'%2$d\'>%3$s</font> %4$s]]></string>
<string name="timelineReviewLeftComment">%1$s left a comment: %2$s %3$s</string>
<string name="commitStatuses">Statuses</string>
<string name="statusNoUrl">This status has no linked target URL.</string>
<string name="starredRepos">Starred Repos</string>
<string name="lang_statistics">Language Statistics</string>
<string name="dashboard">Dashboard</string>
<string name="createdRepository">created repository</string>
<string name="renamedRepository">renamed repository from %1$s to</string>
<string name="starredRepository">starred</string>
<string name="transferredRepository">transferred repository %1$s to</string>
<string name="createdBranch">created branch %1$s in</string>
<string name="pushedTo">pushed to %1$s at</string>
<string name="openedIssue">opened issue</string>
<string name="commentedOnIssue">commented on issue</string>
<string name="closedIssue">closed issue</string>
<string name="reopenedIssue">reopened issue</string>
<string name="createdPR">created pull request</string>
<string name="closedPR">closed pull request</string>
<string name="reopenedPR">reopened pull request</string>
<string name="mergedPR">merged pull request</string>
<string name="approved">approved</string>
<string name="suggestedChanges">suggested changes for</string>
<string name="commentedOnPR">commented on pull request</string>
<string name="autoMergePR">automatically merged pull request</string>
<string name="deletedBranch">deleted branch %1$s at</string>
<string name="pushedTag">pushed tag %1$s to</string>
<string name="deletedTag">deleted tag %1$s from</string>
<string name="releasedBranch">released %1$s at</string>
<string name="syncedCommits">synced commits to %1$s at</string>
<string name="syncedRefs">synced new reference %1$s to</string>
<string name="syncedDeletedRefs">synced and deleted reference %1$s at</string>
<string name="attachment">Attachment</string>
<string name="attachments">Attachments</string>
<string name="attachmentsSaveError">An issue was created but cannot process attachments at this time. Check the server logs for more details.</string>
</resources>

View File

@ -20,6 +20,8 @@
<item>tr</item>
<item>uk</item>
<item>el</item>
<item>eo</item>
<item>zh-TW</item>
</string-array>
<string-array name="fonts">

View File

@ -237,10 +237,8 @@
<string name="settingsFileViewerSourceCodeSelectedText" translatable="false">Sublime</string>
<string name="cacheSizeDataDialogHeader">Data Cache Size</string>
<string name="cacheSizeDataSelectionHeaderText">Data Cache Size</string>
<string name="cacheSizeDataSelectionSelectedText" translatable="false">50 MB</string>
<string name="cacheSizeImagesDialogHeader">Images Cache Size</string>
<string name="cacheSizeImagesSelectionHeaderText">Images Cache Size</string>
<string name="cacheSizeImagesSelectionSelectedText" translatable="false">50 MB</string>
<string name="clearCacheSelectionHeaderText">Clear Cache</string>
<string name="clearCacheSelectionSelectedText" translatable="false">0 B</string>
<string name="clearCacheDialogHeader">Clear Cache?</string>
@ -876,6 +874,7 @@
<string name="timelineRefPr">%1$s referenced this pull request in #%2$d %3$s</string>
<string name="timelineStatusRefIssue"><![CDATA[%1$s referenced this issue from a <font color=\'%2$d\'>%3$s</font> %4$s]]></string>
<string name="timelineReviewLeftComment">%1$s left a comment: %2$s %3$s</string>
<string name="timelinePinned">%1$s pinned this %2$s</string>
<string name="commitStatuses">Statuses</string>
<string name="statusNoUrl">This status has no linked target URL.</string>

View File

@ -5,7 +5,7 @@ preserve_hierarchy: false
files: [
{
"source": "app/src/main/res/values/strings.xml",
"translation": "app/src/main/res/values-%two_letters_code%/strings.xml",
"translation": "app/src/main/res/values-%android_code%/strings.xml",
},
{
"source": "fastlane/metadata/android/en-US/short_description.txt",