Fixing and improving scaling of images, improving performance by doing work that has to be done once only once and using different terminology. (#831)

remove unknown case for editing

Improve var names and code formatting

Minor improvements.

Restoring ACRA functionality.

Fixing and improving scaling of images, improving performance by doing work that has to be done once only once and using different terminology.

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/831
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-Authored-By: opyale <opyale@noreply.codeberg.org>
Co-Committed-By: opyale <opyale@noreply.codeberg.org>
This commit is contained in:
opyale 2021-02-13 20:31:38 +01:00 committed by M M Arif
parent 711711274e
commit d8a14105c9
36 changed files with 387 additions and 369 deletions

View File

@ -9,9 +9,10 @@
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<application <application
android:name=".core.MainApplication"
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/app_logo" android:icon="@mipmap/app_logo"
android:label="@string/app_name" android:label="@string/appName"
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:resizeableActivity="true" android:resizeableActivity="true"
android:roundIcon="@mipmap/app_logo_round" android:roundIcon="@mipmap/app_logo_round"
@ -64,7 +65,7 @@
<activity <activity
android:name=".activities.OrganizationDetailActivity" android:name=".activities.OrganizationDetailActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
android:label="@string/title_activity_org_detail" android:label="@string/titleActivityOrgDetail"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".activities.CreateLabelActivity" android:name=".activities.CreateLabelActivity"
@ -82,7 +83,7 @@
<activity <activity
android:name=".activities.RepoDetailActivity" android:name=".activities.RepoDetailActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
android:label="@string/title_activity_repo_detail" android:label="@string/titleActivityRepoDetail"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".activities.MainActivity" android:name=".activities.MainActivity"

View File

@ -254,7 +254,7 @@ public class IssueActions {
} }
else { else {
Toasty.error(ctx, ctx.getString(R.string.unsubscriptionError)); Toasty.error(ctx, ctx.getString(R.string.unSubscriptionError));
} }

View File

@ -1,39 +1,17 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import org.acra.ACRA;
import org.acra.BuildConfig;
import org.acra.annotation.AcraCore;
import org.acra.annotation.AcraNotification;
import org.acra.config.CoreConfigurationBuilder;
import org.acra.config.LimiterConfigurationBuilder;
import org.acra.config.MailSenderConfigurationBuilder;
import org.acra.data.StringFormat;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.notifications.NotificationsMaster;
import static org.acra.ReportField.ANDROID_VERSION;
import static org.acra.ReportField.PHONE_MODEL;
import static org.acra.ReportField.STACK_TRACE;
/** /**
* Author M M Arif * Author M M Arif
*/ */
@SuppressLint("NonConstantResourceId")
@AcraNotification(resIcon = R.drawable.gitnex_transparent,
resTitle = R.string.crashTitle,
resChannelName = R.string.setCrashReports,
resText = R.string.crashMessage)
@AcraCore(reportContent = { ANDROID_VERSION, PHONE_MODEL, STACK_TRACE })
public abstract class BaseActivity extends AppCompatActivity { public abstract class BaseActivity extends AppCompatActivity {
protected TinyDB tinyDB; protected TinyDB tinyDB;
@ -44,6 +22,8 @@ public abstract class BaseActivity extends AppCompatActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.appCtx = getApplicationContext(); this.appCtx = getApplicationContext();
this.tinyDB = TinyDB.getInstance(appCtx); this.tinyDB = TinyDB.getInstance(appCtx);
@ -96,84 +76,8 @@ public abstract class BaseActivity extends AppCompatActivity {
} }
String appLocale = tinyDB.getString("locale"); AppUtil.setAppLocale(getResources(), tinyDB.getString("locale"));
AppUtil.setAppLocale(getResources(), appLocale);
super.onCreate(savedInstanceState);
// FIXME Performance nightmare
switch(tinyDB.getInt("customFontId", -1)) {
case 0:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/roboto.ttf");
break;
case 2:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/sourcecodeproregular.ttf");
break;
default:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/manroperegular.ttf");
}
if(tinyDB.getInt("pollingDelayMinutes", 0) <= 0) {
tinyDB.putInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay);
}
// FIXME Performance nightmare
NotificationsMaster.hireWorker(appCtx);
// enabling counter badges by default
if(tinyDB.getString("enableCounterBadgesInit").isEmpty()) {
tinyDB.putBoolean("enableCounterBadges", true);
tinyDB.putString("enableCounterBadgesInit", "yes");
}
// enable crash reports by default
if(tinyDB.getString("crashReportingEnabledInit").isEmpty()) {
tinyDB.putBoolean("crashReportingEnabled", true);
tinyDB.putString("crashReportingEnabledInit", "yes");
}
// default cache setter
if(tinyDB.getString("cacheSizeStr").isEmpty()) {
tinyDB.putString("cacheSizeStr", getResources().getString(R.string.cacheSizeDataSelectionSelectedText));
}
if(tinyDB.getString("cacheSizeImagesStr").isEmpty()) {
tinyDB.putString("cacheSizeImagesStr", getResources().getString(R.string.cacheSizeImagesSelectionSelectedText));
}
// enable comment drafts by default
if(tinyDB.getString("draftsCommentsDeletionEnabledInit").isEmpty()) {
tinyDB.putBoolean("draftsCommentsDeletionEnabled", true);
tinyDB.putString("draftsCommentsDeletionEnabledInit", "yes");
}
// FIXME Performance nightmare
if (tinyDB.getBoolean("crashReportingEnabled")) {
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this);
ACRABuilder.setBuildConfigClass(BuildConfig.class).setReportFormat(StringFormat.KEY_VALUE_LIST);
ACRABuilder.getPluginConfigurationBuilder(MailSenderConfigurationBuilder.class).setReportAsFile(true).setMailTo(getResources().getString(R.string.appEmail)).setSubject(getResources().getString(R.string.crashReportEmailSubject, AppUtil.getAppBuildNo(getApplicationContext()))).setEnabled(true);
ACRABuilder.getPluginConfigurationBuilder(LimiterConfigurationBuilder.class).setEnabled(true);
ACRA.init(getApplication(), ACRABuilder);
}
} }
} }

View File

@ -162,7 +162,6 @@ public class CreateFileActivity extends BaseActivity {
private void processNewFile() { private void processNewFile() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
String newFileName_ = newFileName.getText().toString(); String newFileName_ = newFileName.getText().toString();
String newFileContent_ = newFileContent.getText().toString(); String newFileContent_ = newFileContent.getText().toString();
@ -181,7 +180,7 @@ public class CreateFileActivity extends BaseActivity {
return; return;
} }
if(!appUtil.checkStringsWithDash(newFileBranchName_)) { if(!AppUtil.checkStringsWithDash(newFileBranchName_)) {
Toasty.error(ctx, getString(R.string.newFileInvalidBranchName)); Toasty.error(ctx, getString(R.string.newFileInvalidBranchName));
return; return;
@ -198,7 +197,7 @@ public class CreateFileActivity extends BaseActivity {
switch(fileAction) { switch(fileAction) {
case FILE_ACTION_CREATE: case FILE_ACTION_CREATE:
createNewFile(Authorization.get(ctx), repoOwner, repoName, newFileName_, appUtil.encodeBase64(newFileContent_), newFileCommitMessage_, newFileBranchName_); createNewFile(Authorization.get(ctx), repoOwner, repoName, newFileName_, AppUtil.encodeBase64(newFileContent_), newFileCommitMessage_, newFileBranchName_);
break; break;
case FILE_ACTION_DELETE: case FILE_ACTION_DELETE:
@ -207,7 +206,7 @@ public class CreateFileActivity extends BaseActivity {
case FILE_ACTION_EDIT: case FILE_ACTION_EDIT:
editFile(Authorization.get(ctx), repoOwner, repoName, filePath, editFile(Authorization.get(ctx), repoOwner, repoName, filePath,
appUtil.encodeBase64(newFileContent_), newFileCommitMessage_, newFileBranchName_, fileSha); AppUtil.encodeBase64(newFileContent_), newFileCommitMessage_, newFileBranchName_, fileSha);
break; break;
} }

View File

@ -122,7 +122,7 @@ public class CreateLabelActivity extends BaseActivity {
private void processUpdateLabel() { private void processUpdateLabel() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
String repoFullName = tinyDB.getString("repoFullName"); String repoFullName = tinyDB.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
@ -152,7 +152,7 @@ public class CreateLabelActivity extends BaseActivity {
return; return;
} }
if(!appUtil.checkStrings(updateLabelName)) { if(!AppUtil.checkStrings(updateLabelName)) {
Toasty.error(ctx, getString(R.string.labelNameError)); Toasty.error(ctx, getString(R.string.labelNameError));
return; return;
@ -167,7 +167,6 @@ public class CreateLabelActivity extends BaseActivity {
private void processCreateLabel() { private void processCreateLabel() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
String repoFullName = tinyDB.getString("repoFullName"); String repoFullName = tinyDB.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
@ -198,7 +197,7 @@ public class CreateLabelActivity extends BaseActivity {
return; return;
} }
if(!appUtil.checkStrings(newLabelName)) { if(!AppUtil.checkStrings(newLabelName)) {
Toasty.error(ctx, getString(R.string.labelNameError)); Toasty.error(ctx, getString(R.string.labelNameError));
return; return;

View File

@ -92,7 +92,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
private void processNewMilestone() { private void processNewMilestone() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = TinyDB.getInstance(appCtx); TinyDB tinyDb = TinyDB.getInstance(appCtx);
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");

View File

@ -17,7 +17,6 @@ import org.mian.gitnex.databinding.ActivityCreateNewUserBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -74,8 +73,6 @@ public class CreateNewUserActivity extends BaseActivity {
private void processCreateNewUser() { private void processCreateNewUser() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = TinyDB.getInstance(appCtx);
String newFullName = fullName.getText().toString().trim(); String newFullName = fullName.getText().toString().trim();
String newUserName = userUserName.getText().toString().trim(); String newUserName = userUserName.getText().toString().trim();
@ -94,13 +91,13 @@ public class CreateNewUserActivity extends BaseActivity {
return; return;
} }
if(!appUtil.checkStrings(newFullName)) { if(!AppUtil.checkStrings(newFullName)) {
Toasty.error(ctx, getString(R.string.userInvalidFullName)); Toasty.error(ctx, getString(R.string.userInvalidFullName));
return; return;
} }
if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) { if(!AppUtil.checkStringsWithAlphaNumeric(newUserName)) {
Toasty.error(ctx, getString(R.string.userInvalidUserName)); Toasty.error(ctx, getString(R.string.userInvalidUserName));
return; return;

View File

@ -94,8 +94,6 @@ public class CreateOrganizationActivity extends BaseActivity {
private void processNewOrganization() { private void processNewOrganization() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = TinyDB.getInstance(appCtx);
String newOrgName = orgName.getText().toString(); String newOrgName = orgName.getText().toString();
String newOrgDesc = orgDesc.getText().toString(); String newOrgDesc = orgDesc.getText().toString();
@ -119,7 +117,7 @@ public class CreateOrganizationActivity extends BaseActivity {
Toasty.error(ctx, getString(R.string.orgNameErrorEmpty)); Toasty.error(ctx, getString(R.string.orgNameErrorEmpty));
} }
else if(!appUtil.checkStrings(newOrgName)) { else if(!AppUtil.checkStrings(newOrgName)) {
Toasty.warning(ctx, getString(R.string.orgNameErrorInvalid)); Toasty.warning(ctx, getString(R.string.orgNameErrorInvalid));
} }

View File

@ -104,7 +104,6 @@ public class CreateRepoActivity extends BaseActivity {
private void processNewRepo() { private void processNewRepo() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
String newRepoName = repoName.getText().toString(); String newRepoName = repoName.getText().toString();
String newRepoDesc = repoDesc.getText().toString(); String newRepoDesc = repoDesc.getText().toString();
@ -129,7 +128,7 @@ public class CreateRepoActivity extends BaseActivity {
Toasty.error(ctx, getString(R.string.repoNameErrorEmpty)); Toasty.error(ctx, getString(R.string.repoNameErrorEmpty));
} }
else if(!appUtil.checkStrings(newRepoName)) { else if(!AppUtil.checkStrings(newRepoName)) {
Toasty.warning(ctx, getString(R.string.repoNameErrorInvalid)); Toasty.warning(ctx, getString(R.string.repoNameErrorInvalid));
} }

View File

@ -224,7 +224,6 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
private void processCreateTeam() { private void processCreateTeam() {
AppUtil appUtil = new AppUtil();
final TinyDB tinyDb = TinyDB.getInstance(appCtx); final TinyDB tinyDb = TinyDB.getInstance(appCtx);
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -248,7 +247,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
return; return;
} }
if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) { if(!AppUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) {
Toasty.warning(ctx, getString(R.string.teamNameError)); Toasty.warning(ctx, getString(R.string.teamNameError));
return; return;
@ -256,7 +255,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if(!newTeamDesc.equals("")) { if(!newTeamDesc.equals("")) {
if(!appUtil.checkStrings(newTeamDesc)) { if(!AppUtil.checkStrings(newTeamDesc)) {
Toasty.warning(ctx, getString(R.string.teamDescError)); Toasty.warning(ctx, getString(R.string.teamDescError));
return; return;

View File

@ -326,7 +326,7 @@ public class DeepLinksActivity extends BaseActivity {
// pull was done from a deleted fork // pull was done from a deleted fork
tinyDB.putString("prIsFork", "true"); tinyDB.putString("prIsFork", "true");
tinyDB.putString("prForkFullName", ctx.getString(R.string.prDeletedFrok)); tinyDB.putString("prForkFullName", ctx.getString(R.string.prDeletedFork));
} }
} }

View File

@ -17,8 +17,6 @@ import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts; import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -68,13 +66,11 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private Boolean pdfNightMode; private Boolean pdfNightMode;
private String singleFileName; private String singleFileName;
private String fileSha; private String fileSha;
private AppUtil appUtil;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appUtil = new AppUtil();
ActivityFileViewBinding activityFileViewBinding = ActivityFileViewBinding.inflate(getLayoutInflater()); ActivityFileViewBinding activityFileViewBinding = ActivityFileViewBinding.inflate(getLayoutInflater());
setContentView(activityFileViewBinding.getRoot()); setContentView(activityFileViewBinding.getRoot());
@ -172,86 +168,94 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
tinyDB.putString("downloadFileName", filename); tinyDB.putString("downloadFileName", filename);
tinyDB.putString("downloadFileContents", response.body().getContent()); tinyDB.putString("downloadFileContents", response.body().getContent());
if(appUtil.imageExtension(fileExtension)) { // file is image boolean unknown = false;
singleFileContentsFrame.setVisibility(View.GONE); switch(AppUtil.getFileType(fileExtension)) {
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
imageData = Base64.decode(response.body().getContent(), Base64.DEFAULT); case IMAGE:
imageView.setImageBitmap(Images.scaleImage(imageData, 1920, 1920)); singleFileContentsFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
imageData = Base64.decode(response.body().getContent(), Base64.DEFAULT);
imageView.setImageBitmap(Images.scaleImage(imageData, 1920));
break;
case TEXT:
imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.VISIBLE);
switch(tinyDB.getInt("fileviewerSourceCodeThemeId")) {
case 1: singleCodeContents.setTheme(Theme.ARDUINO_LIGHT); break;
case 2: singleCodeContents.setTheme(Theme.GITHUB); break;
case 3: singleCodeContents.setTheme(Theme.FAR); break;
case 4: singleCodeContents.setTheme(Theme.IR_BLACK); break;
case 5: singleCodeContents.setTheme(Theme.ANDROID_STUDIO); break;
default: singleCodeContents.setTheme(Theme.MONOKAI_SUBLIME);
}
singleCodeContents.setSource(AppUtil.decodeBase64(response.body().getContent()));
break;
case DOCUMENT:
if(fileExtension.equalsIgnoreCase("pdf")) {
imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.VISIBLE);
pdfNightMode = tinyDB.getBoolean("enablePdfMode");
decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT);
pdfView.fromBytes(decodedPdf)
.enableSwipe(true)
.swipeHorizontal(false)
.enableDoubletap(true)
.defaultPage(0)
.enableAnnotationRendering(false)
.password(null)
.scrollHandle(null)
.enableAntialiasing(true)
.spacing(0)
.autoSpacing(true)
.pageFitPolicy(FitPolicy.WIDTH)
.fitEachPage(true)
.pageSnap(false)
.pageFling(true)
.nightMode(pdfNightMode).load();
}
else {
unknown = true;
}
break;
case UNKNOWN:
default:
unknown = true;
break;
} }
else if(appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode
imageView.setVisibility(View.GONE); if(unknown) { // While the file could still be non-binary,
singleFileContentsFrame.setVisibility(View.GONE); // it's better we don't show it (to prevent any crashes and/or unwanted behavior) and let the user download it instead.
pdfViewFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.VISIBLE);
switch(tinyDB.getInt("fileviewerSourceCodeThemeId")) {
case 1:
singleCodeContents.setTheme(Theme.ARDUINO_LIGHT);
break;
case 2:
singleCodeContents.setTheme(Theme.GITHUB);
break;
case 3:
singleCodeContents.setTheme(Theme.FAR);
break;
case 4:
singleCodeContents.setTheme(Theme.IR_BLACK);
break;
case 5:
singleCodeContents.setTheme(Theme.ANDROID_STUDIO);
break;
default:
singleCodeContents.setTheme(Theme.MONOKAI_SUBLIME);
}
singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent()));
}
else if(appUtil.pdfExtension(fileExtension)) { // file is pdf
imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.VISIBLE);
pdfNightMode = tinyDB.getBoolean("enablePdfMode");
decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT);
pdfView.fromBytes(decodedPdf).enableSwipe(true).swipeHorizontal(false).enableDoubletap(true).defaultPage(0).enableAnnotationRendering(false).password(null).scrollHandle(null).enableAntialiasing(true).spacing(0).autoSpacing(true).pageFitPolicy(FitPolicy.WIDTH).fitEachPage(true).pageSnap(false).pageFling(true).nightMode(pdfNightMode).load();
}
else if(appUtil.excludeFilesInFileViewerExtension(fileExtension)) { // files need to be excluded
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE); pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE); singleFileContentsFrame.setVisibility(View.VISIBLE);
singleFileContents.setText(getResources().getString(R.string.excludeFilesInFileviewer)); singleFileContents.setText(getString(R.string.excludeFilesInFileViewer));
singleFileContents.setGravity(Gravity.CENTER); singleFileContents.setGravity(Gravity.CENTER);
singleFileContents.setTypeface(null, Typeface.BOLD); singleFileContents.setTypeface(null, Typeface.BOLD);
} }
else { // file type not known - plain text view
imageView.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE);
singleFileContents.setText(appUtil.decodeBase64(response.body().getContent()));
}
} }
else { else {
@ -321,7 +325,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
else if(id == R.id.markdown) { else if(id == R.id.markdown) {
new Markdown(ctx, EmojiParser.parseToUnicode(appUtil.decodeBase64(tinyDB.getString("downloadFileContents"))), singleFileContents); new Markdown(ctx, EmojiParser.parseToUnicode(AppUtil.decodeBase64(tinyDB.getString("downloadFileContents"))), singleFileContents);
if(!tinyDB.getBoolean("enableMarkdownInFileView")) { if(!tinyDB.getBoolean("enableMarkdownInFileView")) {
@ -335,7 +339,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
singleCodeContents.setVisibility(View.VISIBLE); singleCodeContents.setVisibility(View.VISIBLE);
singleFileContentsFrame.setVisibility(View.GONE); singleFileContentsFrame.setVisibility(View.GONE);
singleFileContents.setVisibility(View.GONE); singleFileContents.setVisibility(View.GONE);
singleCodeContents.setSource(appUtil.decodeBase64(tinyDB.getString("downloadFileContents"))); singleCodeContents.setSource(AppUtil.decodeBase64(tinyDB.getString("downloadFileContents")));
tinyDB.putBoolean("enableMarkdownInFileView", false); tinyDB.putBoolean("enableMarkdownInFileView", false);
} }
return true; return true;
@ -357,20 +361,15 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
if("deleteFile".equals(text)) { if("deleteFile".equals(text)) {
String fileExtension = FileUtils.getExtension(singleFileName); String fileExtension = FileUtils.getExtension(singleFileName);
String data = appUtil.decodeBase64(tinyDB.getString("downloadFileContents"));
String data = AppUtil.getFileType(fileExtension) == AppUtil.FileType.TEXT ?
AppUtil.decodeBase64(tinyDB.getString("downloadFileContents")) : "";
Intent intent = new Intent(ctx, CreateFileActivity.class); Intent intent = new Intent(ctx, CreateFileActivity.class);
intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_DELETE); intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_DELETE);
intent.putExtra("filePath", singleFileName); intent.putExtra("filePath", singleFileName);
intent.putExtra("fileSha", fileSha); intent.putExtra("fileSha", fileSha);
intent.putExtra("fileContents", data);
if(!appUtil.imageExtension(fileExtension)) {
intent.putExtra("fileContents", data);
}
else {
intent.putExtra("fileContents", "");
}
ctx.startActivity(intent); ctx.startActivity(intent);
} }
@ -378,24 +377,25 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
if("editFile".equals(text)) { if("editFile".equals(text)) {
String fileExtension = FileUtils.getExtension(singleFileName); String fileExtension = FileUtils.getExtension(singleFileName);
String data = appUtil.decodeBase64(tinyDB.getString("downloadFileContents"));
Intent intent = new Intent(ctx, CreateFileActivity.class);
intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_EDIT);
intent.putExtra("filePath", singleFileName);
intent.putExtra("fileSha", fileSha);
if(!appUtil.imageExtension(fileExtension)) { switch(AppUtil.getFileType(fileExtension)) {
intent.putExtra("fileContents", data); case TEXT:
Intent intent = new Intent(ctx, CreateFileActivity.class);
intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_EDIT);
intent.putExtra("filePath", singleFileName);
intent.putExtra("fileSha", fileSha);
intent.putExtra("fileContents", AppUtil.decodeBase64(tinyDB.getString("downloadFileContents")));
ctx.startActivity(intent);
break;
default:
Toasty.error(ctx, getString(R.string.fileTypeCannotBeEdited));
} }
else {
intent.putExtra("fileContents", "");
}
ctx.startActivity(intent);
} }
} }
private void requestFileDownload() { private void requestFileDownload() {
@ -418,11 +418,8 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
} }
ActivityResultLauncher<Intent> fileDownloadActivityResultLauncher = registerForActivityResult( ActivityResultLauncher<Intent> fileDownloadActivityResultLauncher =
new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) { if (result.getResultCode() == Activity.RESULT_OK) {
@ -443,15 +440,14 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
outputStream.close(); outputStream.close();
Toasty.success(ctx, getString(R.string.downloadFileSaved)); Toasty.success(ctx, getString(R.string.downloadFileSaved));
} }
catch(IOException e) { catch(IOException e) {
Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage())); Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage()));
} }
} }
}
}); });
private void initCloseListener() { private void initCloseListener() {

View File

@ -214,7 +214,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
Menu menu = navigationView.getMenu(); Menu menu = navigationView.getMenu();
navNotifications = menu.findItem(R.id.nav_notifications); navNotifications = menu.findItem(R.id.nav_notifications);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigationDrawerOpen, R.string.navigationDrawerClose);
drawer.addDrawerListener(toggle); drawer.addDrawerListener(toggle);
drawer.addDrawerListener(new DrawerLayout.DrawerListener() { drawer.addDrawerListener(new DrawerLayout.DrawerListener() {

View File

@ -54,7 +54,7 @@ public class SettingsFileViewerActivity extends BaseActivity {
AlertDialog.Builder fvtsBuilder = new AlertDialog.Builder(SettingsFileViewerActivity.this); AlertDialog.Builder fvtsBuilder = new AlertDialog.Builder(SettingsFileViewerActivity.this);
fvtsBuilder.setTitle(R.string.fileviewerSourceCodeThemeSelectorDialogTitle); fvtsBuilder.setTitle(R.string.fileViewerSourceCodeThemeSelectorDialogTitle);
fvtsBuilder.setCancelable(fileViewerSourceCodeThemesSelectedChoice != -1); fvtsBuilder.setCancelable(fileViewerSourceCodeThemesSelectedChoice != -1);
fvtsBuilder.setSingleChoiceItems(fileViewerSourceCodeThemesList, fileViewerSourceCodeThemesSelectedChoice, (dialogInterfaceTheme, i) -> { fvtsBuilder.setSingleChoiceItems(fileViewerSourceCodeThemesList, fileViewerSourceCodeThemesSelectedChoice, (dialogInterfaceTheme, i) -> {

View File

@ -113,7 +113,7 @@ public class SettingsGeneralActivity extends BaseActivity {
// home screen // home screen
// link handler // link handler
String[] defaultScreen_ = {getResources().getString(R.string.generalDeepLinkSelectedText), getResources().getString(R.string.navRepos), getResources().getString(R.string.navOrgs), getResources().getString(R.string.pageTitleNotifications), getResources().getString(R.string.navExplore)}; String[] defaultScreen_ = {getResources().getString(R.string.generalDeepLinkSelectedText), getResources().getString(R.string.navRepos), getResources().getString(R.string.navOrg), getResources().getString(R.string.pageTitleNotifications), getResources().getString(R.string.navExplore)};
defaultScreen = new ArrayList<>(Arrays.asList(defaultScreen_)); defaultScreen = new ArrayList<>(Arrays.asList(defaultScreen_));
String[] linksArray = new String[defaultScreen.size()]; String[] linksArray = new String[defaultScreen.size()];
@ -131,7 +131,7 @@ public class SettingsGeneralActivity extends BaseActivity {
} }
else if(defaultLinkHandlerScreenSelectedChoice == 2) { else if(defaultLinkHandlerScreenSelectedChoice == 2) {
viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.navOrgs)); viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.navOrg));
} }
else if(defaultLinkHandlerScreenSelectedChoice == 3) { else if(defaultLinkHandlerScreenSelectedChoice == 3) {

View File

@ -10,7 +10,7 @@ import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding; import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding;
import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.notifications.NotificationsMaster; import org.mian.gitnex.notifications.Notifications;
/** /**
* Template Author M M Arif * Template Author M M Arif
@ -43,7 +43,7 @@ public class SettingsNotificationsActivity extends BaseActivity {
viewBinding.enableNotificationsMode.setOnCheckedChangeListener((buttonView, isChecked) -> { viewBinding.enableNotificationsMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
tinyDB.putBoolean("notificationsEnabled", isChecked); tinyDB.putBoolean("notificationsEnabled", isChecked);
if(!isChecked) NotificationsMaster.fireWorker(ctx); if(!isChecked) Notifications.stopWorker(ctx);
Toasty.info(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
@ -66,8 +66,8 @@ public class SettingsNotificationsActivity extends BaseActivity {
tinyDB.putInt("pollingDelayMinutes", numberPicker.getValue()); tinyDB.putInt("pollingDelayMinutes", numberPicker.getValue());
NotificationsMaster.fireWorker(ctx); Notifications.stopWorker(ctx);
NotificationsMaster.hireWorker(ctx); Notifications.startWorker(ctx);
viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), numberPicker.getValue())); viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), numberPicker.getValue()));
Toasty.info(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));

View File

@ -199,7 +199,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
else { else {
// pull was done from a deleted fork // pull was done from a deleted fork
prIsFork.setText("true"); prIsFork.setText("true");
prForkFullName.setText(context.getString(R.string.prDeletedFrok)); prForkFullName.setText(context.getString(R.string.prDeletedFork));
} }
} }
prCommentsCount.setText(String.valueOf(prModel.getComments())); prCommentsCount.setText(String.valueOf(prModel.getComments()));

View File

@ -0,0 +1,127 @@
package org.mian.gitnex.core;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import org.acra.ACRA;
import org.acra.BuildConfig;
import org.acra.ReportField;
import org.acra.annotation.AcraCore;
import org.acra.annotation.AcraNotification;
import org.acra.config.CoreConfigurationBuilder;
import org.acra.config.LimiterConfigurationBuilder;
import org.acra.config.MailSenderConfigurationBuilder;
import org.acra.data.StringFormat;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.notifications.Notifications;
/**
* @author opyale
*/
@SuppressLint("NonConstantResourceId")
@AcraNotification(resIcon = R.drawable.gitnex_transparent,
resTitle = R.string.crashTitle,
resChannelName = R.string.setCrashReports,
resText = R.string.crashMessage)
@AcraCore(reportContent = { ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, ReportField.STACK_TRACE })
public class MainApplication extends Application {
private Context appCtx;
private TinyDB tinyDB;
@Override
public void onCreate() {
super.onCreate();
appCtx = getApplicationContext();
tinyDB = TinyDB.getInstance(appCtx);
setDefaults();
switch(tinyDB.getInt("customFontId", -1)) {
case 0:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/roboto.ttf");
break;
case 2:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/sourcecodeproregular.ttf");
break;
default:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/manroperegular.ttf");
}
if(tinyDB.getBoolean("crashReportingEnabled")) {
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this);
ACRABuilder.setBuildConfigClass(BuildConfig.class).setReportFormat(StringFormat.KEY_VALUE_LIST);
ACRABuilder.getPluginConfigurationBuilder(MailSenderConfigurationBuilder.class).setReportAsFile(true).setMailTo(getResources().getString(R.string.appEmail)).setSubject(getResources().getString(R.string.crashReportEmailSubject, AppUtil.getAppBuildNo(getApplicationContext()))).setEnabled(true);
ACRABuilder.getPluginConfigurationBuilder(LimiterConfigurationBuilder.class).setEnabled(true);
ACRA.init(this, ACRABuilder);
}
Notifications.startWorker(appCtx);
}
private void setDefaults() {
// enabling counter badges by default
if(tinyDB.getString("enableCounterBadgesInit").isEmpty()) {
tinyDB.putBoolean("enableCounterBadges", true);
tinyDB.putString("enableCounterBadgesInit", "yes");
}
// enable crash reports by default
if(tinyDB.getString("crashReportingEnabledInit").isEmpty()) {
tinyDB.putBoolean("crashReportingEnabled", true);
tinyDB.putString("crashReportingEnabledInit", "yes");
}
// default cache setter
if(tinyDB.getString("cacheSizeStr").isEmpty()) {
tinyDB.putString("cacheSizeStr", getResources().getString(R.string.cacheSizeDataSelectionSelectedText));
}
if(tinyDB.getString("cacheSizeImagesStr").isEmpty()) {
tinyDB.putString("cacheSizeImagesStr", getResources().getString(R.string.cacheSizeImagesSelectionSelectedText));
}
// enable comment drafts by default
if(tinyDB.getString("draftsCommentsDeletionEnabledInit").isEmpty()) {
tinyDB.putBoolean("draftsCommentsDeletionEnabled", true);
tinyDB.putString("draftsCommentsDeletionEnabledInit", "yes");
}
// setting default polling delay
if(tinyDB.getInt("pollingDelayMinutes", 0) <= 0) {
tinyDB.putInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay);
}
}
}

View File

@ -52,7 +52,7 @@ public class OrganizationsFragment extends Fragment {
final SwipeRefreshLayout swipeRefresh = fragmentOrganizationsBinding.pullToRefresh; final SwipeRefreshLayout swipeRefresh = fragmentOrganizationsBinding.pullToRefresh;
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navOrgs)); ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navOrg));
mProgressBar = fragmentOrganizationsBinding.progressBar; mProgressBar = fragmentOrganizationsBinding.progressBar;
noDataOrg = fragmentOrganizationsBinding.noDataOrg; noDataOrg = fragmentOrganizationsBinding.noDataOrg;

View File

@ -18,6 +18,8 @@ import java.text.SimpleDateFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale; import java.util.Locale;
/** /**
@ -26,6 +28,33 @@ import java.util.Locale;
public class AppUtil { public class AppUtil {
public enum FileType { IMAGE, DOCUMENT, TEXT, UNKNOWN }
private static final HashMap<List<String>, FileType> extensions = new HashMap<>();
// AppUtil should not be instantiated.
private AppUtil() {}
static {
extensions.put(Arrays.asList("jpg", "jpeg", "gif", "png", "ico"), FileType.IMAGE);
extensions.put(Arrays.asList("doc", "docx", "ppt", "pptx", "xls", "xlsx", "xlsm", "odt", "ott", "odf", "ods", "ots", "exe", "jar", "odg", "otg", "odp", "otp", "bin", "dmg", "psd", "xcf", "pdf"), FileType.DOCUMENT);
extensions.put(Arrays.asList("txt", "md", "json", "java", "go", "php", "c", "cc", "cpp", "h", "cxx", "cyc", "m", "cs", "bash", "sh", "bsh", "cv", "python", "perl", "pm", "rb", "ruby", "javascript", "coffee", "rc", "rs", "rust", "basic", "clj", "css", "dart", "lisp", "erl", "hs", "lsp", "rkt", "ss", "llvm", "ll", "lua", "matlab", "pascal", "r", "scala", "sql", "latex", "tex", "vb", "vbs", "vhd", "tcl", "wiki.meta", "yaml", "yml", "markdown", "xml", "proto", "regex", "py", "pl", "js", "html", "htm", "volt", "ini", "htaccess", "conf", "gitignore", "gradle", "txt", "properties", "bat", "twig", "cvs", "cmake", "in", "info", "spec", "m4", "am", "dist", "pam", "hx", "ts"), FileType.TEXT);
}
public static FileType getFileType(String extension) {
for(List<String> e : extensions.keySet()) {
if(e.contains(extension)) {
return extensions.get(e);
}
}
return FileType.UNKNOWN;
}
public static boolean hasNetworkConnection(Context context) { public static boolean hasNetworkConnection(Context context) {
return NetworkStatusObserver.get(context).hasNetworkConnection(); return NetworkStatusObserver.get(context).hasNetworkConnection();
@ -57,19 +86,19 @@ public class AppUtil {
return context.getPackageName().equals("org.mian.gitnex.pro"); return context.getPackageName().equals("org.mian.gitnex.pro");
} }
public Boolean checkStringsWithAlphaNumeric(String str) { // [a-zA-Z0-9] public static Boolean checkStringsWithAlphaNumeric(String str) { // [a-zA-Z0-9]
return str.matches("^[\\w]+$"); return str.matches("^[\\w]+$");
} }
public Boolean checkStrings(String str) { // [a-zA-Z0-9-_. ] public static Boolean checkStrings(String str) { // [a-zA-Z0-9-_. ]
return str.matches("^[\\w .-]+$"); return str.matches("^[\\w .-]+$");
} }
public Boolean checkStringsWithAlphaNumericDashDotUnderscore(String str) { // [a-zA-Z0-9-_] public static Boolean checkStringsWithAlphaNumericDashDotUnderscore(String str) { // [a-zA-Z0-9-_]
return str.matches("^[\\w.-]+$"); return str.matches("^[\\w.-]+$");
} }
public Boolean checkStringsWithDash(String str) { // [a-zA-Z0-9-_. ] public static Boolean checkStringsWithDash(String str) { // [a-zA-Z0-9-_. ]
return str.matches("^[\\w-]+$"); return str.matches("^[\\w-]+$");
} }
@ -168,7 +197,7 @@ public class AppUtil {
} }
public String encodeBase64(String str) { public static String encodeBase64(String str) {
String base64Str = str; String base64Str = str;
if(!str.equals("")) { if(!str.equals("")) {
@ -180,7 +209,7 @@ public class AppUtil {
} }
public String decodeBase64(String str) { public static String decodeBase64(String str) {
String base64Str = str; String base64Str = str;
if(!str.equals("")) { if(!str.equals("")) {
@ -192,39 +221,7 @@ public class AppUtil {
} }
public Boolean sourceCodeExtension(String ext) { public static String getLastCharactersOfWord(String str, int count) {
String[] extValues = new String[]{"md", "json", "java", "go", "php", "c", "cc", "cpp", "h", "cxx", "cyc", "m", "cs", "bash", "sh", "bsh", "cv", "python", "perl", "pm", "rb", "ruby", "javascript", "coffee", "rc", "rs", "rust", "basic", "clj", "css", "dart", "lisp", "erl", "hs", "lsp", "rkt", "ss", "llvm", "ll", "lua", "matlab", "pascal", "r", "scala", "sql", "latex", "tex", "vb", "vbs", "vhd", "tcl", "wiki.meta", "yaml", "yml", "markdown", "xml", "proto", "regex", "py", "pl", "js", "html", "htm", "volt", "ini", "htaccess", "conf", "gitignore", "gradle", "txt", "properties", "bat", "twig", "cvs", "cmake", "in", "info", "spec", "m4", "am", "dist", "pam", "hx", "ts"};
return Arrays.asList(extValues).contains(ext);
}
public Boolean pdfExtension(String ext) {
String[] extValues = new String[]{"pdf"};
return Arrays.asList(extValues).contains(ext);
}
public Boolean imageExtension(String ext) {
String[] extValues = new String[]{"jpg", "jpeg", "gif", "png", "ico"};
return Arrays.asList(extValues).contains(ext);
}
public Boolean excludeFilesInFileViewerExtension(String ext) {
String[] extValues = new String[]{"doc", "docx", "ppt", "pptx", "xls", "xlsx", "xlsm", "odt", "ott", "odf", "ods", "ots", "exe", "jar", "odg", "otg", "odp", "otp", "bin", "dmg", "psd", "xcf"};
return Arrays.asList(extValues).contains(ext);
}
public String getLastCharactersOfWord(String str, int count) {
return str.substring(str.length() - count); return str.substring(str.length() - count);

View File

@ -9,24 +9,34 @@ import android.graphics.BitmapFactory;
public class Images { public class Images {
public static Bitmap scaleImage(byte[] imageData, int maxSizeWidth, int maxSizeScaledWidth) { public static Bitmap scaleImage(byte[] imageData, int sizeLimit) {
Bitmap scaledImage; Bitmap original = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
Bitmap image = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
int orgWidth = image.getWidth();
int orgHeight = image.getHeight();
if(orgWidth > maxSizeWidth) { if(original.getHeight() > sizeLimit && original.getWidth() <= original.getHeight()) {
double reductionPercentage = (double) sizeLimit / original.getHeight();
Bitmap scaled = Bitmap.createScaledBitmap(original, (int) (reductionPercentage * original.getWidth()), sizeLimit, false);
original.recycle();
return scaled;
int aspectRatio = orgWidth / orgHeight;
int scaledHeight = maxSizeScaledWidth * aspectRatio;
scaledImage = Bitmap.createScaledBitmap(image, maxSizeScaledWidth, scaledHeight, false);
} }
else { else if(original.getWidth() > sizeLimit && original.getHeight() < original.getWidth()) {
double reductionPercentage = (double) sizeLimit / original.getWidth();
Bitmap scaled = Bitmap.createScaledBitmap(original, sizeLimit, (int) (reductionPercentage * original.getHeight()), false);
original.recycle();
return scaled;
scaledImage = Bitmap.createScaledBitmap(image, orgWidth, orgHeight, false);
} }
return scaledImage; // Image size does not exceed bounds.
return original;
} }
} }

View File

@ -19,15 +19,15 @@ public class MemorizingActivity extends Activity {
Intent intent = getIntent(); Intent intent = getIntent();
int decisionId = intent.getIntExtra("DECISION_INTENT_ID", MTMDecision.DECISION_INVALID); int decisionId = intent.getIntExtra("DECISION_INTENT_ID", MTMDecision.DECISION_INVALID);
int titleId = intent.getIntExtra("DECISION_TITLE_ID", R.string.mtm_accept_cert); int titleId = intent.getIntExtra("DECISION_TITLE_ID", R.string.mtmAcceptCert);
String cert = intent.getStringExtra("DECISION_INTENT_CERT"); String cert = intent.getStringExtra("DECISION_INTENT_CERT");
AlertDialog.Builder builder = new AlertDialog.Builder(MemorizingActivity.this); AlertDialog.Builder builder = new AlertDialog.Builder(MemorizingActivity.this);
builder.setTitle(titleId); builder.setTitle(titleId);
builder.setMessage(cert); builder.setMessage(cert);
builder.setPositiveButton(R.string.mtm_decision_always, (dialog, which) -> onSendResult(decisionId, MTMDecision.DECISION_ALWAYS)); builder.setPositiveButton(R.string.mtmDecisionAlways, (dialog, which) -> onSendResult(decisionId, MTMDecision.DECISION_ALWAYS));
builder.setNeutralButton(R.string.mtm_decision_abort, (dialog, which) -> onSendResult(decisionId, MTMDecision.DECISION_ABORT)); builder.setNeutralButton(R.string.mtmDecisionAbort, (dialog, which) -> onSendResult(decisionId, MTMDecision.DECISION_ABORT));
builder.setOnCancelListener(dialog -> onSendResult(decisionId, MTMDecision.DECISION_ABORT)); builder.setOnCancelListener(dialog -> onSendResult(decisionId, MTMDecision.DECISION_ABORT));
builder.create().show(); builder.create().show();

View File

@ -449,10 +449,10 @@ public class MemorizingTrustManager implements X509TrustManager {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
if(isPathException(e)) { if(isPathException(e)) {
stringBuilder.append(context.getString(R.string.mtm_trust_anchor)); stringBuilder.append(context.getString(R.string.mtmTrustAnchor));
} }
else if(isExpiredException(e)) { else if(isExpiredException(e)) {
stringBuilder.append(context.getString(R.string.mtm_cert_expired)); stringBuilder.append(context.getString(R.string.mtmCertExpired));
} }
else { else {
// get to the cause // get to the cause
@ -464,9 +464,9 @@ public class MemorizingTrustManager implements X509TrustManager {
} }
stringBuilder.append("\n\n"); stringBuilder.append("\n\n");
stringBuilder.append(context.getString(R.string.mtm_connect_anyway)); stringBuilder.append(context.getString(R.string.mtmConnectAnyway));
stringBuilder.append("\n\n"); stringBuilder.append("\n\n");
stringBuilder.append(context.getString(R.string.mtm_cert_details)); stringBuilder.append(context.getString(R.string.mtmCertDetails));
for(X509Certificate c : chain) { for(X509Certificate c : chain) {
certDetails(stringBuilder, c); certDetails(stringBuilder, c);
@ -479,7 +479,7 @@ public class MemorizingTrustManager implements X509TrustManager {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(context.getString(R.string.mtm_hostname_mismatch, hostname)); stringBuilder.append(context.getString(R.string.mtmHostnameMismatch, hostname));
stringBuilder.append("\n\n"); stringBuilder.append("\n\n");
try { try {
@ -510,9 +510,9 @@ public class MemorizingTrustManager implements X509TrustManager {
} }
stringBuilder.append("\n"); stringBuilder.append("\n");
stringBuilder.append(context.getString(R.string.mtm_connect_anyway)); stringBuilder.append(context.getString(R.string.mtmConnectAnyway));
stringBuilder.append("\n\n"); stringBuilder.append("\n\n");
stringBuilder.append(context.getString(R.string.mtm_cert_details)); stringBuilder.append(context.getString(R.string.mtmCertDetails));
certDetails(stringBuilder, cert); certDetails(stringBuilder, cert);
return stringBuilder.toString(); return stringBuilder.toString();
} }
@ -544,7 +544,7 @@ public class MemorizingTrustManager implements X509TrustManager {
private void startActivityNotification(Intent intent, int decisionId, String certName) { private void startActivityNotification(Intent intent, int decisionId, String certName) {
final PendingIntent call = PendingIntent.getActivity(context, 0, intent, 0); final PendingIntent call = PendingIntent.getActivity(context, 0, intent, 0);
final String mtmNotification = context.getString(R.string.mtm_notification); final String mtmNotification = context.getString(R.string.mtmNotification);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "ssl") NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "ssl")
.setSmallIcon(android.R.drawable.ic_lock_lock) .setSmallIcon(android.R.drawable.ic_lock_lock)
@ -596,7 +596,7 @@ public class MemorizingTrustManager implements X509TrustManager {
private void interactCert(final X509Certificate[] chain, String authType, CertificateException cause) throws CertificateException { private void interactCert(final X509Certificate[] chain, String authType, CertificateException cause) throws CertificateException {
if(interact(certChainMessage(chain, cause), R.string.mtm_accept_cert) == MTMDecision.DECISION_ALWAYS) { if(interact(certChainMessage(chain, cause), R.string.mtmAcceptCert) == MTMDecision.DECISION_ALWAYS) {
storeCert(chain[0]); // only store the server cert, not the whole chain storeCert(chain[0]); // only store the server cert, not the whole chain
} else { } else {
throw (cause); throw (cause);
@ -605,7 +605,7 @@ public class MemorizingTrustManager implements X509TrustManager {
private boolean interactHostname(X509Certificate cert, String hostname) { private boolean interactHostname(X509Certificate cert, String hostname) {
if(interact(hostNameMessage(cert, hostname), R.string.mtm_accept_server_name) == MTMDecision.DECISION_ALWAYS) { if(interact(hostNameMessage(cert, hostname), R.string.mtmAcceptServerName) == MTMDecision.DECISION_ALWAYS) {
storeCert(hostname, cert); storeCert(hostname, cert);
return true; return true;
} }

View File

@ -16,7 +16,7 @@ import java.util.concurrent.TimeUnit;
* Author opyale * Author opyale
*/ */
public class NotificationsMaster { public class Notifications {
private static int notificationsSupported = -1; private static int notificationsSupported = -1;
@ -30,12 +30,12 @@ public class NotificationsMaster {
} }
} }
public static void fireWorker(Context context) { public static void stopWorker(Context context) {
WorkManager.getInstance(context).cancelAllWorkByTag(context.getPackageName()); WorkManager.getInstance(context).cancelAllWorkByTag(context.getPackageName());
} }
public static void hireWorker(Context context) { public static void startWorker(Context context) {
TinyDB tinyDB = TinyDB.getInstance(context); TinyDB tinyDB = TinyDB.getInstance(context);

View File

@ -36,8 +36,8 @@ public class NotificationsWorker extends Worker {
private static final int MAXIMUM_NOTIFICATIONS = 100; private static final int MAXIMUM_NOTIFICATIONS = 100;
private static final long[] VIBRATION_PATTERN = new long[]{ 1000, 1000 }; private static final long[] VIBRATION_PATTERN = new long[]{ 1000, 1000 };
private Context context; private final Context context;
private TinyDB tinyDB; private final TinyDB tinyDB;
public NotificationsWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { public NotificationsWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
@ -157,7 +157,7 @@ public class NotificationsWorker extends Worker {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName(), context.getString(R.string.app_name), NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName(), context.getString(R.string.appName),
NotificationManager.IMPORTANCE_DEFAULT); NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setDescription(context.getString(R.string.notificationChannelDescription)); notificationChannel.setDescription(context.getString(R.string.notificationChannelDescription));

View File

@ -94,7 +94,7 @@
android:id="@+id/organization" android:id="@+id/organization"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="60dp"
android:text="@string/navOrgs" android:text="@string/navOrg"
android:textColor="@color/btnTextColor" android:textColor="@color/btnTextColor"
android:textSize="16sp" android:textSize="16sp"
android:layout_marginTop="8dp" /> android:layout_marginTop="8dp" />

View File

@ -22,7 +22,7 @@
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:layout_marginBottom="20dp" android:layout_marginBottom="20dp"
android:baselineAligned="false" android:baselineAligned="false"
android:contentDescription="@string/app_name" android:contentDescription="@string/appName"
android:src="@mipmap/app_logo" /> android:src="@mipmap/app_logo" />
<TextView <TextView

View File

@ -48,7 +48,7 @@
android:id="@+id/tabItemInfo" android:id="@+id/tabItemInfo"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tab_text_info" /> android:text="@string/tabTextInfo" />
<com.google.android.material.tabs.TabItem <com.google.android.material.tabs.TabItem
android:id="@+id/tabItem_repos" android:id="@+id/tabItem_repos"
@ -60,7 +60,7 @@
android:id="@+id/tabItem_labels" android:id="@+id/tabItem_labels"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tab_text_labels" /> android:text="@string/tabTextLabels" />
<com.google.android.material.tabs.TabItem <com.google.android.material.tabs.TabItem
android:id="@+id/tabItem_teams" android:id="@+id/tabItem_teams"

View File

@ -48,13 +48,13 @@
android:id="@+id/tab_item_info" android:id="@+id/tab_item_info"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tab_text_info" /> android:text="@string/tabTextInfo" />
<com.google.android.material.tabs.TabItem <com.google.android.material.tabs.TabItem
android:id="@+id/tab_item_files" android:id="@+id/tab_item_files"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tab_text_files" /> android:text="@string/tabTextFiles" />
<com.google.android.material.tabs.TabItem <com.google.android.material.tabs.TabItem
android:id="@+id/tab_item_issues" android:id="@+id/tab_item_issues"
@ -72,25 +72,25 @@
android:id="@+id/tab_item_releases" android:id="@+id/tab_item_releases"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tab_text_releases" /> android:text="@string/tabTextReleases" />
<com.google.android.material.tabs.TabItem <com.google.android.material.tabs.TabItem
android:id="@+id/tab_item_ml" android:id="@+id/tab_item_ml"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tab_text_ml" /> android:text="@string/tabTextMl" />
<com.google.android.material.tabs.TabItem <com.google.android.material.tabs.TabItem
android:id="@+id/tab_item_labels" android:id="@+id/tab_item_labels"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tab_text_labels" /> android:text="@string/tabTextLabels" />
<com.google.android.material.tabs.TabItem <com.google.android.material.tabs.TabItem
android:id="@+id/tab_item_collaborators" android:id="@+id/tab_item_collaborators"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tab_text_collaborators" /> android:text="@string/tabTextCollaborators" />
</com.google.android.material.tabs.TabLayout> </com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View File

@ -59,7 +59,7 @@
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:layout_marginStart="44dp" android:layout_marginStart="44dp"
android:layout_marginEnd="24dp" android:layout_marginEnd="24dp"
android:text="@string/settingsFileviewerSourceCodeHeaderText" android:text="@string/settingsFileViewerSourceCodeHeaderText"
android:textColor="?attr/primaryTextColor"/> android:textColor="?attr/primaryTextColor"/>
<TextView <TextView
@ -69,7 +69,7 @@
android:textSize="14sp" android:textSize="14sp"
android:layout_marginStart="44dp" android:layout_marginStart="44dp"
android:layout_marginEnd="24dp" android:layout_marginEnd="24dp"
android:text="@string/settingsFileviewerSourceCodeSelectedText" android:text="@string/settingsFileViewerSourceCodeSelectedText"
android:textColor="?attr/selectedTextColor"/> android:textColor="?attr/selectedTextColor"/>
</LinearLayout> </LinearLayout>

View File

@ -11,7 +11,7 @@
android:gravity="center" android:gravity="center"
android:textSize="16sp" android:textSize="16sp"
app:textAllCaps="true" app:textAllCaps="true"
android:text="@string/tab_text_releases" android:text="@string/tabTextReleases"
android:textColor="@color/lightGray" /> android:textColor="@color/lightGray" />
<TextView <TextView

View File

@ -24,14 +24,14 @@
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:baselineAligned="false" android:baselineAligned="false"
android:contentDescription="@string/app_name" android:contentDescription="@string/appName"
android:src="@mipmap/app_logo" /> android:src="@mipmap/app_logo" />
<TextView <TextView
android:id="@+id/appName" android:id="@+id/appName"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/app_name" android:text="@string/appName"
android:textIsSelectable="true" android:textIsSelectable="true"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:textSize="24sp" android:textSize="24sp"

View File

@ -11,7 +11,7 @@
android:id="@+id/collaboratorAvatar" android:id="@+id/collaboratorAvatar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="110dp" android:layout_height="110dp"
android:contentDescription="@string/tab_text_collaborators" android:contentDescription="@string/tabTextCollaborators"
android:src="@drawable/ic_person" /> android:src="@drawable/ic_person" />
<TextView <TextView
@ -20,7 +20,7 @@
android:layout_height="60dp" android:layout_height="60dp"
android:gravity="top|center_horizontal" android:gravity="top|center_horizontal"
android:layout_marginTop="1dp" android:layout_marginTop="1dp"
android:text="@string/tab_text_collaborators" android:text="@string/tabTextCollaborators"
android:textSize="14sp" android:textSize="14sp"
android:textColor="?attr/primaryTextColor" /> android:textColor="?attr/primaryTextColor" />

View File

@ -107,7 +107,7 @@
android:id="@+id/repoFullName" android:id="@+id/repoFullName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/repoFullname" android:text="@string/repoFullName"
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" /> android:textStyle="bold" />

View File

@ -17,7 +17,7 @@
<item android:id="@+id/nav_organizations" <item android:id="@+id/nav_organizations"
android:icon="@drawable/ic_organization" android:icon="@drawable/ic_organization"
android:title="@string/navOrgs" /> android:title="@string/navOrg" />
<item android:id="@+id/nav_repositories" <item android:id="@+id/nav_repositories"
android:icon="@drawable/ic_repo" android:icon="@drawable/ic_repo"

View File

@ -1,6 +1,6 @@
<resources> <resources>
<string name="app_name" translatable="false">GitNex</string> <string name="appName" translatable="false">GitNex</string>
<string name="appEmail" translatable="false">gitnex@swatian.com</string> <string name="appEmail" translatable="false">gitnex@swatian.com</string>
<string name="appRepo" translatable="false">Source code</string> <string name="appRepo" translatable="false">Source code</string>
<string name="appRepoLink" translatable="false">https://codeberg.org/gitnex/GitNex</string> <string name="appRepoLink" translatable="false">https://codeberg.org/gitnex/GitNex</string>
@ -25,7 +25,7 @@
<string name="navRepos">Repositories</string> <string name="navRepos">Repositories</string>
<string name="navProfile">Profile</string> <string name="navProfile">Profile</string>
<string name="navSettings">Settings</string> <string name="navSettings">Settings</string>
<string name="navOrgs">Organizations</string> <string name="navOrg">Organizations</string>
<string name="navAbout">About</string> <string name="navAbout">About</string>
<string name="navRate">Rate GitNex</string> <string name="navRate">Rate GitNex</string>
<string name="navLogout">Logout</string> <string name="navLogout">Logout</string>
@ -62,7 +62,7 @@
<!-- page titles --> <!-- page titles -->
<string name="repoName">Demo repo</string> <string name="repoName">Demo repo</string>
<string name="repoFullname">Repo with ORG</string> <string name="repoFullName">Repo with ORG</string>
<string name="repoDescription">Demo description</string> <string name="repoDescription">Demo description</string>
<string name="noData">No repositories found</string> <string name="noData">No repositories found</string>
@ -87,8 +87,8 @@
<string name="passWord">Password</string> <string name="passWord">Password</string>
<string name="btnLogin">LOGIN</string> <string name="btnLogin">LOGIN</string>
<string name="instanceUrl">Instance URL</string> <string name="instanceUrl">Instance URL</string>
<string name="navigation_drawer_open">Open Navigation Drawer</string> <string name="navigationDrawerOpen">Open Navigation Drawer</string>
<string name="navigation_drawer_close">Close Navigation Drawer</string> <string name="navigationDrawerClose">Close Navigation Drawer</string>
<string name="logo">Login to Gitea</string> <string name="logo">Login to Gitea</string>
<string name="protocol">Protocol</string> <string name="protocol">Protocol</string>
<string name="urlInfoTooltip">1- Choose the correct protocol(https or http). \n2- Enter Gitea 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="urlInfoTooltip">1- Choose the correct protocol(https or http). \n2- Enter Gitea 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>
@ -136,14 +136,14 @@
<string name="removeContent">Remove</string> <string name="removeContent">Remove</string>
<string name="genericApiStatusError">Instance has returned an error. Code\u0020</string> <string name="genericApiStatusError">Instance has returned an error. Code\u0020</string>
<string name="title_activity_repo_detail">RepoDetailActivity</string> <string name="titleActivityRepoDetail">RepoDetailActivity</string>
<string name="tab_text_info">Details</string> <string name="tabTextInfo">Details</string>
<string name="tab_text_files">Files</string> <string name="tabTextFiles">Files</string>
<string name="tab_text_ml">Milestones</string> <string name="tabTextMl">Milestones</string>
<string name="tab_text_releases">Releases</string> <string name="tabTextReleases">Releases</string>
<string name="tab_text_branches">Branches</string> <string name="tabTextBranches">Branches</string>
<string name="tab_text_labels">Labels</string> <string name="tabTextLabels">Labels</string>
<string name="tab_text_collaborators">Collaborators</string> <string name="tabTextCollaborators">Collaborators</string>
<string name="tabPullRequests">Pull Requests</string> <string name="tabPullRequests">Pull Requests</string>
<string name="noDataIssueTab">No issues found</string> <string name="noDataIssueTab">No issues found</string>
@ -252,9 +252,9 @@
<string name="settingsPdfModeHeaderText">PDF Night Mode</string> <string name="settingsPdfModeHeaderText">PDF Night Mode</string>
<string name="fileViewerHeader">File Viewer</string> <string name="fileViewerHeader">File Viewer</string>
<string name="settingsCounterBadges">Counter Badges</string> <string name="settingsCounterBadges">Counter Badges</string>
<string name="settingsFileviewerSourceCodeHeaderText">Source Code Theme</string> <string name="settingsFileViewerSourceCodeHeaderText">Source Code Theme</string>
<string name="settingsFileviewerSourceCodeSelectedText" translatable="false">Sublime</string> <string name="settingsFileViewerSourceCodeSelectedText" translatable="false">Sublime</string>
<string name="fileviewerSourceCodeThemeSelectorDialogTitle">Select Source Code Theme</string> <string name="fileViewerSourceCodeThemeSelectorDialogTitle">Select Source Code Theme</string>
<string name="cacheSizeDataDialogHeader">Data Cache Size</string> <string name="cacheSizeDataDialogHeader">Data Cache Size</string>
<string name="cacheSizeDataSelectionHeaderText">Data Cache Size</string> <string name="cacheSizeDataSelectionHeaderText">Data Cache Size</string>
<string name="cacheSizeDataSelectionSelectedText" translatable="false">50 MB</string> <string name="cacheSizeDataSelectionSelectedText" translatable="false">50 MB</string>
@ -309,7 +309,7 @@
<string name="labelDeleteNegativeButton">Cancel</string> <string name="labelDeleteNegativeButton">Cancel</string>
<!-- org tabbed layout str --> <!-- org tabbed layout str -->
<string name="title_activity_org_detail">OrgDetailActivity</string> <string name="titleActivityOrgDetail">OrgDetailActivity</string>
<string name="orgTabRepos">Repositories</string> <string name="orgTabRepos">Repositories</string>
<string name="orgTabTeams">Teams</string> <string name="orgTabTeams">Teams</string>
<string name="orgTabMembers">Members</string> <string name="orgTabMembers">Members</string>
@ -397,15 +397,6 @@
<string name="singleIssueUnSubscribe">Unsubscribe</string> <string name="singleIssueUnSubscribe">Unsubscribe</string>
<!-- single issue section --> <!-- single issue section -->
<!-- multi select dialog -->
<string name="select_entry">Select Entries</string>
<string name="please_select_atleast">Please select at least </string>
<string name="you_can_only_select_upto">You can only select up to </string>
<string name="option"> option</string>
<string name="options"> options</string>
<string name="select_all">Select all</string>
<!-- multi select dialog -->
<string name="repoMetaData">Repository Meta</string> <string name="repoMetaData">Repository Meta</string>
<!-- admin --> <!-- admin -->
@ -496,7 +487,7 @@
<string name="noDataFilesTab">No files found</string> <string name="noDataFilesTab">No files found</string>
<string name="filesGenericError">Sorry this file cannot be viewed as API returned an error</string> <string name="filesGenericError">Sorry this file cannot be viewed as API returned an error</string>
<string name="colonDivider" translatable="false">\u0020:\u0020</string> <string name="colonDivider" translatable="false">\u0020:\u0020</string>
<string name="fileTypeCannotBeEdited">Files of this type cannot be edited</string>
<string name="notSupported">Not supported</string> <string name="notSupported">Not supported</string>
<!-- generic copy --> <!-- generic copy -->
@ -556,7 +547,7 @@
<string name="unauthorizedApiError">Instance has returned an error - Unauthorized. Check your credentials and try again</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="loginTokenError">Token is required</string>
<string name="prDeletedFrok">Deleted Fork</string> <string name="prDeletedFork">Deleted Fork</string>
<string name="noDataPullRequests">No pull requests found</string> <string name="noDataPullRequests">No pull requests found</string>
<string name="prCreator">Creator :\u0020</string> <string name="prCreator">Creator :\u0020</string>
<string name="editPrText">Edit Pull Request</string> <string name="editPrText">Edit Pull Request</string>
@ -586,7 +577,7 @@
<string name="downloadFile">Download This File</string> <string name="downloadFile">Download This File</string>
<string name="waitLoadingDownloadFile">Please wait for the file to load to memory</string> <string name="waitLoadingDownloadFile">Please wait for the file to load to memory</string>
<string name="downloadFileSaved">File saved successfully</string> <string name="downloadFileSaved">File saved successfully</string>
<string name="excludeFilesInFileviewer">This file type is not supported in file viewer. Download it instead from the three dotted menu?</string> <string name="excludeFilesInFileViewer">This file type is not supported in file viewer. Download it instead from the three dotted menu?</string>
<string name="deleteFile">Delete This File</string> <string name="deleteFile">Delete This File</string>
<string name="editFile">Edit This File</string> <string name="editFile">Edit This File</string>
<string name="deleteFileText">Delete %1$s</string> <string name="deleteFileText">Delete %1$s</string>
@ -605,23 +596,23 @@
<string name="changelogTitle" translatable="false">Changelog</string> <string name="changelogTitle" translatable="false">Changelog</string>
<!-- Memorizing Trust Manager --> <!-- Memorizing Trust Manager -->
<string name="mtm_notification">Certificate Verification</string> <string name="mtmNotification">Certificate Verification</string>
<string name="mtm_accept_cert">Accept Unknown Certificate?</string> <string name="mtmAcceptCert">Accept Unknown Certificate?</string>
<string name="mtm_trust_anchor">The server certificate is not signed by a known Certificate Authority</string> <string name="mtmTrustAnchor">The server certificate is not signed by a known Certificate Authority</string>
<string name="mtm_cert_expired">The server certificate is expired.</string> <string name="mtmCertExpired">The server certificate is expired.</string>
<string name="mtm_accept_server_name">Accept Mismatching Server Name?</string> <string name="mtmAcceptServerName">Accept Mismatching Server Name?</string>
<string name="mtm_hostname_mismatch">Server could not authenticate as \&quot;%s\&quot;. The certificate is only valid for:</string> <string name="mtmHostnameMismatch">Server could not authenticate as \&quot;%s\&quot;. The certificate is only valid for:</string>
<string name="mtm_connect_anyway">Do you want to connect anyway?</string> <string name="mtmConnectAnyway">Do you want to connect anyway?</string>
<string name="mtm_cert_details">Certificate details:</string> <string name="mtmCertDetails">Certificate details:</string>
<string name="mtm_decision_always">Trust</string> <string name="mtmDecisionAlways">Trust</string>
<string name="mtm_decision_abort">Abort</string> <string name="mtmDecisionAbort">Abort</string>
<string name="subscribedSuccessfully">Subscribed successfully</string> <string name="subscribedSuccessfully">Subscribed successfully</string>
<string name="alreadySubscribed">You have already subscribed</string> <string name="alreadySubscribed">You have already subscribed</string>
<string name="subscriptionError">Subscription failed</string> <string name="subscriptionError">Subscription failed</string>
<string name="unsubscribedSuccessfully">Unsubscribed successfully</string> <string name="unsubscribedSuccessfully">Unsubscribed successfully</string>
<string name="alreadyUnsubscribed">You have already Unsubscribed</string> <string name="alreadyUnsubscribed">You have already Unsubscribed</string>
<string name="unsubscriptionError">Un-Subscription failed</string> <string name="unSubscriptionError">Un-Subscription failed</string>
<string name="closeMilestone">Close Milestone</string> <string name="closeMilestone">Close Milestone</string>
<string name="openMilestone">Open Milestone</string> <string name="openMilestone">Open Milestone</string>
@ -741,4 +732,5 @@
<string name="codeBlockGreyOnBlack">Grey on Black</string> <string name="codeBlockGreyOnBlack">Grey on Black</string>
<string name="codeBlockWhiteOnGrey">White on Grey</string> <string name="codeBlockWhiteOnGrey">White on Grey</string>
<string name="codeBlockDarkOnWhite">Dark on White</string> <string name="codeBlockDarkOnWhite">Dark on White</string>
</resources> </resources>