mirror of
https://codeberg.org/gitnex/GitNex.git
synced 2024-12-16 15:48:13 +08:00
Improve file type handling. (#841)
Removing file size selection dialog in favor of hardcoded value. Adding warning to file size picker and minor improvements. Bump dependencies and gradle Merge branch 'master' of https://codeberg.org/gitnex/GitNex into improve-filetype-recognition Improving credits, adding symlink and submodule icons to FilesAdapter and removing unused libraries. Minor improvements and bug fixes. Add true progress indication routine for copying streams. Merge branch 'master' of https://codeberg.org/gitnex/GitNex into improve-filetype-recognition Performance and memory usage improvements Notification improvements Renaming StaticGlobalVariables to Constants Overall improvements and fixes. Merge branch 'master' of https://codeberg.org/gitnex/GitNex into improve-filetype-recognition Add additional image formats. Adding audio and video categories. Merge branch 'master' of https://codeberg.org/gitnex/GitNex into improve-filetype-recognition Improve file type handling. Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/841 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:
parent
ef3108db14
commit
98cf1a1976
45
README.md
45
README.md
@ -69,26 +69,31 @@ We use [Crowdin](https://crowdin.com/project/gitnex) for translation. If your la
|
||||
Thanks to all the open source libraries, contributors and donators.
|
||||
|
||||
#### Open source libraries
|
||||
- Retrofit
|
||||
- Gson
|
||||
- Okhttp
|
||||
- Picasso
|
||||
- Markwon
|
||||
- Prism4j
|
||||
- Prettytime
|
||||
- Amulyakhare/textdrawable
|
||||
- Vdurmont/emoji-java
|
||||
- Pes/materialcolorpicker
|
||||
- HamidrezaAmz/BreadcrumbsView
|
||||
- Chrisbanes/PhotoView
|
||||
- Pddstudio/highlightjs-android
|
||||
- Apache/commons-io
|
||||
- Caverock/androidsvg
|
||||
- Droidsonroids.gif/android-gif-drawable
|
||||
- Barteksc/androidPdfViewer
|
||||
- Ge0rg/memorizingTrustManager
|
||||
- Dimezis/blurView
|
||||
- Mikaelhg/urlbuilder
|
||||
- [square/retrofit](https://github.com/square/retrofit)
|
||||
- [google/gson](https://github.com/google/gson)
|
||||
- [square/okhttp](https://github.com/square/okhttp)
|
||||
- [square/picasso](https://github.com/square/picasso)
|
||||
- [wasabeef/picasso-transformations](https://github.com/wasabeef/picasso-transformations)
|
||||
- [cats-oss/android-gpuimage](https://github.com/cats-oss/android-gpuimage)
|
||||
- [noties/Markwon](https://github.com/noties/Markwon)
|
||||
- [noties/Prism4j](https://github.com/noties/Prism4j)
|
||||
- [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime)
|
||||
- [amulyakhare/TextDrawable](https://github.com/amulyakhare/TextDrawable)
|
||||
- [vdurmont/emoji-java](https://github.com/vdurmont/emoji-java)
|
||||
- [Pes8/android-material-color-picker-dialog](https://github.com/Pes8/android-material-color-picker-dialog)
|
||||
- [HamidrezaAmz/BreadcrumbsView](https://github.com/HamidrezaAmz/BreadcrumbsView)
|
||||
- [Baseflow/PhotoView](https://github.com/Baseflow/PhotoView)
|
||||
- [PDDStudio/highlightjs-android](https://github.com/PDDStudio/highlightjs-android)
|
||||
- [apache/commons](https://github.com/apache/commons-io)
|
||||
- [barteksc/AndroidPdfViewer](https://github.com/barteksc/AndroidPdfViewer)
|
||||
- [ge0rg/MemorizingTrustManager](https://github.com/ge0rg/MemorizingTrustManager)
|
||||
- [mikaelhg/urlbuilder](https://github.com/mikaelhg/urlbuilder)
|
||||
- [ACRA/acra](https://github.com/ACRA/acra)
|
||||
|
||||
#### Icon sets
|
||||
- [feathericons/feather](https://github.com/feathericons/feather)
|
||||
- [primer/octicons](https://github.com/primer/octicons)
|
||||
- [google/material-design-icons](https://github.com/google/material-design-icons)
|
||||
|
||||
[Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif)
|
||||
|
||||
|
@ -30,7 +30,7 @@ android {
|
||||
release {
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
lintOptions {
|
||||
@ -55,7 +55,7 @@ configurations {
|
||||
|
||||
dependencies {
|
||||
def lifecycle_version = '2.3.0'
|
||||
def markwon_version = '4.6.1'
|
||||
def markwon_version = '4.6.2'
|
||||
def work_version = "2.5.0"
|
||||
def acra = "5.7.0"
|
||||
|
||||
@ -65,17 +65,19 @@ dependencies {
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
|
||||
testImplementation 'junit:junit:4.13.1'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2'
|
||||
implementation "com.google.code.gson:gson:2.8.6"
|
||||
implementation "com.squareup.picasso:picasso:2.71828"
|
||||
implementation 'jp.wasabeef:picasso-transformations:2.4.0'
|
||||
implementation 'jp.co.cyberagent.android:gpuimage:2.1.0'
|
||||
implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1"
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2'
|
||||
implementation 'org.ocpsoft.prettytime:prettytime:5.0.0.Final'
|
||||
implementation "com.pes.materialcolorpicker:library:1.2.5"
|
||||
implementation "io.noties.markwon:core:$markwon_version"
|
||||
@ -94,11 +96,9 @@ dependencies {
|
||||
implementation "io.noties.markwon:image-picasso:$markwon_version"
|
||||
implementation "io.noties:prism4j:2.0.0"
|
||||
annotationProcessor "io.noties:prism4j-bundler:2.0.0"
|
||||
implementation "com.caverock:androidsvg:1.4"
|
||||
implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.21"
|
||||
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
|
||||
implementation "commons-io:commons-io:20030203.000550"
|
||||
implementation 'org.apache.commons:commons-lang3:3.11'
|
||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||
implementation "com.github.chrisbanes:PhotoView:2.3.0"
|
||||
implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
|
||||
implementation "ch.acra:acra-mail:$acra"
|
||||
@ -107,11 +107,10 @@ dependencies {
|
||||
implementation 'androidx.room:room-runtime:2.2.6'
|
||||
annotationProcessor 'androidx.room:room-compiler:2.2.6'
|
||||
implementation "androidx.work:work-runtime:$work_version"
|
||||
implementation "com.eightbitlab:blurview:1.6.4"
|
||||
implementation "io.mikael:urlbuilder:2.0.9"
|
||||
implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2"
|
||||
implementation "org.codeberg.gitnex:tea4j:1.0.1"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.1"
|
||||
implementation "org.codeberg.gitnex:tea4j:1.0.5"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
|
||||
implementation 'androidx.biometric:biometric:1.1.0'
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
|
||||
/**
|
||||
@ -35,7 +34,7 @@ public class NotificationsActions {
|
||||
|
||||
public void setNotificationStatus(NotificationThread notificationThread, NotificationStatus notificationStatus) throws IOException {
|
||||
|
||||
Call<ResponseBody> call = RetrofitClient.getApiInterface(context)
|
||||
Call<Void> call = RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadAsRead(instanceToken, notificationThread.getId(), notificationStatus.name());
|
||||
|
||||
if(!call.execute().isSuccessful()) {
|
||||
@ -46,7 +45,7 @@ public class NotificationsActions {
|
||||
|
||||
public boolean setAllNotificationsRead(Date date) throws IOException {
|
||||
|
||||
Call<ResponseBody> call = RetrofitClient.getApiInterface(context)
|
||||
Call<Void> call = RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadsAsRead(instanceToken, AppUtil.getTimestampFromDate(context, date), true,
|
||||
new String[]{"unread", "pinned"}, "read");
|
||||
|
||||
|
@ -24,7 +24,7 @@ import org.mian.gitnex.adapters.CommitsAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCommitsBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
@ -43,7 +43,7 @@ public class CommitsActivity extends BaseActivity {
|
||||
private TextView noData;
|
||||
private ProgressBar progressBar;
|
||||
private String TAG = "CommitsActivity";
|
||||
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private int pageSize = 1;
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
@ -85,7 +85,7 @@ public class CommitsActivity extends BaseActivity {
|
||||
// if gitea is 1.12 or higher use the new limit (resultLimitNewGiteaInstances)
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12")) {
|
||||
|
||||
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
recyclerView = activityCommitsBinding.recyclerView;
|
||||
|
@ -8,10 +8,6 @@ import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
@ -38,16 +34,7 @@ import retrofit2.Callback;
|
||||
|
||||
public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
public ImageView closeActivity;
|
||||
private View.OnClickListener onClickListener;
|
||||
private Button newFileCreate;
|
||||
|
||||
private EditText newFileName;
|
||||
private EditText newFileContent;
|
||||
private EditText newFileCommitMessage;
|
||||
private AutoCompleteTextView newFileBranches;
|
||||
private String filePath;
|
||||
private String fileSha;
|
||||
private ActivityCreateFileBinding binding;
|
||||
|
||||
public static final int FILE_ACTION_CREATE = 0;
|
||||
public static final int FILE_ACTION_DELETE = 1;
|
||||
@ -55,6 +42,9 @@ public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
private int fileAction = FILE_ACTION_CREATE;
|
||||
|
||||
private String filePath;
|
||||
private String fileSha;
|
||||
|
||||
private final List<String> branches = new ArrayList<>();
|
||||
|
||||
private String repoOwner;
|
||||
@ -66,154 +56,127 @@ public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityCreateFileBinding activityCreateFileBinding = ActivityCreateFileBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityCreateFileBinding.getRoot());
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
binding = ActivityCreateFileBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
repoOwner = parts[0];
|
||||
repoName = parts[1];
|
||||
|
||||
closeActivity = activityCreateFileBinding.close;
|
||||
newFileName = activityCreateFileBinding.newFileName;
|
||||
newFileContent = activityCreateFileBinding.newFileContent;
|
||||
newFileCommitMessage = activityCreateFileBinding.newFileCommitMessage;
|
||||
TextView toolbarTitle = activityCreateFileBinding.toolbarTitle;
|
||||
TextView toolbarTitle = binding.toolbarTitle;
|
||||
|
||||
newFileName.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(newFileName, InputMethodManager.SHOW_IMPLICIT);
|
||||
binding.newFileName.requestFocus();
|
||||
|
||||
initCloseListener();
|
||||
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
assert inputMethodManager != null;
|
||||
inputMethodManager.showSoftInput(binding.newFileName, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
newFileCreate = activityCreateFileBinding.newFileCreate;
|
||||
newFileContent.setOnTouchListener((touchView, motionEvent) -> {
|
||||
binding.close.setOnClickListener(view -> finish());
|
||||
binding.newFileContent.setOnTouchListener((touchView, motionEvent) -> {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) {
|
||||
if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 &&
|
||||
(motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
});
|
||||
|
||||
if(getIntent().getStringExtra("filePath") != null && getIntent().getIntExtra("fileAction", FILE_ACTION_DELETE) == FILE_ACTION_DELETE) {
|
||||
|
||||
fileAction = getIntent().getIntExtra("fileAction", FILE_ACTION_DELETE);
|
||||
|
||||
filePath = getIntent().getStringExtra("filePath");
|
||||
String fileContents = getIntent().getStringExtra("fileContents");
|
||||
fileSha = getIntent().getStringExtra("fileSha");
|
||||
|
||||
toolbarTitle.setText(getString(R.string.deleteFileText, filePath));
|
||||
|
||||
newFileCreate.setText(R.string.deleteFile);
|
||||
newFileName.setText(filePath);
|
||||
newFileName.setEnabled(false);
|
||||
newFileName.setFocusable(false);
|
||||
binding.newFileCreate.setText(R.string.deleteFile);
|
||||
|
||||
newFileContent.setText(fileContents);
|
||||
newFileContent.setEnabled(false);
|
||||
newFileContent.setFocusable(false);
|
||||
binding.newFileNameLayout.setVisibility(View.GONE);
|
||||
binding.newFileContentLayout.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
if(getIntent().getStringExtra("filePath") != null && getIntent().getIntExtra("fileAction", FILE_ACTION_EDIT) == FILE_ACTION_EDIT) {
|
||||
|
||||
fileAction = getIntent().getIntExtra("fileAction", FILE_ACTION_EDIT);
|
||||
|
||||
filePath = getIntent().getStringExtra("filePath");
|
||||
String fileContents = getIntent().getStringExtra("fileContents");
|
||||
fileSha = getIntent().getStringExtra("fileSha");
|
||||
|
||||
toolbarTitle.setText(getString(R.string.editFileText, filePath));
|
||||
|
||||
newFileCreate.setText(R.string.editFile);
|
||||
newFileName.setText(filePath);
|
||||
newFileName.setEnabled(false);
|
||||
newFileName.setFocusable(false);
|
||||
binding.newFileCreate.setText(R.string.editFile);
|
||||
binding.newFileName.setText(filePath);
|
||||
binding.newFileName.setEnabled(false);
|
||||
binding.newFileName.setFocusable(false);
|
||||
|
||||
newFileContent.setText(fileContents);
|
||||
binding.newFileContent.setText(getIntent().getStringExtra("fileContents"));
|
||||
|
||||
}
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
newFileBranches = activityCreateFileBinding.newFileBranches;
|
||||
getBranches(repoOwner, repoName);
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
NetworkStatusObserver networkStatusObserver = NetworkStatusObserver.getInstance(ctx);
|
||||
networkStatusObserver.registerNetworkStatusListener(hasNetworkConnection -> newFileCreate.setEnabled(hasNetworkConnection));
|
||||
networkStatusObserver.registerNetworkStatusListener(binding.newFileCreate::setEnabled);
|
||||
|
||||
newFileCreate.setOnClickListener(createFileListener);
|
||||
binding.newFileCreate.setOnClickListener(v -> processNewFile());
|
||||
|
||||
}
|
||||
|
||||
private final View.OnClickListener createFileListener = v -> processNewFile();
|
||||
|
||||
private void processNewFile() {
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
String newFileName_ = newFileName.getText().toString();
|
||||
String newFileContent_ = newFileContent.getText().toString();
|
||||
String newFileBranchName_ = newFileBranches.getText().toString();
|
||||
String newFileCommitMessage_ = newFileCommitMessage.getText().toString();
|
||||
|
||||
if(!connToInternet) {
|
||||
String newFileName = binding.newFileName.getText() != null ? binding.newFileName.getText().toString() : "";
|
||||
String newFileContent = binding.newFileContent.getText() != null ? binding.newFileContent.getText().toString() : "";
|
||||
String newFileBranchName = binding.newFileBranches.getText() != null ? binding.newFileBranches.getText().toString() : "";
|
||||
String newFileCommitMessage = binding.newFileCommitMessage.getText() != null ? binding.newFileCommitMessage.getText().toString() : "";
|
||||
|
||||
if(!AppUtil.hasNetworkConnection(appCtx)) {
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
}
|
||||
|
||||
if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) {
|
||||
|
||||
if(((newFileName.isEmpty() || newFileContent.isEmpty()) && fileAction != FILE_ACTION_DELETE) || newFileCommitMessage.isEmpty()) {
|
||||
Toasty.error(ctx, getString(R.string.newFileRequiredFields));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!AppUtil.checkStringsWithDash(newFileBranchName_)) {
|
||||
|
||||
if(!AppUtil.checkStringsWithDash(newFileBranchName)) {
|
||||
Toasty.error(ctx, getString(R.string.newFileInvalidBranchName));
|
||||
return;
|
||||
}
|
||||
|
||||
if(newFileCommitMessage_.length() > 255) {
|
||||
|
||||
if(newFileCommitMessage.length() > 255) {
|
||||
Toasty.warning(ctx, getString(R.string.newFileCommitMessageError));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
disableProcessButton();
|
||||
disableProcessButton();
|
||||
|
||||
switch(fileAction) {
|
||||
switch(fileAction) {
|
||||
|
||||
case FILE_ACTION_CREATE:
|
||||
createNewFile(Authorization.get(ctx), repoOwner, repoName, newFileName_, AppUtil.encodeBase64(newFileContent_), newFileCommitMessage_, newFileBranchName_);
|
||||
break;
|
||||
case FILE_ACTION_CREATE:
|
||||
createNewFile(repoOwner, repoName, newFileName, AppUtil.encodeBase64(newFileContent), newFileCommitMessage, newFileBranchName);
|
||||
break;
|
||||
|
||||
case FILE_ACTION_DELETE:
|
||||
deleteFile(Authorization.get(ctx), repoOwner, repoName, filePath, newFileCommitMessage_, newFileBranchName_, fileSha);
|
||||
break;
|
||||
case FILE_ACTION_DELETE:
|
||||
deleteFile(repoOwner, repoName, filePath, newFileCommitMessage, newFileBranchName, fileSha);
|
||||
break;
|
||||
|
||||
case FILE_ACTION_EDIT:
|
||||
editFile(Authorization.get(ctx), repoOwner, repoName, filePath,
|
||||
AppUtil.encodeBase64(newFileContent_), newFileCommitMessage_, newFileBranchName_, fileSha);
|
||||
break;
|
||||
case FILE_ACTION_EDIT:
|
||||
editFile(repoOwner, repoName, filePath, AppUtil.encodeBase64(newFileContent), newFileCommitMessage, newFileBranchName, fileSha);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createNewFile(final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName) {
|
||||
private void createNewFile(String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName) {
|
||||
|
||||
NewFile createNewFileJsonStr = branches.contains(branchName) ?
|
||||
new NewFile(branchName, fileContent, fileCommitMessage, "") :
|
||||
@ -221,7 +184,7 @@ public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.createNewFile(token, repoOwner, repoName, fileName, createNewFileJsonStr);
|
||||
.createNewFile(Authorization.get(ctx), repoOwner, repoName, fileName, createNewFileJsonStr);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@ -268,7 +231,7 @@ public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
}
|
||||
|
||||
private void deleteFile(final String token, String repoOwner, String repoName, String fileName, String fileCommitMessage, String branchName, String fileSha) {
|
||||
private void deleteFile(String repoOwner, String repoName, String fileName, String fileCommitMessage, String branchName, String fileSha) {
|
||||
|
||||
DeleteFile deleteFileJsonStr = branches.contains(branchName) ?
|
||||
new DeleteFile(branchName, fileCommitMessage, "", fileSha) :
|
||||
@ -276,42 +239,42 @@ public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.deleteFile(token, repoOwner, repoName, fileName, deleteFileJsonStr);
|
||||
.deleteFile(Authorization.get(ctx), repoOwner, repoName, fileName, deleteFileJsonStr);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
switch(response.code()) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.deleteFileMessage, tinyDB.getString("repoBranch")));
|
||||
getIntent().removeExtra("filePath");
|
||||
getIntent().removeExtra("fileSha");
|
||||
getIntent().removeExtra("fileContents");
|
||||
finish();
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
case 200:
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.deleteFileMessage, tinyDB.getString("repoBranch")));
|
||||
getIntent().removeExtra("filePath");
|
||||
getIntent().removeExtra("fileSha");
|
||||
getIntent().removeExtra("fileContents");
|
||||
finish();
|
||||
break;
|
||||
|
||||
enableProcessButton();
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
}
|
||||
else {
|
||||
|
||||
if(response.code() == 404) {
|
||||
case 401:
|
||||
enableProcessButton();
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
break;
|
||||
|
||||
case 404:
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.apiNotFound));
|
||||
}
|
||||
else {
|
||||
break;
|
||||
|
||||
default:
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.genericError));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,7 +288,7 @@ public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
}
|
||||
|
||||
private void editFile(final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName, String fileSha) {
|
||||
private void editFile(String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName, String fileSha) {
|
||||
|
||||
EditFile editFileJsonStr = branches.contains(branchName) ?
|
||||
new EditFile(branchName, fileCommitMessage, "", fileSha, fileContent) :
|
||||
@ -333,7 +296,7 @@ public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.editFile(token, repoOwner, repoName, fileName, editFileJsonStr);
|
||||
.editFile(Authorization.get(ctx), repoOwner, repoName, fileName, editFileJsonStr);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@ -402,8 +365,8 @@ public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(CreateFileActivity.this, R.layout.list_spinner_items, branches);
|
||||
|
||||
newFileBranches.setAdapter(adapter);
|
||||
newFileBranches.setText(tinyDB.getString("repoBranch"), false);
|
||||
binding.newFileBranches.setAdapter(adapter);
|
||||
binding.newFileBranches.setText(tinyDB.getString("repoBranch"), false);
|
||||
|
||||
enableProcessButton();
|
||||
|
||||
@ -419,19 +382,7 @@ public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
newFileCreate.setEnabled(false);
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
newFileCreate.setEnabled(true);
|
||||
}
|
||||
private void disableProcessButton() { binding.newFileCreate.setEnabled(false); }
|
||||
private void enableProcessButton() { binding.newFileCreate.setEnabled(true); }
|
||||
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
@ -51,7 +51,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
|
||||
private CustomLabelsSelectionDialogBinding labelsBinding;
|
||||
private CustomAssigneesSelectionDialogBinding assigneesBinding;
|
||||
private View.OnClickListener onClickListener;
|
||||
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private Dialog dialogLabels;
|
||||
private Dialog dialogAssignees;
|
||||
private String labelsSetter;
|
||||
@ -93,7 +93,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
|
||||
// require gitea 1.12 or higher
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
|
||||
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
viewBinding.newIssueTitle.requestFocus();
|
||||
|
@ -24,13 +24,12 @@ import org.mian.gitnex.databinding.ActivityCreatePrBinding;
|
||||
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
@ -43,7 +42,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis
|
||||
private View.OnClickListener onClickListener;
|
||||
private ActivityCreatePrBinding viewBinding;
|
||||
private CustomLabelsSelectionDialogBinding labelsBinding;
|
||||
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private Dialog dialogLabels;
|
||||
private String labelsSetter;
|
||||
private List<Integer> labelsIds = new ArrayList<>();
|
||||
@ -80,7 +79,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis
|
||||
// require gitea 1.12 or higher
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
|
||||
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
viewBinding.prBody.setOnTouchListener((touchView, motionEvent) -> {
|
||||
@ -165,14 +164,14 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis
|
||||
|
||||
CreatePullRequest createPullRequest = new CreatePullRequest(prTitle, prDescription, loginUid, mergeInto, pullFrom, milestoneId, dueDate, assignees, labelsIds);
|
||||
|
||||
Call<ResponseBody> transferCall = RetrofitClient
|
||||
Call<Void> transferCall = RetrofitClient
|
||||
.getApiInterface(appCtx)
|
||||
.createPullRequest(instanceToken, repoOwner, repoName, createPullRequest);
|
||||
|
||||
transferCall.enqueue(new Callback<ResponseBody>() {
|
||||
transferCall.enqueue(new Callback<Void>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
@ -199,7 +198,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
|
@ -27,7 +27,7 @@ import org.mian.gitnex.databinding.ActivityEditIssueBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.text.DateFormat;
|
||||
@ -45,7 +45,7 @@ import retrofit2.Callback;
|
||||
public class EditIssueActivity extends BaseActivity implements View.OnClickListener {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
|
||||
private EditText editIssueTitle;
|
||||
private EditText editIssueDescription;
|
||||
@ -93,7 +93,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
// if gitea is 1.12 or higher use the new limit
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
|
||||
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
editIssueTitle.requestFocus();
|
||||
|
@ -1,13 +1,11 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import org.gitnex.tea4j.models.FileDiffView;
|
||||
import org.mian.gitnex.R;
|
||||
@ -15,6 +13,7 @@ import org.mian.gitnex.adapters.FilesDiffAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityFileDiffBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.ParseDiff;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
@ -23,7 +22,7 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@ -52,8 +51,6 @@ public class FileDiffActivity extends BaseActivity {
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
|
||||
ImageView closeActivity = activityFileDiffBinding.close;
|
||||
toolbarTitle = activityFileDiffBinding.toolbarTitle;
|
||||
@ -71,80 +68,69 @@ public class FileDiffActivity extends BaseActivity {
|
||||
String pullIndex = tinyDb.getString("issueNumber");
|
||||
|
||||
boolean apiCall = !new Version(tinyDb.getString("giteaVersion")).less("1.13.0");
|
||||
getPullDiffContent(repoOwner, repoName, pullIndex, instanceToken, apiCall);
|
||||
getPullDiffContent(repoOwner, repoName, pullIndex, apiCall);
|
||||
|
||||
}
|
||||
|
||||
private void getPullDiffContent(String owner, String repo, String pullIndex, String token, boolean apiCall) {
|
||||
private void getPullDiffContent(String owner, String repo, String pullIndex, boolean apiCall) {
|
||||
|
||||
Call<ResponseBody> call;
|
||||
if(apiCall) {
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
call = RetrofitClient.getApiInterface(ctx).getPullDiffContent(token, owner, repo, pullIndex);
|
||||
}
|
||||
else {
|
||||
Call<ResponseBody> call = apiCall ?
|
||||
RetrofitClient.getApiInterface(ctx).getPullDiffContent(Authorization.get(ctx), owner, repo, pullIndex) :
|
||||
RetrofitClient.getWebInterface(ctx).getPullDiffContent(Authorization.getWeb(ctx), owner, repo, pullIndex);
|
||||
|
||||
call = RetrofitClient.getWebInterface(ctx).getPullDiffContent(owner, repo, pullIndex);
|
||||
}
|
||||
try {
|
||||
|
||||
call.enqueue(new Callback<ResponseBody>() {
|
||||
Response<ResponseBody> response = call.execute();
|
||||
assert response.body() != null;
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
|
||||
switch(response.code()) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
case 200:
|
||||
List<FileDiffView> fileDiffViews = ParseDiff.getFileDiffViewArray(response.body().string());
|
||||
|
||||
try {
|
||||
int filesCount = fileDiffViews.size();
|
||||
|
||||
assert response.body() != null;
|
||||
String toolbarTitleText = (filesCount > 1) ?
|
||||
getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount)) :
|
||||
getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount));
|
||||
|
||||
List<FileDiffView> fileContentsArray = ParseDiff.getFileDiffViewArray(response.body().string());
|
||||
FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, getSupportFragmentManager(), fileDiffViews);
|
||||
|
||||
int filesCount = fileContentsArray.size();
|
||||
if(filesCount > 1) {
|
||||
runOnUiThread(() -> {
|
||||
toolbarTitle.setText(toolbarTitleText);
|
||||
mListView.setAdapter(adapter);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
});
|
||||
break;
|
||||
|
||||
toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount)));
|
||||
}
|
||||
else {
|
||||
case 401:
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx,
|
||||
getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
break;
|
||||
|
||||
toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount)));
|
||||
}
|
||||
case 403:
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
break;
|
||||
|
||||
FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, getSupportFragmentManager(), fileContentsArray);
|
||||
mListView.setAdapter(adapter);
|
||||
case 404:
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
break;
|
||||
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
catch(IOException e) {
|
||||
default:
|
||||
Toasty.error(ctx, getString(R.string.labelGeneralError));
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
} catch(IOException ignored) {}
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.labelGeneralError));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
thread.start();
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
@ -153,6 +139,7 @@ public class FileDiffActivity extends BaseActivity {
|
||||
|
||||
getIntent().removeExtra("singleFileName");
|
||||
finish();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,21 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import com.github.barteksc.pdfviewer.PDFView;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import com.github.barteksc.pdfviewer.util.FitPolicy;
|
||||
import com.github.chrisbanes.photoview.PhotoView;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.gitnex.tea4j.models.Files;
|
||||
@ -33,19 +25,19 @@ import org.mian.gitnex.databinding.ActivityFileViewBinding;
|
||||
import org.mian.gitnex.fragments.BottomSheetFileViewerFragment;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Images;
|
||||
import org.mian.gitnex.helpers.Markdown;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.highlightjs.HighlightJsView;
|
||||
import org.mian.gitnex.helpers.highlightjs.models.Theme;
|
||||
import java.io.File;
|
||||
import org.mian.gitnex.notifications.Notifications;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Objects;
|
||||
import java.util.Arrays;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@ -53,74 +45,38 @@ import retrofit2.Callback;
|
||||
|
||||
public class FileViewActivity extends BaseActivity implements BottomSheetFileViewerFragment.BottomSheetListener {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView singleFileContents;
|
||||
private LinearLayout singleFileContentsFrame;
|
||||
private HighlightJsView singleCodeContents;
|
||||
private PhotoView imageView;
|
||||
private ProgressBar mProgressBar;
|
||||
private byte[] imageData;
|
||||
private PDFView pdfView;
|
||||
private LinearLayout pdfViewFrame;
|
||||
private byte[] decodedPdf;
|
||||
private ActivityFileViewBinding binding;
|
||||
private Boolean pdfNightMode;
|
||||
private String singleFileName;
|
||||
private String fileSha;
|
||||
|
||||
private Files file;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityFileViewBinding activityFileViewBinding = ActivityFileViewBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityFileViewBinding.getRoot());
|
||||
binding = ActivityFileViewBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
Toolbar toolbar = activityFileViewBinding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
setSupportActionBar(binding.toolbar);
|
||||
|
||||
tinyDB.putBoolean("enableMarkdownInFileView", false);
|
||||
|
||||
file = (Files) getIntent().getSerializableExtra("file");
|
||||
|
||||
binding.close.setOnClickListener(view -> finish());
|
||||
|
||||
binding.toolbarTitle.setMovementMethod(new ScrollingMovementMethod());
|
||||
binding.toolbarTitle.setText(file.getPath());
|
||||
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String repoBranch = tinyDB.getString("repoBranch");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String loginUid = tinyDB.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDB.getString(loginUid + "-token");
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
|
||||
tinyDB.putBoolean("enableMarkdownInFileView", false);
|
||||
getSingleFileContents(repoOwner, repoName, file.getPath(), repoBranch);
|
||||
|
||||
ImageView closeActivity = activityFileViewBinding.close;
|
||||
singleFileContents = activityFileViewBinding.singleFileContents;
|
||||
singleCodeContents = activityFileViewBinding.singleCodeContents;
|
||||
imageView = activityFileViewBinding.imageView;
|
||||
mProgressBar = activityFileViewBinding.progressBar;
|
||||
pdfView = activityFileViewBinding.pdfView;
|
||||
pdfViewFrame = activityFileViewBinding.pdfViewFrame;
|
||||
singleFileContentsFrame = activityFileViewBinding.singleFileContentsFrame;
|
||||
|
||||
singleFileName = getIntent().getStringExtra("singleFileName");
|
||||
|
||||
TextView toolbar_title = activityFileViewBinding.toolbarTitle;
|
||||
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
tinyDB.putString("downloadFileContents", "");
|
||||
|
||||
try {
|
||||
|
||||
singleFileName = URLDecoder.decode(singleFileName, "UTF-8");
|
||||
singleFileName = singleFileName.replaceAll("//", "/");
|
||||
singleFileName = singleFileName.startsWith("/") ? singleFileName.substring(1) : singleFileName;
|
||||
}
|
||||
catch(UnsupportedEncodingException e) {
|
||||
|
||||
Log.i("singleFileName", singleFileName);
|
||||
}
|
||||
|
||||
toolbar_title.setText(singleFileName);
|
||||
|
||||
getSingleFileContents(instanceToken, repoOwner, repoName, singleFileName, repoBranch);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -128,166 +84,201 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
|
||||
|
||||
super.onResume();
|
||||
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String repoBranch = tinyDB.getString("repoBranch");
|
||||
String[] parts = repoFullName.split("/");
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
String loginUid = tinyDB.getString("loginUid");
|
||||
String instanceToken = "token " + tinyDB.getString(loginUid + "-token");
|
||||
|
||||
if(tinyDB.getBoolean("fileModified")) {
|
||||
|
||||
getSingleFileContents(instanceToken, repoOwner, repoName, singleFileName, repoBranch);
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String repoBranch = tinyDB.getString("repoBranch");
|
||||
String[] parts = repoFullName.split("/");
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
|
||||
getSingleFileContents(repoOwner, repoName, file.getPath(), repoBranch);
|
||||
tinyDB.putBoolean("fileModified", false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void getSingleFileContents(final String owner, String repo, final String filename, String ref) {
|
||||
|
||||
private void getSingleFileContents(String token, final String owner, String repo, final String filename, String ref) {
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
Call<Files> call = RetrofitClient.getApiInterface(ctx).getSingleFileContents(token, owner, repo, filename, ref);
|
||||
Call<ResponseBody> call = RetrofitClient
|
||||
.getWebInterface(ctx)
|
||||
.getFileContents(Authorization.getWeb(ctx), owner, repo, ref, filename);
|
||||
|
||||
call.enqueue(new Callback<Files>() {
|
||||
try {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Files> call, @NonNull retrofit2.Response<Files> response) {
|
||||
Response<ResponseBody> response = call.execute();
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
assert response.body() != null;
|
||||
ResponseBody responseBody = response.body();
|
||||
|
||||
if(!response.body().getContent().equals("")) {
|
||||
if(responseBody != null) {
|
||||
|
||||
runOnUiThread(() -> binding.progressBar.setVisibility(View.GONE));
|
||||
|
||||
String fileExtension = FileUtils.getExtension(filename);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
|
||||
fileSha = response.body().getSha();
|
||||
|
||||
// download file meta
|
||||
tinyDB.putString("downloadFileName", filename);
|
||||
tinyDB.putString("downloadFileContents", response.body().getContent());
|
||||
|
||||
boolean unknown = false;
|
||||
boolean processable = false;
|
||||
|
||||
switch(AppUtil.getFileType(fileExtension)) {
|
||||
|
||||
case IMAGE:
|
||||
|
||||
singleFileContentsFrame.setVisibility(View.GONE);
|
||||
singleCodeContents.setVisibility(View.GONE);
|
||||
pdfViewFrame.setVisibility(View.GONE);
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
// See https://developer.android.com/guide/topics/media/media-formats#core
|
||||
if(Arrays.asList("bmp", "gif", "jpg", "jpeg", "png", "webp", "heic", "heif").contains(fileExtension.toLowerCase())) {
|
||||
|
||||
imageData = Base64.decode(response.body().getContent(), Base64.DEFAULT);
|
||||
imageView.setImageBitmap(Images.scaleImage(imageData, 1920));
|
||||
processable = true;
|
||||
|
||||
byte[] pictureBytes = responseBody.bytes();
|
||||
|
||||
runOnUiThread(() -> {
|
||||
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
binding.pdfViewFrame.setVisibility(View.GONE);
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
|
||||
binding.photoView.setVisibility(View.VISIBLE);
|
||||
binding.photoView.setImageBitmap(Images.scaleImage(pictureBytes, 1920));
|
||||
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case UNKNOWN:
|
||||
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);
|
||||
|
||||
if(file.getSize() > Constants.maximumFileViewerSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
singleCodeContents.setSource(AppUtil.decodeBase64(response.body().getContent()));
|
||||
processable = true;
|
||||
|
||||
String text = responseBody.string();
|
||||
|
||||
runOnUiThread(() -> {
|
||||
|
||||
binding.photoView.setVisibility(View.GONE);
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
binding.pdfViewFrame.setVisibility(View.GONE);
|
||||
|
||||
switch(tinyDB.getInt("fileviewerSourceCodeThemeId")) {
|
||||
|
||||
case 1: binding.contents.setTheme(Theme.ARDUINO_LIGHT); break;
|
||||
case 2: binding.contents.setTheme(Theme.GITHUB); break;
|
||||
case 3: binding.contents.setTheme(Theme.FAR); break;
|
||||
case 4: binding.contents.setTheme(Theme.IR_BLACK); break;
|
||||
case 5: binding.contents.setTheme(Theme.ANDROID_STUDIO); break;
|
||||
|
||||
default: binding.contents.setTheme(Theme.MONOKAI_SUBLIME);
|
||||
|
||||
}
|
||||
|
||||
binding.contents.setVisibility(View.VISIBLE);
|
||||
binding.contents.setContent(text);
|
||||
|
||||
});
|
||||
break;
|
||||
|
||||
case DOCUMENT:
|
||||
|
||||
if(fileExtension.equalsIgnoreCase("pdf")) {
|
||||
|
||||
imageView.setVisibility(View.GONE);
|
||||
singleFileContentsFrame.setVisibility(View.GONE);
|
||||
singleCodeContents.setVisibility(View.GONE);
|
||||
pdfViewFrame.setVisibility(View.VISIBLE);
|
||||
processable = true;
|
||||
|
||||
pdfNightMode = tinyDB.getBoolean("enablePdfMode");
|
||||
decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT);
|
||||
byte[] documentBytes = responseBody.bytes();
|
||||
|
||||
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();
|
||||
runOnUiThread(() -> {
|
||||
|
||||
binding.photoView.setVisibility(View.GONE);
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
|
||||
pdfNightMode = tinyDB.getBoolean("enablePdfMode");
|
||||
|
||||
binding.pdfViewFrame.setVisibility(View.VISIBLE);
|
||||
binding.pdfView.fromBytes(documentBytes)
|
||||
.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;
|
||||
}
|
||||
|
||||
if(unknown) { // While the file could still be non-binary,
|
||||
if(!processable) { // While the file could still be non-binary,
|
||||
// it's better we don't show it (to prevent any crashes and/or unwanted behavior) and let the user download it instead.
|
||||
|
||||
imageView.setVisibility(View.GONE);
|
||||
singleCodeContents.setVisibility(View.GONE);
|
||||
pdfViewFrame.setVisibility(View.GONE);
|
||||
singleFileContentsFrame.setVisibility(View.VISIBLE);
|
||||
responseBody.close();
|
||||
|
||||
singleFileContents.setText(getString(R.string.excludeFilesInFileViewer));
|
||||
singleFileContents.setGravity(Gravity.CENTER);
|
||||
singleFileContents.setTypeface(null, Typeface.BOLD);
|
||||
runOnUiThread(() -> {
|
||||
|
||||
binding.photoView.setVisibility(View.GONE);
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
binding.pdfViewFrame.setVisibility(View.GONE);
|
||||
|
||||
binding.markdownFrame.setVisibility(View.VISIBLE);
|
||||
binding.markdown.setText(getString(R.string.excludeFilesInFileViewer));
|
||||
binding.markdown.setGravity(Gravity.CENTER);
|
||||
binding.markdown.setTypeface(null, Typeface.BOLD);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
runOnUiThread(() -> {
|
||||
binding.markdown.setText("");
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
});
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 401:
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx,
|
||||
getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
break;
|
||||
|
||||
case 403:
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
break;
|
||||
|
||||
case 404:
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
break;
|
||||
|
||||
default:
|
||||
Toasty.error(ctx, getString(R.string.labelGeneralError));
|
||||
|
||||
singleFileContents.setText("");
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
} catch(IOException ignored) {}
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.labelGeneralError));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Files> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
thread.start();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -297,11 +288,11 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
|
||||
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
|
||||
inflater.inflate(R.menu.files_view_menu, menu);
|
||||
|
||||
String fileExtension = FileUtils.getExtension(singleFileName);
|
||||
if(!FileUtils.getExtension(file.getName())
|
||||
.equalsIgnoreCase("md")) {
|
||||
|
||||
if(!fileExtension.equalsIgnoreCase("md")) {
|
||||
|
||||
menu.getItem(0).setVisible(false);
|
||||
menu.getItem(0)
|
||||
.setVisible(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -316,35 +307,36 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
|
||||
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.genericMenu) {
|
||||
|
||||
} else if(id == R.id.genericMenu) {
|
||||
|
||||
BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet");
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.markdown) {
|
||||
|
||||
new Markdown(ctx, EmojiParser.parseToUnicode(AppUtil.decodeBase64(tinyDB.getString("downloadFileContents"))), singleFileContents);
|
||||
} else if(id == R.id.markdown) {
|
||||
|
||||
if(!tinyDB.getBoolean("enableMarkdownInFileView")) {
|
||||
|
||||
singleCodeContents.setVisibility(View.GONE);
|
||||
singleFileContentsFrame.setVisibility(View.VISIBLE);
|
||||
singleFileContents.setVisibility(View.VISIBLE);
|
||||
tinyDB.putBoolean("enableMarkdownInFileView", true);
|
||||
}
|
||||
else {
|
||||
new Markdown(ctx, EmojiParser.parseToUnicode(binding.contents.getContent()), binding.markdown);
|
||||
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
binding.markdownFrame.setVisibility(View.VISIBLE);
|
||||
|
||||
tinyDB.putBoolean("enableMarkdownInFileView", true);
|
||||
|
||||
} else {
|
||||
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
binding.contents.setVisibility(View.VISIBLE);
|
||||
|
||||
singleCodeContents.setVisibility(View.VISIBLE);
|
||||
singleFileContentsFrame.setVisibility(View.GONE);
|
||||
singleFileContents.setVisibility(View.GONE);
|
||||
singleCodeContents.setSource(AppUtil.decodeBase64(tinyDB.getString("downloadFileContents")));
|
||||
tinyDB.putBoolean("enableMarkdownInFileView", false);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
@ -360,102 +352,118 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
|
||||
|
||||
if("deleteFile".equals(text)) {
|
||||
|
||||
String fileExtension = FileUtils.getExtension(singleFileName);
|
||||
|
||||
String data = AppUtil.getFileType(fileExtension) == AppUtil.FileType.TEXT ?
|
||||
AppUtil.decodeBase64(tinyDB.getString("downloadFileContents")) : "";
|
||||
|
||||
Intent intent = new Intent(ctx, CreateFileActivity.class);
|
||||
intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_DELETE);
|
||||
intent.putExtra("filePath", singleFileName);
|
||||
intent.putExtra("fileSha", fileSha);
|
||||
intent.putExtra("fileContents", data);
|
||||
intent.putExtra("filePath", file.getPath());
|
||||
intent.putExtra("fileSha", file.getSha());
|
||||
|
||||
ctx.startActivity(intent);
|
||||
|
||||
}
|
||||
|
||||
if("editFile".equals(text)) {
|
||||
|
||||
String fileExtension = FileUtils.getExtension(singleFileName);
|
||||
if(binding.contents.getContent() != null &&
|
||||
!binding.contents.getContent().isEmpty()) {
|
||||
|
||||
switch(AppUtil.getFileType(fileExtension)) {
|
||||
Intent intent = new Intent(ctx, CreateFileActivity.class);
|
||||
|
||||
case TEXT:
|
||||
intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_EDIT);
|
||||
intent.putExtra("filePath", file.getPath());
|
||||
intent.putExtra("fileSha", file.getSha());
|
||||
intent.putExtra("fileContents", binding.contents.getContent());
|
||||
|
||||
Intent intent = new Intent(ctx, CreateFileActivity.class);
|
||||
ctx.startActivity(intent);
|
||||
|
||||
intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_EDIT);
|
||||
intent.putExtra("filePath", singleFileName);
|
||||
intent.putExtra("fileSha", fileSha);
|
||||
intent.putExtra("fileContents", AppUtil.decodeBase64(tinyDB.getString("downloadFileContents")));
|
||||
} else {
|
||||
|
||||
ctx.startActivity(intent);
|
||||
break;
|
||||
default:
|
||||
|
||||
Toasty.error(ctx, getString(R.string.fileTypeCannotBeEdited));
|
||||
Toasty.error(ctx, getString(R.string.fileTypeCannotBeEdited));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void requestFileDownload() {
|
||||
|
||||
if(!tinyDB.getString("downloadFileContents").isEmpty()) {
|
||||
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||
|
||||
File outputFileName = new File(tinyDB.getString("downloadFileName"));
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.putExtra(Intent.EXTRA_TITLE, file.getName());
|
||||
intent.setType("*/*");
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||
activityResultLauncher.launch(intent);
|
||||
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
intent.putExtra(Intent.EXTRA_TITLE, outputFileName.getName());
|
||||
|
||||
fileDownloadActivityResultLauncher.launch(intent);
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.waitLoadingDownloadFile));
|
||||
}
|
||||
}
|
||||
|
||||
ActivityResultLauncher<Intent> fileDownloadActivityResultLauncher =
|
||||
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
||||
ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
||||
|
||||
if (result.getResultCode() == Activity.RESULT_OK) {
|
||||
if (result.getResultCode() == Activity.RESULT_OK) {
|
||||
|
||||
Intent data = result.getData();
|
||||
assert result.getData() != null;
|
||||
|
||||
try {
|
||||
try {
|
||||
|
||||
assert data != null;
|
||||
Uri uri = data.getData();
|
||||
OutputStream outputStream = getContentResolver().openOutputStream(result.getData().getData());
|
||||
|
||||
assert uri != null;
|
||||
OutputStream outputStream = getContentResolver().openOutputStream(uri);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, ctx.getPackageName())
|
||||
.setContentTitle(getString(R.string.fileViewerNotificationTitleStarted))
|
||||
.setContentText(getString(R.string.fileViewerNotificationDescriptionStarted, file.getName()))
|
||||
.setSmallIcon(R.drawable.gitnex_transparent)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setChannelId(Constants.downloadNotificationChannelId)
|
||||
.setProgress(100, 0, false)
|
||||
.setOngoing(true);
|
||||
|
||||
byte[] dataAsBytes = Base64.decode(tinyDB.getString("downloadFileContents"), 0);
|
||||
int notificationId = Notifications.uniqueNotificationId(ctx);
|
||||
|
||||
assert outputStream != null;
|
||||
outputStream.write(dataAsBytes);
|
||||
outputStream.close();
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);;
|
||||
notificationManager.notify(notificationId, builder.build());
|
||||
|
||||
Toasty.success(ctx, getString(R.string.downloadFileSaved));
|
||||
}
|
||||
catch(IOException e) {
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String repoBranch = tinyDB.getString("repoBranch");
|
||||
String[] parts = repoFullName.split("/");
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
|
||||
Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage()));
|
||||
}
|
||||
}
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
});
|
||||
try {
|
||||
|
||||
private void initCloseListener() {
|
||||
Call<ResponseBody> call = RetrofitClient
|
||||
.getWebInterface(ctx)
|
||||
.getFileContents(Authorization.getWeb(ctx), repoOwner, repoName, repoBranch, file.getPath());
|
||||
|
||||
onClickListener = view -> {
|
||||
Response<ResponseBody> response = call.execute();
|
||||
|
||||
getIntent().removeExtra("singleFileName");
|
||||
finish();
|
||||
};
|
||||
}
|
||||
assert response.body() != null;
|
||||
|
||||
AppUtil.copyProgress(response.body().byteStream(), outputStream, file.getSize(), progress -> {
|
||||
builder.setProgress(100, progress, false);
|
||||
notificationManager.notify(notificationId, builder.build());
|
||||
});
|
||||
|
||||
builder.setContentTitle(getString(R.string.fileViewerNotificationTitleFinished))
|
||||
.setContentText(getString(R.string.fileViewerNotificationDescriptionFinished, file.getName()));
|
||||
|
||||
} catch(IOException ignored) {
|
||||
|
||||
builder.setContentTitle(getString(R.string.fileViewerNotificationTitleFailed))
|
||||
.setContentText(getString(R.string.fileViewerNotificationDescriptionFailed, file.getName()));
|
||||
|
||||
} finally {
|
||||
|
||||
builder.setProgress(0,0,false)
|
||||
.setOngoing(false);
|
||||
|
||||
notificationManager.notify(notificationId, builder.build());
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
thread.start();
|
||||
|
||||
} catch(IOException ignored) {}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
@ -61,8 +60,7 @@ import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import eightbitlab.com.blurview.BlurView;
|
||||
import eightbitlab.com.blurview.RenderScriptBlur;
|
||||
import jp.wasabeef.picasso.transformations.BlurTransformation;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
@ -73,12 +71,10 @@ import retrofit2.Callback;
|
||||
public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener, BottomSheetDraftsFragment.BottomSheetListener {
|
||||
|
||||
private DrawerLayout drawer;
|
||||
private BlurView blurView;
|
||||
private TextView userFullName;
|
||||
private TextView userEmail;
|
||||
private ImageView userAvatar;
|
||||
private ImageView userAvatarBackground;
|
||||
private ViewGroup navHeaderFrame;
|
||||
private TextView toolbarTitle;
|
||||
private Typeface myTypeface;
|
||||
|
||||
@ -273,12 +269,10 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
||||
String userFullNameNav = tinyDB.getString("userFullname");
|
||||
String userAvatarNav = tinyDB.getString("userAvatar");
|
||||
|
||||
blurView = hView.findViewById(R.id.blurView);
|
||||
userEmail = hView.findViewById(R.id.userEmail);
|
||||
userFullName = hView.findViewById(R.id.userFullname);
|
||||
userAvatar = hView.findViewById(R.id.userAvatar);
|
||||
userAvatarBackground = hView.findViewById(R.id.userAvatarBackground);
|
||||
navHeaderFrame = hView.findViewById(R.id.navHeaderFrame);
|
||||
|
||||
List<UserAccount> userAccountsList;
|
||||
userAccountsList = new ArrayList<>();
|
||||
@ -323,24 +317,18 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
||||
|
||||
PicassoService.getInstance(ctx).get()
|
||||
.load(userAvatarNav)
|
||||
.transform(new BlurTransformation(ctx))
|
||||
.into(userAvatarBackground, new com.squareup.picasso.Callback() {
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
|
||||
int textColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground);
|
||||
int textColor = new ColorInverter().getImageViewContrastColor(userAvatar);
|
||||
|
||||
userFullName.setTextColor(textColor);
|
||||
userEmail.setTextColor(textColor);
|
||||
|
||||
blurView.setupWith(navHeaderFrame)
|
||||
.setBlurAlgorithm(new RenderScriptBlur(ctx))
|
||||
.setBlurRadius(5)
|
||||
.setHasFixedTransformationMatrix(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {}
|
||||
@Override public void onError(Exception e) {}
|
||||
});
|
||||
}
|
||||
|
||||
@ -350,6 +338,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_profile);
|
||||
drawer.closeDrawers();
|
||||
|
||||
});
|
||||
|
||||
getNotificationsCount(instanceToken);
|
||||
@ -403,22 +392,21 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
||||
switch(launchFragmentByHandler) {
|
||||
|
||||
case "repos":
|
||||
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_repositories);
|
||||
return;
|
||||
case "org":
|
||||
|
||||
case "org":
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_organizations);
|
||||
return;
|
||||
case "notification":
|
||||
|
||||
case "notification":
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_notifications);
|
||||
return;
|
||||
case "explore":
|
||||
|
||||
case "explore":
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_explore);
|
||||
return;
|
||||
@ -438,49 +426,48 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
||||
switch(tinyDB.getInt("homeScreenId")) {
|
||||
|
||||
case 1:
|
||||
|
||||
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_starred_repos);
|
||||
break;
|
||||
case 2:
|
||||
|
||||
case 2:
|
||||
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_organizations);
|
||||
break;
|
||||
case 3:
|
||||
|
||||
case 3:
|
||||
toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_repositories);
|
||||
break;
|
||||
case 4:
|
||||
|
||||
case 4:
|
||||
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_profile);
|
||||
break;
|
||||
case 5:
|
||||
|
||||
case 5:
|
||||
toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_explore);
|
||||
break;
|
||||
case 6:
|
||||
|
||||
case 6:
|
||||
toolbarTitle.setText(getResources().getString(R.string.titleDrafts));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new DraftsFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_comments_draft);
|
||||
break;
|
||||
case 7:
|
||||
|
||||
case 7:
|
||||
toolbarTitle.setText(getResources().getString(R.string.pageTitleNotifications));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_notifications);
|
||||
break;
|
||||
default:
|
||||
|
||||
default:
|
||||
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
|
||||
navigationView.setCheckedItem(R.id.nav_home);
|
||||
|
@ -21,7 +21,6 @@ import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
@ -170,12 +169,12 @@ public class MergePullRequestActivity extends BaseActivity {
|
||||
|
||||
MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle);
|
||||
|
||||
Call<ResponseBody> call = RetrofitClient.getApiInterface(ctx).mergePullRequest(Authorization.get(ctx), repoOwner, repoName, prIndex, mergePR);
|
||||
Call<Void> call = RetrofitClient.getApiInterface(ctx).mergePullRequest(Authorization.get(ctx), repoOwner, repoName, prIndex, mergePR);
|
||||
|
||||
call.enqueue(new Callback<ResponseBody>() {
|
||||
call.enqueue(new Callback<Void>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
@ -244,7 +243,7 @@ public class MergePullRequestActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
|
@ -27,7 +27,7 @@ import org.mian.gitnex.adapters.RepoForksAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityRepoForksBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
@ -46,7 +46,7 @@ public class RepoForksActivity extends BaseActivity {
|
||||
private TextView noData;
|
||||
private ProgressBar progressBar;
|
||||
private String TAG = "RepositoryForks";
|
||||
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private int pageSize = 1;
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
@ -90,7 +90,7 @@ public class RepoForksActivity extends BaseActivity {
|
||||
// if gitea is 1.12 or higher use the new limit (resultLimitNewGiteaInstances)
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12")) {
|
||||
|
||||
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
recyclerView = activityRepoForksBinding.recyclerView;
|
||||
|
@ -1,12 +1,8 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivitySettingsFileviewerBinding;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
@ -17,40 +13,29 @@ import org.mian.gitnex.helpers.Toasty;
|
||||
|
||||
public class SettingsFileViewerActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
private static final String[] fileViewerSourceCodeThemesList = {"Sublime", "Arduino Light", "Github", "Far ", "Ir Black", "Android Studio"};
|
||||
private static int fileViewerSourceCodeThemesSelectedChoice = 0;
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivitySettingsFileviewerBinding activitySettingsFileviewerBinding = ActivitySettingsFileviewerBinding.inflate(getLayoutInflater());
|
||||
setContentView(activitySettingsFileviewerBinding.getRoot());
|
||||
ActivitySettingsFileviewerBinding binding = ActivitySettingsFileviewerBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
ImageView closeActivity = activitySettingsFileviewerBinding.close;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
TextView fileViewerSourceCodeThemesSelected = activitySettingsFileviewerBinding.sourceCodeThemeSelected; // setter for fileviewer theme
|
||||
LinearLayout sourceCodeThemeFrame = activitySettingsFileviewerBinding.sourceCodeThemeFrame;
|
||||
SwitchMaterial pdfModeSwitch = activitySettingsFileviewerBinding.switchPdfMode;
|
||||
|
||||
if(!tinyDB.getString("fileviewerSourceCodeThemeStr").isEmpty()) {
|
||||
fileViewerSourceCodeThemesSelected.setText(tinyDB.getString("fileviewerSourceCodeThemeStr"));
|
||||
}
|
||||
binding.close.setOnClickListener(view -> finish());
|
||||
|
||||
if(fileViewerSourceCodeThemesSelectedChoice == 0) {
|
||||
fileViewerSourceCodeThemesSelectedChoice = tinyDB.getInt("fileviewerThemeId");
|
||||
}
|
||||
|
||||
pdfModeSwitch.setChecked(tinyDB.getBoolean("enablePdfMode"));
|
||||
binding.sourceCodeThemeSelected.setText(tinyDB.getString("fileviewerSourceCodeThemeStr", fileViewerSourceCodeThemesList[0]));
|
||||
binding.switchPdfMode.setChecked(tinyDB.getBoolean("enablePdfMode"));
|
||||
|
||||
// fileviewer srouce code theme selection dialog
|
||||
sourceCodeThemeFrame.setOnClickListener(view -> {
|
||||
// fileviewer source code theme selection dialog
|
||||
binding.sourceCodeThemeFrame.setOnClickListener(view -> {
|
||||
|
||||
AlertDialog.Builder fvtsBuilder = new AlertDialog.Builder(SettingsFileViewerActivity.this);
|
||||
|
||||
@ -60,7 +45,7 @@ public class SettingsFileViewerActivity extends BaseActivity {
|
||||
fvtsBuilder.setSingleChoiceItems(fileViewerSourceCodeThemesList, fileViewerSourceCodeThemesSelectedChoice, (dialogInterfaceTheme, i) -> {
|
||||
|
||||
fileViewerSourceCodeThemesSelectedChoice = i;
|
||||
fileViewerSourceCodeThemesSelected.setText(fileViewerSourceCodeThemesList[i]);
|
||||
binding.sourceCodeThemeSelected.setText(fileViewerSourceCodeThemesList[i]);
|
||||
tinyDB.putString("fileviewerSourceCodeThemeStr", fileViewerSourceCodeThemesList[i]);
|
||||
tinyDB.putInt("fileviewerSourceCodeThemeId", i);
|
||||
|
||||
@ -69,21 +54,20 @@ public class SettingsFileViewerActivity extends BaseActivity {
|
||||
|
||||
});
|
||||
|
||||
AlertDialog cfDialog = fvtsBuilder.create();
|
||||
cfDialog.show();
|
||||
AlertDialog alertDialog = fvtsBuilder.create();
|
||||
alertDialog.show();
|
||||
|
||||
});
|
||||
|
||||
// pdf night mode switcher
|
||||
pdfModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
binding.switchPdfMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
tinyDB.putBoolean("enablePdfMode", isChecked);
|
||||
tinyDB.putString("enablePdfModeInit", "yes");
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = view -> finish();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import androidx.appcompat.app.AlertDialog;
|
||||
import com.pes.androidmaterialcolorpickerdialog.ColorPicker;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.notifications.Notifications;
|
||||
|
||||
@ -33,7 +33,7 @@ public class SettingsNotificationsActivity extends BaseActivity {
|
||||
|
||||
viewBinding.close.setOnClickListener(onClickListener);
|
||||
|
||||
viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay)));
|
||||
viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay)));
|
||||
viewBinding.chooseColorState.setCardBackgroundColor(tinyDB.getInt("notificationsLightColor", Color.GREEN));
|
||||
|
||||
viewBinding.enableNotificationsMode.setChecked(tinyDB.getBoolean("notificationsEnabled", true));
|
||||
@ -52,9 +52,9 @@ public class SettingsNotificationsActivity extends BaseActivity {
|
||||
viewBinding.pollingDelayFrame.setOnClickListener(v -> {
|
||||
|
||||
NumberPicker numberPicker = new NumberPicker(ctx);
|
||||
numberPicker.setMinValue(StaticGlobalVariables.minimumPollingDelay);
|
||||
numberPicker.setMaxValue(StaticGlobalVariables.maximumPollingDelay);
|
||||
numberPicker.setValue(tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay));
|
||||
numberPicker.setMinValue(Constants.minimumPollingDelay);
|
||||
numberPicker.setMaxValue(Constants.maximumPollingDelay);
|
||||
numberPicker.setValue(tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay));
|
||||
numberPicker.setWrapSelectorWheel(true);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||
@ -76,6 +76,7 @@ public class SettingsNotificationsActivity extends BaseActivity {
|
||||
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
|
||||
builder.setView(numberPicker);
|
||||
builder.create().show();
|
||||
|
||||
});
|
||||
|
||||
// lights switcher
|
||||
|
@ -14,7 +14,6 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.gitnex.tea4j.models.Files;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -33,13 +32,12 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
|
||||
|
||||
public interface FilesAdapterListener {
|
||||
|
||||
void onClickDir(String str);
|
||||
void onClickFile(String str);
|
||||
void onClickFile(Files file);
|
||||
}
|
||||
|
||||
class FilesViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private String fileType;
|
||||
private Files file;
|
||||
|
||||
private final ImageView fileTypeIs;
|
||||
private final TextView fileName;
|
||||
@ -55,21 +53,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
|
||||
|
||||
//ImageView filesDropdownMenu = itemView.findViewById(R.id.filesDropdownMenu);
|
||||
|
||||
fileName.setOnClickListener(v -> {
|
||||
|
||||
Context context = v.getContext();
|
||||
|
||||
if(fileType.equals("file")) {
|
||||
filesListener.onClickFile(fileName.getText().toString());
|
||||
}
|
||||
else if(fileType.equals("dir")) {
|
||||
filesListener.onClickDir(fileName.getText().toString());
|
||||
}
|
||||
else {
|
||||
Toasty.warning(context, context.getString(R.string.filesGenericError));
|
||||
}
|
||||
|
||||
});
|
||||
fileName.setOnClickListener(v -> filesListener.onClickFile(file));
|
||||
|
||||
|
||||
/*filesDropdownMenu.setOnClickListener(new View.OnClickListener() {
|
||||
@ -170,25 +154,36 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
|
||||
|
||||
Files currentItem = alteredFiles.get(position);
|
||||
|
||||
holder.fileType = currentItem.getType();
|
||||
holder.file = currentItem;
|
||||
holder.fileName.setText(currentItem.getName());
|
||||
|
||||
if(currentItem.getType().equals("file")) {
|
||||
switch(currentItem.getType()) {
|
||||
|
||||
case "file":
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_file));
|
||||
holder.fileInfo.setVisibility(View.VISIBLE);
|
||||
holder.fileInfo.setText(FileUtils.byteCountToDisplaySize(currentItem.getSize()));
|
||||
break;
|
||||
|
||||
case "dir":
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_directory));
|
||||
holder.fileInfo.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
case "submodule":
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_submodule));
|
||||
holder.fileInfo.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
case "symlink":
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_symlink));
|
||||
holder.fileInfo.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
default:
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_question));
|
||||
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_file));
|
||||
holder.fileInfo.setVisibility(View.VISIBLE);
|
||||
holder.fileInfo.setText(FileUtils.byteCountToDisplaySize(currentItem.getSize()));
|
||||
}
|
||||
else if(currentItem.getType().equals("dir")) {
|
||||
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_directory));
|
||||
holder.fileInfo.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_question));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -224,6 +219,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
|
||||
results.values = filteredList;
|
||||
|
||||
return results;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -102,9 +102,8 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||
|
||||
class IssuesHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private String userLoginId;
|
||||
private Issues issue;
|
||||
|
||||
private final TextView issueNumber;
|
||||
private final ImageView issueAssigneeAvatar;
|
||||
private final TextView issueTitle;
|
||||
private final TextView issueCreatedTime;
|
||||
@ -114,7 +113,6 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||
|
||||
super(itemView);
|
||||
|
||||
issueNumber = itemView.findViewById(R.id.issueNumber);
|
||||
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
|
||||
issueTitle = itemView.findViewById(R.id.issueTitle);
|
||||
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
|
||||
@ -126,10 +124,10 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||
Context context = title.getContext();
|
||||
|
||||
Intent intent = new Intent(context, IssueDetailActivity.class);
|
||||
intent.putExtra("issueNumber", issueNumber.getText());
|
||||
intent.putExtra("issueNumber", issue.getNumber());
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
tinyDb.putString("issueNumber", issueNumber.getText().toString());
|
||||
tinyDb.putString("issueNumber", String.valueOf(issue.getNumber()));
|
||||
tinyDb.putString("issueType", "Issue");
|
||||
context.startActivity(intent);
|
||||
|
||||
@ -140,18 +138,18 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||
Context context = commentsCount.getContext();
|
||||
|
||||
Intent intent = new Intent(context, IssueDetailActivity.class);
|
||||
intent.putExtra("issueNumber", issueNumber.getText());
|
||||
intent.putExtra("issueNumber", issue.getNumber());
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
tinyDb.putString("issueNumber", issueNumber.getText().toString());
|
||||
tinyDb.putString("issueNumber", String.valueOf(issue.getNumber()));
|
||||
tinyDb.putString("issueType", "Issue");
|
||||
context.startActivity(intent);
|
||||
|
||||
});
|
||||
|
||||
issueAssigneeAvatar.setOnClickListener(loginId -> {
|
||||
|
||||
Context context = loginId.getContext();
|
||||
issueAssigneeAvatar.setOnClickListener(v -> {
|
||||
Context context = v.getContext();
|
||||
String userLoginId = issue.getUser().getLogin();
|
||||
|
||||
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
|
||||
});
|
||||
@ -159,40 +157,44 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
void bindData(Issues issuesModel) {
|
||||
void bindData(Issues issue) {
|
||||
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
final String locale = tinyDb.getString("locale");
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
String locale = tinyDb.getString("locale");
|
||||
String timeFormat = tinyDb.getString("dateFormat");
|
||||
|
||||
userLoginId = issuesModel.getUser().getLogin();
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(issue.getUser().getAvatar_url())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(8, 0))
|
||||
.resize(120, 120)
|
||||
.centerCrop()
|
||||
.into(issueAssigneeAvatar);
|
||||
|
||||
PicassoService.getInstance(context).get().load(issuesModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
|
||||
String issueNumber_ = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + context.getResources().getString(R.string.hash) + issue.getNumber() + "</font>";
|
||||
issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + EmojiParser.parseToUnicode(issue.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
|
||||
String issueNumber_ = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
|
||||
issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + EmojiParser.parseToUnicode(issuesModel.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
|
||||
issueNumber.setText(String.valueOf(issuesModel.getNumber()));
|
||||
issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
|
||||
this.issue = issue;
|
||||
this.issueCommentsCount.setText(String.valueOf(issue.getComments()));
|
||||
|
||||
switch(timeFormat) {
|
||||
case "pretty": {
|
||||
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
|
||||
String createdTime = prettyTime.format(issuesModel.getCreated_at());
|
||||
issueCreatedTime.setText(createdTime);
|
||||
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
|
||||
String createdTime = prettyTime.format(issue.getCreated_at());
|
||||
this.issueCreatedTime.setText(createdTime);
|
||||
this.issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issue.getCreated_at()), context));
|
||||
break;
|
||||
}
|
||||
case "normal": {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
|
||||
String createdTime = formatter.format(issuesModel.getCreated_at());
|
||||
issueCreatedTime.setText(createdTime);
|
||||
String createdTime = formatter.format(issue.getCreated_at());
|
||||
this.issueCreatedTime.setText(createdTime);
|
||||
break;
|
||||
}
|
||||
case "normal1": {
|
||||
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
|
||||
String createdTime = formatter.format(issuesModel.getCreated_at());
|
||||
issueCreatedTime.setText(createdTime);
|
||||
String createdTime = formatter.format(issue.getCreated_at());
|
||||
this.issueCreatedTime.setText(createdTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ import org.gitnex.tea4j.models.Milestones;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.actions.MilestoneActions;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Markdown;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.text.DateFormat;
|
||||
@ -41,7 +41,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||
private OnLoadMoreListener loadMoreListener;
|
||||
private boolean isLoading = false;
|
||||
private boolean isMoreDataAvailable = true;
|
||||
private String TAG = StaticGlobalVariables.tagMilestonesAdapter;
|
||||
private String TAG = Constants.tagMilestonesAdapter;
|
||||
|
||||
public MilestonesAdapter(Context context, List<Milestones> dataListMain) {
|
||||
|
||||
|
@ -67,15 +67,11 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
||||
|
||||
isLoading = true;
|
||||
loadMoreListener.onLoadMore();
|
||||
|
||||
}
|
||||
|
||||
if(getItemViewType(position) == TYPE_LOAD) {
|
||||
|
||||
((PullRequestsAdapter.PullRequestsHolder) holder).bindData(prList.get(position));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -87,7 +83,6 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -99,13 +94,8 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
||||
|
||||
class PullRequestsHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private String userLoginId;
|
||||
private PullRequests pullRequest;
|
||||
|
||||
private final TextView prNumber;
|
||||
private final TextView prMergeable;
|
||||
private final TextView prHeadBranch;
|
||||
private final TextView prIsFork;
|
||||
private final TextView prForkFullName;
|
||||
private final ImageView assigneeAvatar;
|
||||
private final TextView prTitle;
|
||||
private final TextView prCreatedTime;
|
||||
@ -115,11 +105,6 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
||||
|
||||
super(itemView);
|
||||
|
||||
prNumber = itemView.findViewById(R.id.prNumber);
|
||||
prMergeable = itemView.findViewById(R.id.prMergeable);
|
||||
prHeadBranch = itemView.findViewById(R.id.prHeadBranch);
|
||||
prIsFork = itemView.findViewById(R.id.prIsFork);
|
||||
prForkFullName = itemView.findViewById(R.id.prForkFullName);
|
||||
assigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
|
||||
prTitle = itemView.findViewById(R.id.prTitle);
|
||||
prCommentsCount = itemView.findViewById(R.id.prCommentsCount);
|
||||
@ -131,16 +116,25 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
||||
Context context = v.getContext();
|
||||
|
||||
Intent intent = new Intent(context, IssueDetailActivity.class);
|
||||
intent.putExtra("issueNumber", prNumber.getText());
|
||||
intent.putExtra("prMergeable", prMergeable.getText());
|
||||
intent.putExtra("prHeadBranch", prHeadBranch.getText());
|
||||
intent.putExtra("issueNumber", pullRequest.getNumber());
|
||||
intent.putExtra("prMergeable", pullRequest.isMergeable());
|
||||
intent.putExtra("prHeadBranch", pullRequest.getHead().getRef());
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
tinyDb.putString("issueNumber", prNumber.getText().toString());
|
||||
tinyDb.putString("prMergeable", prMergeable.getText().toString());
|
||||
tinyDb.putString("prHeadBranch", prHeadBranch.getText().toString());
|
||||
tinyDb.putString("prIsFork", prIsFork.getText().toString());
|
||||
tinyDb.putString("prForkFullName", prForkFullName.getText().toString());
|
||||
tinyDb.putString("issueNumber", String.valueOf(pullRequest.getNumber()));
|
||||
tinyDb.putString("prMergeable", String.valueOf(pullRequest.isMergeable()));
|
||||
tinyDb.putString("prHeadBranch", pullRequest.getHead().getRef());
|
||||
|
||||
if(pullRequest.getHead() != null && pullRequest.getHead().getRepo() != null) {
|
||||
tinyDb.putString("prIsFork", String.valueOf(pullRequest.getHead().getRepo().isFork()));
|
||||
tinyDb.putString("prForkFullName", pullRequest.getHead().getRepo().getFull_name());
|
||||
}
|
||||
else {
|
||||
// pull was done from a deleted fork
|
||||
tinyDb.putString("prIsFork", "true");
|
||||
tinyDb.putString("prForkFullName", context.getString(R.string.prDeletedFork));
|
||||
}
|
||||
|
||||
tinyDb.putString("issueType", "Pull");
|
||||
context.startActivity(intent);
|
||||
|
||||
@ -151,23 +145,33 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
||||
Context context = v.getContext();
|
||||
|
||||
Intent intent = new Intent(context, IssueDetailActivity.class);
|
||||
intent.putExtra("issueNumber", prNumber.getText());
|
||||
intent.putExtra("prMergeable", prMergeable.getText());
|
||||
intent.putExtra("prHeadBranch", prHeadBranch.getText());
|
||||
intent.putExtra("issueNumber", pullRequest.getNumber());
|
||||
intent.putExtra("prMergeable", pullRequest.isMergeable());
|
||||
intent.putExtra("prHeadBranch", pullRequest.getHead().getRef());
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
tinyDb.putString("issueNumber", prNumber.getText().toString());
|
||||
tinyDb.putString("prMergeable", prMergeable.getText().toString());
|
||||
tinyDb.putString("prHeadBranch", prHeadBranch.getText().toString());
|
||||
tinyDb.putString("prIsFork", prIsFork.getText().toString());
|
||||
tinyDb.putString("prForkFullName", prForkFullName.getText().toString());
|
||||
tinyDb.putString("issueNumber", String.valueOf(pullRequest.getNumber()));
|
||||
tinyDb.putString("prMergeable", String.valueOf(pullRequest.isMergeable()));
|
||||
tinyDb.putString("prHeadBranch", pullRequest.getHead().getRef());
|
||||
|
||||
if(pullRequest.getHead() != null && pullRequest.getHead().getRepo() != null) {
|
||||
tinyDb.putString("prIsFork", String.valueOf(pullRequest.getHead().getRepo().isFork()));
|
||||
tinyDb.putString("prForkFullName", pullRequest.getHead().getRepo().getFull_name());
|
||||
}
|
||||
else {
|
||||
// pull was done from a deleted fork
|
||||
tinyDb.putString("prIsFork", "true");
|
||||
tinyDb.putString("prForkFullName", context.getString(R.string.prDeletedFork));
|
||||
}
|
||||
|
||||
tinyDb.putString("issueType", "Pull");
|
||||
context.startActivity(intent);
|
||||
|
||||
});
|
||||
|
||||
assigneeAvatar.setOnClickListener(loginId -> {
|
||||
|
||||
Context context = loginId.getContext();
|
||||
assigneeAvatar.setOnClickListener(v -> {
|
||||
Context context = v.getContext();
|
||||
String userLoginId = pullRequest.getUser().getLogin();
|
||||
|
||||
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
|
||||
});
|
||||
@ -175,43 +179,32 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
void bindData(PullRequests prModel) {
|
||||
void bindData(PullRequests pullRequest) {
|
||||
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
final String locale = tinyDb.getString("locale");
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
String locale = tinyDb.getString("locale");
|
||||
String timeFormat = tinyDb.getString("dateFormat");
|
||||
|
||||
userLoginId = prModel.getUser().getLogin();
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(pullRequest.getUser().getAvatar_url())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(8, 0))
|
||||
.resize(120, 120)
|
||||
.centerCrop()
|
||||
.into(this.assigneeAvatar);
|
||||
|
||||
PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
|
||||
this.pullRequest = pullRequest;
|
||||
|
||||
String prNumber_ = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + context.getResources().getString(R.string.hash) + prModel.getNumber() + "</font>";
|
||||
prTitle.setText(HtmlCompat.fromHtml(prNumber_ + " " + EmojiParser.parseToUnicode(prModel.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
String prNumber_ = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + context.getResources().getString(R.string.hash) + pullRequest.getNumber() + "</font>";
|
||||
|
||||
prNumber.setText(String.valueOf(prModel.getNumber()));
|
||||
prMergeable.setText(String.valueOf(prModel.isMergeable()));
|
||||
if(prModel.getHead() != null) {
|
||||
prHeadBranch.setText(prModel.getHead().getRef());
|
||||
if(prModel.getHead().getRepo() != null) {
|
||||
prIsFork.setText(String.valueOf(prModel.getHead().getRepo().isFork()));
|
||||
prForkFullName.setText(prModel.getHead().getRepo().getFull_name());
|
||||
}
|
||||
else {
|
||||
// pull was done from a deleted fork
|
||||
prIsFork.setText("true");
|
||||
prForkFullName.setText(context.getString(R.string.prDeletedFork));
|
||||
}
|
||||
}
|
||||
prCommentsCount.setText(String.valueOf(prModel.getComments()));
|
||||
|
||||
prCreatedTime.setText(TimeHelper.formatTime(prModel.getCreated_at(), new Locale(locale), timeFormat, context));
|
||||
this.prTitle.setText(HtmlCompat.fromHtml(prNumber_ + " " + EmojiParser.parseToUnicode(pullRequest.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
this.prCommentsCount.setText(String.valueOf(pullRequest.getComments()));
|
||||
this.prCreatedTime.setText(TimeHelper.formatTime(pullRequest.getCreated_at(), new Locale(locale), timeFormat, context));
|
||||
|
||||
if(timeFormat.equals("pretty")) {
|
||||
prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(prModel.getCreated_at()), context));
|
||||
this.prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(pullRequest.getCreated_at()), context));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class LoadHolder extends RecyclerView.ViewHolder {
|
||||
|
@ -47,39 +47,35 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapte
|
||||
|
||||
class SearchViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private String userLoginId;
|
||||
private Issues issue;
|
||||
|
||||
private final TextView issueNumber;
|
||||
private final ImageView issueAssigneeAvatar;
|
||||
private final TextView issueTitle;
|
||||
private final TextView issueCreatedTime;
|
||||
private final TextView issueCommentsCount;
|
||||
private final TextView repoFullName;
|
||||
|
||||
private SearchViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
issueNumber = itemView.findViewById(R.id.issueNumber);
|
||||
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
|
||||
issueTitle = itemView.findViewById(R.id.issueTitle);
|
||||
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
|
||||
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
|
||||
repoFullName = itemView.findViewById(R.id.repoFullName);
|
||||
|
||||
issueTitle.setOnClickListener(v -> {
|
||||
|
||||
Context context = v.getContext();
|
||||
|
||||
Intent intent = new Intent(context, IssueDetailActivity.class);
|
||||
intent.putExtra("issueNumber", issueNumber.getText());
|
||||
intent.putExtra("issueNumber", issue.getNumber());
|
||||
|
||||
tinyDb.putString("issueNumber", issueNumber.getText().toString());
|
||||
tinyDb.putString("issueNumber", String.valueOf(issue.getNumber()));
|
||||
tinyDb.putString("issueType", "Issue");
|
||||
|
||||
tinyDb.putString("repoFullName", repoFullName.getText().toString());
|
||||
tinyDb.putString("repoFullName", issue.getRepository().getFull_name());
|
||||
|
||||
String[] parts = repoFullName.getText().toString().split("/");
|
||||
String[] parts = issue.getRepository().getFull_name().split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
@ -104,14 +100,13 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapte
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
issueAssigneeAvatar.setOnClickListener(loginId -> {
|
||||
|
||||
Context context = loginId.getContext();
|
||||
issueAssigneeAvatar.setOnClickListener(v -> {
|
||||
Context context = v.getContext();
|
||||
String userLoginId = issue.getUser().getLogin();
|
||||
|
||||
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -130,17 +125,19 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapte
|
||||
String locale = tinyDb.getString("locale");
|
||||
String timeFormat = tinyDb.getString("dateFormat");
|
||||
|
||||
holder.userLoginId = currentItem.getUser().getLogin();
|
||||
|
||||
PicassoService
|
||||
.getInstance(mCtx).get().load(currentItem.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueAssigneeAvatar);
|
||||
PicassoService.getInstance(mCtx).get()
|
||||
.load(currentItem.getUser().getAvatar_url())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(8, 0))
|
||||
.resize(120, 120)
|
||||
.centerCrop()
|
||||
.into(holder.issueAssigneeAvatar);
|
||||
|
||||
String issueNumber_ = "<font color='" + ResourcesCompat.getColor(mCtx.getResources(), R.color.lightGray, null) + "'>" + currentItem.getRepository().getFull_name() + mCtx.getResources().getString(R.string.hash) + currentItem.getNumber() + "</font>";
|
||||
holder.issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + currentItem.getTitle(), HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
|
||||
holder.issueNumber.setText(String.valueOf(currentItem.getNumber()));
|
||||
holder.issue = currentItem;
|
||||
holder.issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + currentItem.getTitle(), HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
holder.issueCommentsCount.setText(String.valueOf(currentItem.getComments()));
|
||||
holder.repoFullName.setText(currentItem.getRepository().getFull_name());
|
||||
|
||||
switch(timeFormat) {
|
||||
case "pretty": {
|
||||
|
@ -18,7 +18,6 @@ import javax.net.ssl.X509TrustManager;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
import retrofit2.converter.scalars.ScalarsConverterFactory;
|
||||
@ -32,15 +31,12 @@ public class RetrofitClient {
|
||||
private static final Map<String, ApiInterface> apiInterfaces = new ConcurrentHashMap<>();
|
||||
private static final Map<String, WebInterface> webInterfaces = new ConcurrentHashMap<>();
|
||||
|
||||
private static Retrofit createRetrofit(Context context, String instanceUrl) {
|
||||
private static Retrofit createRetrofit(Context context, String instanceUrl, boolean cacheEnabled) {
|
||||
|
||||
TinyDB tinyDB = TinyDB.getInstance(context);
|
||||
|
||||
int cacheSize = FilesData.returnOnlyNumber(tinyDB.getString("cacheSizeStr")) * 1024 * 1024;
|
||||
Cache cache = new Cache(new File(context.getCacheDir(), "responses"), cacheSize);
|
||||
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
// HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
// logging.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
||||
try {
|
||||
|
||||
@ -49,11 +45,17 @@ public class RetrofitClient {
|
||||
MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(context);
|
||||
sslContext.init(null, new X509TrustManager[]{ memorizingTrustManager }, new SecureRandom());
|
||||
|
||||
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder().cache(cache)
|
||||
//.addInterceptor(logging)
|
||||
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder()
|
||||
// .addInterceptor(logging)
|
||||
.sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager)
|
||||
.hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()))
|
||||
.addInterceptor(chain -> {
|
||||
.hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()));
|
||||
|
||||
if(cacheEnabled) {
|
||||
|
||||
int cacheSize = FilesData.returnOnlyNumber(tinyDB.getString("cacheSizeStr")) * 1024 * 1024;
|
||||
Cache cache = new Cache(new File(context.getCacheDir(), "responses"), cacheSize);
|
||||
|
||||
okHttpClient.cache(cache).addInterceptor(chain -> {
|
||||
|
||||
Request request = chain.request();
|
||||
|
||||
@ -64,6 +66,7 @@ public class RetrofitClient {
|
||||
return chain.proceed(request);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return new Retrofit.Builder()
|
||||
.baseUrl(instanceUrl)
|
||||
@ -101,7 +104,7 @@ public class RetrofitClient {
|
||||
synchronized(RetrofitClient.class) {
|
||||
if(!apiInterfaces.containsKey(url)) {
|
||||
|
||||
ApiInterface apiInterface = createRetrofit(context, url).create(ApiInterface.class);
|
||||
ApiInterface apiInterface = createRetrofit(context, url, true).create(ApiInterface.class);
|
||||
apiInterfaces.put(url, apiInterface);
|
||||
|
||||
return apiInterface;
|
||||
@ -119,7 +122,7 @@ public class RetrofitClient {
|
||||
synchronized(RetrofitClient.class) {
|
||||
if(!webInterfaces.containsKey(url)) {
|
||||
|
||||
WebInterface webInterface = createRetrofit(context, url).create(WebInterface.class);
|
||||
WebInterface webInterface = createRetrofit(context, url, false).create(WebInterface.class);
|
||||
webInterfaces.put(url, webInterface);
|
||||
|
||||
return webInterface;
|
||||
|
@ -14,8 +14,8 @@ 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.Constants;
|
||||
import org.mian.gitnex.helpers.FontsOverride;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.notifications.Notifications;
|
||||
|
||||
@ -28,7 +28,9 @@ import org.mian.gitnex.notifications.Notifications;
|
||||
resTitle = R.string.crashTitle,
|
||||
resChannelName = R.string.setCrashReports,
|
||||
resText = R.string.crashMessage)
|
||||
@AcraCore(reportContent = { ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, ReportField.STACK_TRACE })
|
||||
@AcraCore(reportContent = {
|
||||
ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL,
|
||||
ReportField.STACK_TRACE, ReportField.AVAILABLE_MEM_SIZE, ReportField.BRAND })
|
||||
|
||||
public class MainApplication extends Application {
|
||||
|
||||
@ -81,6 +83,7 @@ public class MainApplication extends Application {
|
||||
|
||||
}
|
||||
|
||||
Notifications.createChannels(appCtx);
|
||||
Notifications.startWorker(appCtx);
|
||||
|
||||
}
|
||||
@ -121,7 +124,7 @@ public class MainApplication extends Application {
|
||||
// setting default polling delay
|
||||
if(tinyDB.getInt("pollingDelayMinutes", 0) <= 0) {
|
||||
|
||||
tinyDB.putInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay);
|
||||
tinyDB.putInt("pollingDelayMinutes", Constants.defaultPollingDelay);
|
||||
}
|
||||
|
||||
// disable biometric by default
|
||||
|
@ -7,7 +7,7 @@ import org.mian.gitnex.database.dao.DraftsDao;
|
||||
import org.mian.gitnex.database.db.GitnexDatabase;
|
||||
import org.mian.gitnex.database.models.Draft;
|
||||
import org.mian.gitnex.database.models.DraftWithRepository;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -51,7 +51,7 @@ public class DraftsApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.draftsApi, e.toString());
|
||||
Log.e(Constants.draftsApi, e.toString());
|
||||
}
|
||||
|
||||
return draftId;
|
||||
@ -67,7 +67,7 @@ public class DraftsApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.draftsApi, e.toString());
|
||||
Log.e(Constants.draftsApi, e.toString());
|
||||
}
|
||||
|
||||
return draftId;
|
||||
@ -83,7 +83,7 @@ public class DraftsApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.draftsApi, e.toString());
|
||||
Log.e(Constants.draftsApi, e.toString());
|
||||
}
|
||||
|
||||
return checkDraftFlag;
|
||||
|
@ -6,7 +6,7 @@ import androidx.lifecycle.LiveData;
|
||||
import org.mian.gitnex.database.dao.RepositoriesDao;
|
||||
import org.mian.gitnex.database.db.GitnexDatabase;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -47,7 +47,7 @@ public class RepositoriesApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.repositoriesApi, e.toString());
|
||||
Log.e(Constants.repositoriesApi, e.toString());
|
||||
}
|
||||
|
||||
return repositoryId;
|
||||
@ -63,7 +63,7 @@ public class RepositoriesApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.repositoriesApi, e.toString());
|
||||
Log.e(Constants.repositoriesApi, e.toString());
|
||||
}
|
||||
|
||||
return repository;
|
||||
@ -89,7 +89,7 @@ public class RepositoriesApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.repositoriesApi, e.toString());
|
||||
Log.e(Constants.repositoriesApi, e.toString());
|
||||
}
|
||||
|
||||
return checkRepository;
|
||||
@ -105,7 +105,7 @@ public class RepositoriesApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.repositoriesApi, e.toString());
|
||||
Log.e(Constants.repositoriesApi, e.toString());
|
||||
}
|
||||
|
||||
return repository;
|
||||
@ -121,7 +121,7 @@ public class RepositoriesApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.repositoriesApi, e.toString());
|
||||
Log.e(Constants.repositoriesApi, e.toString());
|
||||
}
|
||||
|
||||
return repository;
|
||||
|
@ -6,7 +6,7 @@ import androidx.lifecycle.LiveData;
|
||||
import org.mian.gitnex.database.dao.UserAccountsDao;
|
||||
import org.mian.gitnex.database.db.GitnexDatabase;
|
||||
import org.mian.gitnex.database.models.UserAccount;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -50,7 +50,7 @@ public class UserAccountsApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.userAccountsApi, e.toString());
|
||||
Log.e(Constants.userAccountsApi, e.toString());
|
||||
}
|
||||
|
||||
return accountId;
|
||||
@ -81,7 +81,7 @@ public class UserAccountsApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.userAccountsApi, e.toString());
|
||||
Log.e(Constants.userAccountsApi, e.toString());
|
||||
}
|
||||
|
||||
return userAccount;
|
||||
@ -97,7 +97,7 @@ public class UserAccountsApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.userAccountsApi, e.toString());
|
||||
Log.e(Constants.userAccountsApi, e.toString());
|
||||
}
|
||||
|
||||
return checkAccount;
|
||||
@ -118,7 +118,7 @@ public class UserAccountsApi {
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
|
||||
Log.e(StaticGlobalVariables.userAccountsApi, e.toString());
|
||||
Log.e(Constants.userAccountsApi, e.toString());
|
||||
}
|
||||
|
||||
return userAccounts;
|
||||
|
@ -10,7 +10,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import org.mian.gitnex.databinding.BottomSheetDraftsBinding;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@ -18,7 +18,7 @@ import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
|
||||
public class BottomSheetDraftsFragment extends BottomSheetDialogFragment {
|
||||
|
||||
private String TAG = StaticGlobalVariables.tagDraftsBottomSheet;
|
||||
private String TAG = Constants.tagDraftsBottomSheet;
|
||||
private BottomSheetDraftsFragment.BottomSheetListener bmListener;
|
||||
|
||||
@Nullable
|
||||
|
@ -25,7 +25,7 @@ import org.mian.gitnex.actions.IssueActions;
|
||||
import org.mian.gitnex.activities.MainActivity;
|
||||
import org.mian.gitnex.database.api.DraftsApi;
|
||||
import org.mian.gitnex.databinding.BottomSheetReplyLayoutBinding;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.util.Objects;
|
||||
@ -266,11 +266,11 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
|
||||
String draftType;
|
||||
if(tinyDB.getString("issueType").equalsIgnoreCase("Issue")) {
|
||||
|
||||
draftType = StaticGlobalVariables.draftTypeIssue;
|
||||
draftType = Constants.draftTypeIssue;
|
||||
}
|
||||
else if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) {
|
||||
|
||||
draftType = StaticGlobalVariables.draftTypePull;
|
||||
draftType = Constants.draftTypePull;
|
||||
}
|
||||
else {
|
||||
|
||||
|
@ -28,8 +28,8 @@ import org.mian.gitnex.databinding.CustomExploreRepositoriesDialogBinding;
|
||||
import org.mian.gitnex.databinding.FragmentExploreRepoBinding;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.InfiniteScrollListener;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
@ -80,7 +80,7 @@ public class ExploreRepositoriesFragment extends Fragment {
|
||||
|
||||
// if gitea is 1.12 or higher use the new limit
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
limit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
limit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ctx);
|
||||
@ -104,7 +104,7 @@ public class ExploreRepositoriesFragment extends Fragment {
|
||||
|
||||
// if gitea is 1.12 or higher use the new limit
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
limit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
limit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
else {
|
||||
limit = 10;
|
||||
@ -134,7 +134,7 @@ public class ExploreRepositoriesFragment extends Fragment {
|
||||
|
||||
// if gitea is 1.12 or higher use the new limit
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
limit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
limit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
else {
|
||||
limit = 10;
|
||||
@ -156,7 +156,7 @@ public class ExploreRepositoriesFragment extends Fragment {
|
||||
int apiCallDefaultLimit = 10;
|
||||
// if gitea is 1.12 or higher use the new limit
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
apiCallDefaultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
apiCallDefaultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
if(apiCallDefaultLimit > limit) {
|
||||
|
@ -11,15 +11,12 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.Files;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.FileViewActivity;
|
||||
import org.mian.gitnex.activities.RepoDetailActivity;
|
||||
@ -31,7 +28,6 @@ import org.mian.gitnex.helpers.Path;
|
||||
import org.mian.gitnex.viewmodels.FilesViewModel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import moe.feng.common.view.breadcrumbs.BreadcrumbsView;
|
||||
import moe.feng.common.view.breadcrumbs.DefaultBreadcrumbsCallback;
|
||||
import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem;
|
||||
|
||||
@ -41,15 +37,11 @@ import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem;
|
||||
|
||||
public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapterListener {
|
||||
|
||||
private ProgressBar mProgressBar;
|
||||
private RecyclerView mRecyclerView;
|
||||
private TextView noDataFiles;
|
||||
private LinearLayout filesFrame;
|
||||
private FragmentFilesBinding binding;
|
||||
|
||||
private static final String repoNameF = "param2";
|
||||
private static final String repoOwnerF = "param1";
|
||||
private static final String repoRefF = "param3";
|
||||
private BreadcrumbsView mBreadcrumbsView;
|
||||
|
||||
private String repoName;
|
||||
private String repoOwner;
|
||||
@ -92,28 +84,21 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
FragmentFilesBinding fragmentFilesBinding = FragmentFilesBinding.inflate(inflater, container, false);
|
||||
binding = FragmentFilesBinding.inflate(inflater, container, false);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
noDataFiles = fragmentFilesBinding.noDataFiles;
|
||||
filesFrame = fragmentFilesBinding.filesFrame;
|
||||
|
||||
filesAdapter = new FilesAdapter(getContext(), this);
|
||||
|
||||
mRecyclerView = fragmentFilesBinding.recyclerView;
|
||||
mRecyclerView.setHasFixedSize(true);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
mRecyclerView.setAdapter(filesAdapter);
|
||||
binding.recyclerView.setHasFixedSize(true);
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
binding.recyclerView.setAdapter(filesAdapter);
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
|
||||
mRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(binding.recyclerView.getContext(), DividerItemDecoration.VERTICAL);
|
||||
binding.recyclerView.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
mProgressBar = fragmentFilesBinding.progressBar;
|
||||
|
||||
mBreadcrumbsView = fragmentFilesBinding.breadcrumbsView;
|
||||
mBreadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref))));
|
||||
binding.breadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref))));
|
||||
// noinspection unchecked
|
||||
mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() {
|
||||
binding.breadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() {
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
@ -140,14 +125,14 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
||||
|
||||
path.clear();
|
||||
ref = repoBranch;
|
||||
mBreadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref))));
|
||||
binding.breadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref))));
|
||||
fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, repoBranch);
|
||||
|
||||
});
|
||||
|
||||
fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref);
|
||||
|
||||
return fragmentFilesBinding.getRoot();
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -157,40 +142,35 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickDir(String dirName) {
|
||||
public void onClickFile(Files file) {
|
||||
|
||||
path.add(dirName);
|
||||
mBreadcrumbsView.addItem(new BreadcrumbItem(Collections.singletonList(dirName)));
|
||||
switch(file.getType()) {
|
||||
|
||||
fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, path.toString(), ref);
|
||||
case "dir":
|
||||
path.add(file.getName());
|
||||
binding.breadcrumbsView.addItem(new BreadcrumbItem(Collections.singletonList(file.getName())));
|
||||
|
||||
}
|
||||
fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, path.toString(), ref);
|
||||
break;
|
||||
|
||||
@Override
|
||||
public void onClickFile(String fileName) {
|
||||
case "file":
|
||||
Intent intent = new Intent(getContext(), FileViewActivity.class);
|
||||
intent.putExtra("file", file);
|
||||
|
||||
Intent intent = new Intent(getContext(), FileViewActivity.class);
|
||||
requireContext().startActivity(intent);
|
||||
break;
|
||||
|
||||
if(path.size() != 0) {
|
||||
|
||||
intent.putExtra("singleFileName", path.toString() + "/" + fileName);
|
||||
}
|
||||
else {
|
||||
|
||||
intent.putExtra("singleFileName", fileName);
|
||||
}
|
||||
|
||||
requireContext().startActivity(intent);
|
||||
}
|
||||
|
||||
private void fetchDataAsync(String instanceToken, String owner, String repo, String ref) {
|
||||
|
||||
mRecyclerView.setVisibility(View.GONE);
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
binding.recyclerView.setVisibility(View.GONE);
|
||||
binding.progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class);
|
||||
|
||||
filesModel.getFilesList(instanceToken, owner, repo, ref, getContext(), mProgressBar, noDataFiles).observe(getViewLifecycleOwner(), filesListMain -> {
|
||||
filesModel.getFilesList(instanceToken, owner, repo, ref, getContext(), binding.progressBar, binding.noDataFiles).observe(getViewLifecycleOwner(), filesListMain -> {
|
||||
|
||||
filesAdapter.getOriginalFiles().clear();
|
||||
filesAdapter.getOriginalFiles().addAll(filesListMain);
|
||||
@ -198,16 +178,16 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
||||
|
||||
if(filesListMain.size() > 0) {
|
||||
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame);
|
||||
noDataFiles.setVisibility(View.GONE);
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, binding.recyclerView, binding.filesFrame);
|
||||
binding.noDataFiles.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
else {
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame, noDataFiles);
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, binding.recyclerView, binding.filesFrame, binding.noDataFiles);
|
||||
}
|
||||
|
||||
filesFrame.setVisibility(View.VISIBLE);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
binding.filesFrame.setVisibility(View.VISIBLE);
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
|
||||
});
|
||||
|
||||
@ -215,12 +195,12 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
||||
|
||||
private void fetchDataAsyncSub(String instanceToken, String owner, String repo, String filesDir, String ref) {
|
||||
|
||||
mRecyclerView.setVisibility(View.GONE);
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
binding.recyclerView.setVisibility(View.GONE);
|
||||
binding.progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class);
|
||||
FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class);
|
||||
|
||||
filesModel2.getFilesList2(instanceToken, owner, repo, filesDir, ref, getContext(), mProgressBar, noDataFiles).observe(this, filesListMain2 -> {
|
||||
filesModel.getFilesList2(instanceToken, owner, repo, filesDir, ref, getContext(), binding.progressBar, binding.noDataFiles).observe(this, filesListMain2 -> {
|
||||
|
||||
filesAdapter.getOriginalFiles().clear();
|
||||
filesAdapter.getOriginalFiles().addAll(filesListMain2);
|
||||
@ -228,15 +208,15 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
||||
|
||||
if(filesListMain2.size() > 0) {
|
||||
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame);
|
||||
noDataFiles.setVisibility(View.GONE);
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, binding.recyclerView, binding.filesFrame);
|
||||
binding.noDataFiles.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame, noDataFiles);
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, binding.recyclerView, binding.filesFrame, binding.noDataFiles);
|
||||
}
|
||||
|
||||
filesFrame.setVisibility(View.VISIBLE);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
binding.filesFrame.setVisibility(View.VISIBLE);
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
|
||||
});
|
||||
|
||||
@ -259,7 +239,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
|
||||
if(mRecyclerView.getAdapter() != null) {
|
||||
if(binding.recyclerView.getAdapter() != null) {
|
||||
filesAdapter.getFilter().filter(newText);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ import org.mian.gitnex.adapters.IssuesAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.FragmentIssuesBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
@ -49,12 +49,12 @@ public class IssuesFragment extends Fragment {
|
||||
private List<Issues> issuesList;
|
||||
private IssuesAdapter adapter;
|
||||
private Context context;
|
||||
private int pageSize = StaticGlobalVariables.issuesPageInit;
|
||||
private int pageSize = Constants.issuesPageInit;
|
||||
private ProgressBar mProgressBar;
|
||||
private String TAG = StaticGlobalVariables.tagIssuesList;
|
||||
private String TAG = Constants.tagIssuesList;
|
||||
private TextView noDataIssues;
|
||||
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
|
||||
private String requestType = StaticGlobalVariables.issuesRequestType;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private String requestType = Constants.issuesRequestType;
|
||||
private ProgressBar progressLoadMore;
|
||||
|
||||
@Nullable
|
||||
@ -78,7 +78,7 @@ public class IssuesFragment extends Fragment {
|
||||
|
||||
// if gitea is 1.12 or higher use the new limit
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
recyclerView = fragmentIssuesBinding.recyclerView;
|
||||
|
@ -23,7 +23,7 @@ import org.mian.gitnex.adapters.MilestonesAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.FragmentMilestonesBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
@ -44,9 +44,9 @@ public class MilestonesFragment extends Fragment {
|
||||
private List<Milestones> dataList;
|
||||
private MilestonesAdapter adapter;
|
||||
private Context ctx;
|
||||
private int pageSize = StaticGlobalVariables.milestonesPageInit;
|
||||
private String TAG = StaticGlobalVariables.tagMilestonesFragment;
|
||||
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
|
||||
private int pageSize = Constants.milestonesPageInit;
|
||||
private String TAG = Constants.tagMilestonesFragment;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
@ -68,7 +68,7 @@ public class MilestonesFragment extends Fragment {
|
||||
|
||||
// if gitea is 1.12 or higher use the new limit
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
dataList = new ArrayList<>();
|
||||
|
@ -29,8 +29,8 @@ import org.mian.gitnex.adapters.NotificationsAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.FragmentNotificationsBinding;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.InfiniteScrollListener;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.io.IOException;
|
||||
@ -83,7 +83,7 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
||||
context = getContext();
|
||||
tinyDB = TinyDB.getInstance(context);
|
||||
|
||||
pageResultLimit = StaticGlobalVariables.getCurrentResultLimit(context);
|
||||
pageResultLimit = Constants.getCurrentResultLimit(context);
|
||||
tinyDB.putString("notificationsFilterState", currentFilterMode);
|
||||
|
||||
markAllAsRead = fragmentNotificationsBinding.markAllAsRead;
|
||||
@ -204,7 +204,7 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
||||
Call<List<NotificationThread>> call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.getNotificationThreads(instanceToken, false, filter,
|
||||
StaticGlobalVariables.defaultOldestTimestamp, "",
|
||||
Constants.defaultOldestTimestamp, "",
|
||||
pageCurrentIndex, pageResultLimit);
|
||||
|
||||
call.enqueue(new Callback<List<NotificationThread>>() {
|
||||
|
@ -30,8 +30,7 @@ import org.mian.gitnex.helpers.ColorInverter;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.util.Locale;
|
||||
import eightbitlab.com.blurview.BlurView;
|
||||
import eightbitlab.com.blurview.RenderScriptBlur;
|
||||
import jp.wasabeef.picasso.transformations.BlurTransformation;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@ -54,7 +53,6 @@ public class ProfileFragment extends Fragment {
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(getContext());
|
||||
|
||||
BlurView blurView = v.findViewById(R.id.blurView);
|
||||
TextView userFullName = v.findViewById(R.id.userFullName);
|
||||
ImageView userAvatarBackground = v.findViewById(R.id.userAvatarBackground);
|
||||
ImageView userAvatar = v.findViewById(R.id.userAvatar);
|
||||
@ -77,10 +75,10 @@ public class ProfileFragment extends Fragment {
|
||||
userLanguage.setText(R.string.notSupported);
|
||||
}
|
||||
|
||||
userAvatar.setOnClickListener(loginId -> {
|
||||
|
||||
AppUtil.copyToClipboard(ctx, tinyDb.getString("userLogin"), ctx.getString(R.string.copyLoginIdToClipBoard, tinyDb.getString("userLogin")));
|
||||
});
|
||||
userAvatar.setOnClickListener(loginId ->
|
||||
AppUtil.copyToClipboard(ctx,
|
||||
tinyDb.getString("userLogin"),
|
||||
ctx.getString(R.string.copyLoginIdToClipBoard, tinyDb.getString("userLogin"))));
|
||||
|
||||
userFullName.setText(Html.fromHtml(tinyDb.getString("userFullname")));
|
||||
userLogin.setText(getString(R.string.usernameWithAt, tinyDb.getString("userLogin")));
|
||||
@ -94,12 +92,12 @@ public class ProfileFragment extends Fragment {
|
||||
|
||||
PicassoService.getInstance(ctx).get()
|
||||
.load(tinyDb.getString("userAvatar"))
|
||||
.transform(new BlurTransformation(ctx))
|
||||
.into(userAvatarBackground, new Callback() {
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
|
||||
int invertedColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground);
|
||||
int invertedColor = new ColorInverter().getImageViewContrastColor(userAvatar);
|
||||
|
||||
userFullName.setTextColor(invertedColor);
|
||||
divider.setBackgroundColor(invertedColor);
|
||||
@ -107,20 +105,11 @@ public class ProfileFragment extends Fragment {
|
||||
userLanguage.setTextColor(invertedColor);
|
||||
|
||||
ImageViewCompat.setImageTintList(userLanguageIcon, ColorStateList.valueOf(invertedColor));
|
||||
|
||||
blurView.setupWith(aboutFrame)
|
||||
.setBlurAlgorithm(new RenderScriptBlur(ctx))
|
||||
.setBlurRadius(3)
|
||||
.setHasFixedTransformationMatrix(true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {}
|
||||
|
||||
@Override public void onError(Exception e) {}
|
||||
});
|
||||
|
||||
|
||||
ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
|
||||
|
||||
ViewPager mViewPager = v.findViewById(R.id.container);
|
||||
@ -181,8 +170,6 @@ public class ProfileFragment extends Fragment {
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
|
||||
Fragment fragment = null;
|
||||
|
||||
switch (position) {
|
||||
|
||||
case 0: // followers
|
||||
@ -196,7 +183,7 @@ public class ProfileFragment extends Fragment {
|
||||
|
||||
}
|
||||
|
||||
return fragment;
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ import org.mian.gitnex.adapters.PullRequestsAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.FragmentPullRequestsBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
@ -49,11 +49,11 @@ public class PullRequestsFragment extends Fragment {
|
||||
private RecyclerView recyclerView;
|
||||
private List<PullRequests> prList;
|
||||
private PullRequestsAdapter adapter;
|
||||
private String TAG = StaticGlobalVariables.tagPullRequestsList;
|
||||
private String TAG = Constants.tagPullRequestsList;
|
||||
private Context context;
|
||||
private int pageSize = StaticGlobalVariables.prPageInit;
|
||||
private int pageSize = Constants.prPageInit;
|
||||
private TextView noData;
|
||||
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private ProgressBar progressLoadMore;
|
||||
|
||||
@Nullable
|
||||
@ -77,7 +77,7 @@ public class PullRequestsFragment extends Fragment {
|
||||
|
||||
// if gitea is 1.12 or higher use the new limit
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
recyclerView = fragmentPullRequestsBinding.recyclerView;
|
||||
|
@ -8,10 +8,7 @@ import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
@ -42,36 +39,18 @@ import retrofit2.Callback;
|
||||
public class RepoInfoFragment extends Fragment {
|
||||
|
||||
private Context ctx;
|
||||
private ProgressBar mProgressBar;
|
||||
private LinearLayout pageContent;
|
||||
private static String repoNameF = "param2";
|
||||
private static String repoOwnerF = "param1";
|
||||
|
||||
private FragmentRepoInfoBinding binding;
|
||||
|
||||
private String repoName;
|
||||
private String repoOwner;
|
||||
private TextView repoMetaName;
|
||||
private TextView repoMetaDescription;
|
||||
private TextView repoMetaStars;
|
||||
private TextView repoMetaPullRequests;
|
||||
private LinearLayout repoMetaPullRequestsFrame;
|
||||
private TextView repoMetaForks;
|
||||
private TextView repoMetaSize;
|
||||
private TextView repoMetaWatchers;
|
||||
private TextView repoMetaCreatedAt;
|
||||
private TextView repoMetaWebsite;
|
||||
private Button repoAdditionalButton;
|
||||
private TextView repoFileContents;
|
||||
private LinearLayout repoMetaFrame;
|
||||
private ImageView repoMetaDataExpandCollapse;
|
||||
private ImageView repoFilenameExpandCollapse;
|
||||
private LinearLayout fileContentsFrameHeader;
|
||||
private LinearLayout fileContentsFrame;
|
||||
|
||||
private OnFragmentInteractionListener mListener;
|
||||
|
||||
public RepoInfoFragment() {
|
||||
|
||||
}
|
||||
public RepoInfoFragment() {}
|
||||
|
||||
public static RepoInfoFragment newInstance(String param1, String param2) {
|
||||
RepoInfoFragment fragment = new RepoInfoFragment();
|
||||
@ -94,44 +73,18 @@ public class RepoInfoFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
FragmentRepoInfoBinding fragmentRepoInfoBinding = FragmentRepoInfoBinding.inflate(inflater, container, false);
|
||||
binding = FragmentRepoInfoBinding.inflate(inflater, container, false);
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(getContext());
|
||||
|
||||
final String locale = tinyDb.getString("locale");
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
ctx = getContext();
|
||||
|
||||
ctx = getActivity();
|
||||
|
||||
pageContent = fragmentRepoInfoBinding.repoInfoLayout;
|
||||
pageContent = binding.repoInfoLayout;
|
||||
pageContent.setVisibility(View.GONE);
|
||||
|
||||
mProgressBar = fragmentRepoInfoBinding.progressBar;
|
||||
repoMetaName = fragmentRepoInfoBinding.repoMetaName;
|
||||
repoMetaDescription = fragmentRepoInfoBinding.repoMetaDescription;
|
||||
repoMetaStars = fragmentRepoInfoBinding.repoMetaStars;
|
||||
repoMetaPullRequests = fragmentRepoInfoBinding.repoMetaPullRequests;
|
||||
repoMetaPullRequestsFrame = fragmentRepoInfoBinding.repoMetaPullRequestsFrame;
|
||||
repoMetaForks = fragmentRepoInfoBinding.repoMetaForks;
|
||||
repoMetaSize = fragmentRepoInfoBinding.repoMetaSize;
|
||||
repoMetaWatchers = fragmentRepoInfoBinding.repoMetaWatchers;
|
||||
repoMetaCreatedAt = fragmentRepoInfoBinding.repoMetaCreatedAt;
|
||||
repoMetaWebsite = fragmentRepoInfoBinding.repoMetaWebsite;
|
||||
repoAdditionalButton = fragmentRepoInfoBinding.repoAdditionalButton;
|
||||
repoFileContents = fragmentRepoInfoBinding.repoFileContents;
|
||||
repoMetaFrame = fragmentRepoInfoBinding.repoMetaFrame;
|
||||
LinearLayout repoMetaFrameHeader = fragmentRepoInfoBinding.repoMetaFrameHeader;
|
||||
repoMetaDataExpandCollapse = fragmentRepoInfoBinding.repoMetaDataExpandCollapse;
|
||||
repoFilenameExpandCollapse = fragmentRepoInfoBinding.repoFilenameExpandCollapse;
|
||||
fileContentsFrameHeader = fragmentRepoInfoBinding.fileContentsFrameHeader;
|
||||
fileContentsFrame = fragmentRepoInfoBinding.fileContentsFrame;
|
||||
LinearLayout repoMetaStarsFrame = fragmentRepoInfoBinding.repoMetaStarsFrame;
|
||||
LinearLayout repoMetaForksFrame = fragmentRepoInfoBinding.repoMetaForksFrame;
|
||||
LinearLayout repoMetaWatchersFrame = fragmentRepoInfoBinding.repoMetaWatchersFrame;
|
||||
binding.repoMetaFrame.setVisibility(View.GONE);
|
||||
|
||||
repoMetaFrame.setVisibility(View.GONE);
|
||||
|
||||
getRepoInfo(Authorization.get(getContext()), repoOwner, repoName, locale, timeFormat);
|
||||
getRepoInfo(Authorization.get(getContext()), repoOwner, repoName, tinyDb.getString("locale"), tinyDb.getString("dateFormat"));
|
||||
getFileContents(Authorization.get(getContext()), repoOwner, repoName, getResources().getString(R.string.defaultFilename));
|
||||
|
||||
if(isExpandViewVisible()) {
|
||||
@ -142,27 +95,26 @@ public class RepoInfoFragment extends Fragment {
|
||||
toggleExpandViewMeta();
|
||||
}
|
||||
|
||||
fileContentsFrameHeader.setOnClickListener(v1 -> toggleExpandView());
|
||||
binding.fileContentsFrameHeader.setOnClickListener(v1 -> toggleExpandView());
|
||||
binding.repoMetaFrameHeader.setOnClickListener(v12 -> toggleExpandViewMeta());
|
||||
|
||||
repoMetaFrameHeader.setOnClickListener(v12 -> toggleExpandViewMeta());
|
||||
|
||||
repoMetaStarsFrame.setOnClickListener(metaStars -> {
|
||||
binding.repoMetaStarsFrame.setOnClickListener(metaStars -> {
|
||||
|
||||
Intent intent = new Intent(ctx, RepoStargazersActivity.class);
|
||||
intent.putExtra("repoFullNameForStars", repoOwner + "/" + repoName);
|
||||
ctx.startActivity(intent);
|
||||
});
|
||||
|
||||
repoMetaWatchersFrame.setOnClickListener(metaWatchers -> {
|
||||
binding.repoMetaWatchersFrame.setOnClickListener(metaWatchers -> {
|
||||
|
||||
Intent intent = new Intent(ctx, RepoWatchersActivity.class);
|
||||
intent.putExtra("repoFullNameForWatchers", repoOwner + "/" + repoName);
|
||||
ctx.startActivity(intent);
|
||||
});
|
||||
|
||||
repoMetaPullRequestsFrame.setOnClickListener(metaPR -> RepoDetailActivity.mViewPager.setCurrentItem(3));
|
||||
binding.repoMetaPullRequestsFrame.setOnClickListener(metaPR -> RepoDetailActivity.mViewPager.setCurrentItem(3));
|
||||
|
||||
return fragmentRepoInfoBinding.getRoot();
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
public void onButtonPressed(Uri uri) {
|
||||
@ -183,42 +135,42 @@ public class RepoInfoFragment extends Fragment {
|
||||
|
||||
private void toggleExpandView() {
|
||||
|
||||
if (repoFileContents.getVisibility() == View.GONE) {
|
||||
repoFilenameExpandCollapse.setImageResource(R.drawable.ic_chevron_up);
|
||||
repoFileContents.setVisibility(View.VISIBLE);
|
||||
if (binding.repoFileContents.getVisibility() == View.GONE) {
|
||||
binding.repoFilenameExpandCollapse.setImageResource(R.drawable.ic_chevron_up);
|
||||
binding.repoFileContents.setVisibility(View.VISIBLE);
|
||||
//Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down);
|
||||
//fileContentsFrame.startAnimation(slide_down);
|
||||
//binding.fileContentsFrame.startAnimation(slide_down);
|
||||
}
|
||||
else {
|
||||
repoFilenameExpandCollapse.setImageResource(R.drawable.ic_chevron_down);
|
||||
repoFileContents.setVisibility(View.GONE);
|
||||
binding.repoFilenameExpandCollapse.setImageResource(R.drawable.ic_chevron_down);
|
||||
binding.repoFileContents.setVisibility(View.GONE);
|
||||
//Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
|
||||
//fileContentsFrame.startAnimation(slide_up);
|
||||
//binding.fileContentsFrame.startAnimation(slide_up);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isExpandViewVisible() {
|
||||
return repoFileContents.getVisibility() == View.VISIBLE;
|
||||
return binding.repoFileContents.getVisibility() == View.VISIBLE;
|
||||
}
|
||||
|
||||
private void toggleExpandViewMeta() {
|
||||
|
||||
if (repoMetaFrame.getVisibility() == View.GONE) {
|
||||
repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_chevron_up);
|
||||
repoMetaFrame.setVisibility(View.VISIBLE);
|
||||
if (binding.repoMetaFrame.getVisibility() == View.GONE) {
|
||||
binding.repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_chevron_up);
|
||||
binding.repoMetaFrame.setVisibility(View.VISIBLE);
|
||||
//Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down);
|
||||
//repoMetaFrame.startAnimation(slide_down);
|
||||
//binding.repoMetaFrame.startAnimation(slide_down);
|
||||
}
|
||||
else {
|
||||
repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_chevron_down);
|
||||
repoMetaFrame.setVisibility(View.GONE);
|
||||
binding.repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_chevron_down);
|
||||
binding.repoMetaFrame.setVisibility(View.GONE);
|
||||
//Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
|
||||
//repoMetaFrame.startAnimation(slide_up);
|
||||
//binding.repoMetaFrame.startAnimation(slide_up);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isExpandViewMetaVisible() {
|
||||
return repoMetaFrame.getVisibility() == View.VISIBLE;
|
||||
return binding.repoMetaFrame.getVisibility() == View.VISIBLE;
|
||||
}
|
||||
|
||||
private void getRepoInfo(String token, final String owner, String repo, final String locale, final String timeFormat) {
|
||||
@ -243,39 +195,39 @@ public class RepoInfoFragment extends Fragment {
|
||||
if (response.code() == 200) {
|
||||
|
||||
assert repoInfo != null;
|
||||
repoMetaName.setText(repoInfo.getName());
|
||||
binding.repoMetaName.setText(repoInfo.getName());
|
||||
|
||||
if(!repoInfo.getDescription().isEmpty()) {
|
||||
repoMetaDescription.setText(repoInfo.getDescription());
|
||||
binding.repoMetaDescription.setText(repoInfo.getDescription());
|
||||
}
|
||||
else {
|
||||
repoMetaDescription.setText(getString(R.string.noDataDescription));
|
||||
binding.repoMetaDescription.setText(getString(R.string.noDataDescription));
|
||||
}
|
||||
|
||||
repoMetaStars.setText(repoInfo.getStars_count());
|
||||
binding.repoMetaStars.setText(repoInfo.getStars_count());
|
||||
|
||||
if(repoInfo.getOpen_pull_count() != null) {
|
||||
repoMetaPullRequests.setText(repoInfo.getOpen_pull_count());
|
||||
binding.repoMetaPullRequests.setText(repoInfo.getOpen_pull_count());
|
||||
}
|
||||
else {
|
||||
repoMetaPullRequestsFrame.setVisibility(View.GONE);
|
||||
binding.repoMetaPullRequestsFrame.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
repoMetaForks.setText(repoInfo.getForks_count());
|
||||
repoMetaWatchers.setText(repoInfo.getWatchers_count());
|
||||
repoMetaSize.setText(FileUtils.byteCountToDisplaySize((int) (repoInfo.getSize() * 1024)));
|
||||
binding.repoMetaForks.setText(repoInfo.getForks_count());
|
||||
binding.repoMetaWatchers.setText(repoInfo.getWatchers_count());
|
||||
binding.repoMetaSize.setText(FileUtils.byteCountToDisplaySize((int) repoInfo.getSize() * 1024));
|
||||
|
||||
repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx));
|
||||
binding.repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx));
|
||||
if(timeFormat.equals("pretty")) {
|
||||
repoMetaCreatedAt.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), ctx));
|
||||
binding.repoMetaCreatedAt.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), ctx));
|
||||
}
|
||||
|
||||
String repoMetaUpdatedAt = TimeHelper.formatTime(repoInfo.getUpdated_at(), new Locale(locale), timeFormat, ctx);
|
||||
|
||||
String website = (repoInfo.getWebsite().isEmpty()) ? getResources().getString(R.string.noDataWebsite) : repoInfo.getWebsite();
|
||||
repoMetaWebsite.setText(website);
|
||||
binding.repoMetaWebsite.setText(website);
|
||||
|
||||
repoAdditionalButton.setOnClickListener(v -> {
|
||||
binding.repoAdditionalButton.setOnClickListener(v -> {
|
||||
|
||||
View view = LayoutInflater.from(ctx).inflate(R.layout.layout_repo_more_info, null);
|
||||
|
||||
@ -334,7 +286,7 @@ public class RepoInfoFragment extends Fragment {
|
||||
|
||||
tinyDb.putString("repoHtmlUrl", repoInfo.getHtml_url());
|
||||
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
pageContent.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
@ -369,39 +321,41 @@ public class RepoInfoFragment extends Fragment {
|
||||
|
||||
if (isAdded()) {
|
||||
|
||||
if (response.code() == 200) {
|
||||
switch(response.code()) {
|
||||
|
||||
new Markdown(ctx, response.body(), repoFileContents);
|
||||
case 200:
|
||||
new Markdown(ctx, response.body(), binding.repoFileContents);
|
||||
break;
|
||||
|
||||
} else if (response.code() == 401) {
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
case 401:
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
break;
|
||||
|
||||
} else if (response.code() == 403) {
|
||||
case 403:
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
break;
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
case 404:
|
||||
binding.fileContentsFrameHeader.setVisibility(View.GONE);
|
||||
binding.fileContentsFrame.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
} else if (response.code() == 404) {
|
||||
|
||||
fileContentsFrameHeader.setVisibility(View.GONE);
|
||||
fileContentsFrame.setVisibility(View.GONE);
|
||||
|
||||
} else {
|
||||
|
||||
Toasty.error(getContext(), getString(R.string.genericError));
|
||||
default:
|
||||
Toasty.error(getContext(), getString(R.string.genericError));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ public class SettingsFragment extends Fragment {
|
||||
fragmentSettingsBinding.aboutAppFrame.setOnClickListener(aboutApp -> requireActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit());
|
||||
|
||||
return fragmentSettingsBinding.getRoot();
|
||||
|
||||
}
|
||||
|
||||
public void rateThisApp() {
|
||||
|
@ -13,15 +13,16 @@ import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.core.content.pm.PackageInfoCompat;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -31,31 +32,38 @@ import java.util.Objects;
|
||||
|
||||
public class AppUtil {
|
||||
|
||||
public enum FileType { IMAGE, DOCUMENT, TEXT, UNKNOWN }
|
||||
public enum FileType { IMAGE, AUDIO, VIDEO, DOCUMENT, TEXT, EXECUTABLE, UNKNOWN }
|
||||
|
||||
private static final HashMap<List<String>, FileType> extensions = new HashMap<>();
|
||||
private static final HashMap<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);
|
||||
extensions.put(new String[]{"jpg", "jpeg", "gif", "png", "ico", "tif", "tiff", "bmp"}, FileType.IMAGE);
|
||||
extensions.put(new String[]{"mp3", "wav", "opus", "flac", "wma", "aac", "m4a", "oga", "mpc", "ogg"}, FileType.AUDIO);
|
||||
extensions.put(new String[]{"mp4", "mkv", "avi", "mov", "wmv", "qt", "mts", "m2ts", "webm", "flv", "ogv", "amv", "mpg", "mpeg", "mpv", "m4v", "3gp", "wmv"}, FileType.VIDEO);
|
||||
extensions.put(new String[]{"doc", "docx", "ppt", "pptx", "xls", "xlsx", "xlsm", "odt", "ott", "odf", "ods", "ots", "odg", "otg", "odp", "otp", "bin", "psd", "xcf", "pdf"}, FileType.DOCUMENT);
|
||||
extensions.put(new String[]{"exe", "msi", "jar", "dmg", "deb", "apk"}, FileType.EXECUTABLE);
|
||||
extensions.put(new String[]{"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", "kt", "kts"}, FileType.TEXT);
|
||||
|
||||
}
|
||||
|
||||
public static FileType getFileType(String extension) {
|
||||
|
||||
for(List<String> e : extensions.keySet()) {
|
||||
if(extension != null && !extension.isEmpty()) {
|
||||
for(String[] testExtensions : extensions.keySet()) {
|
||||
for(String testExtension : testExtensions) {
|
||||
|
||||
if(e.contains(extension)) {
|
||||
|
||||
return extensions.get(e);
|
||||
if(testExtension.equalsIgnoreCase(extension))
|
||||
return extensions.get(testExtensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FileType.UNKNOWN;
|
||||
|
||||
}
|
||||
|
||||
public static boolean hasNetworkConnection(Context context) {
|
||||
@ -63,6 +71,45 @@ public class AppUtil {
|
||||
return NetworkStatusObserver.getInstance(context).hasNetworkConnection();
|
||||
}
|
||||
|
||||
public static void copyProgress(InputStream inputStream, OutputStream outputStream, long totalSize, ProgressListener progressListener) throws IOException {
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int read;
|
||||
|
||||
long totalSteps = (long) Math.ceil((double) totalSize / buffer.length);
|
||||
long stepsPerPercent = (long) Math.floor((double) totalSteps / 100);
|
||||
|
||||
short percent = 0;
|
||||
long stepCount = 0;
|
||||
|
||||
progressListener.onActionStarted();
|
||||
|
||||
while((read = inputStream.read(buffer)) != -1) {
|
||||
|
||||
outputStream.write(buffer, 0, read);
|
||||
stepCount++;
|
||||
|
||||
if(stepCount == stepsPerPercent) {
|
||||
percent++;
|
||||
if(percent <= 100) progressListener.onProgressChanged(percent);
|
||||
stepCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(percent < 100) {
|
||||
progressListener.onProgressChanged((short) 100);
|
||||
}
|
||||
|
||||
progressListener.onActionFinished();
|
||||
}
|
||||
|
||||
public interface ProgressListener {
|
||||
default void onActionStarted() {}
|
||||
default void onActionFinished() {}
|
||||
|
||||
void onProgressChanged(short progress);
|
||||
}
|
||||
|
||||
public static int getAppBuildNo(Context context) {
|
||||
|
||||
try {
|
||||
|
@ -23,4 +23,12 @@ public class Authorization {
|
||||
return "token " + tinyDb.getString(loginUid + "-token");
|
||||
|
||||
}
|
||||
|
||||
public static String getWeb(Context context) {
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
return Credentials.basic("", tinyDb.getString(tinyDb.getString("loginUid") + "-token"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@ -17,45 +18,36 @@ public class ColorInverter {
|
||||
|
||||
double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
|
||||
|
||||
int d;
|
||||
if (a < 0.5) {
|
||||
d = 30; // almost black
|
||||
} else {
|
||||
d = 255; // white
|
||||
}
|
||||
int d = (a < 0.30) ?
|
||||
30 : // almost black
|
||||
255; // white
|
||||
|
||||
return Color.rgb(d, d, d);
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public int getImageViewContrastColor(ImageView imageView) {
|
||||
public int getBitmapContrastColor(@NonNull Bitmap bitmap) {
|
||||
|
||||
if(imageView != null) {
|
||||
int colorSum = 0;
|
||||
int divisionValue = 0;
|
||||
|
||||
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
|
||||
for(int height=0; height<bitmap.getHeight(); height += 10) {
|
||||
for(int width=0; width<bitmap.getWidth(); width += 10) {
|
||||
|
||||
int colorSum = 0;
|
||||
int divisionValue = 0;
|
||||
|
||||
for(int height=0; height<bitmap.getHeight(); height += 10) {
|
||||
|
||||
for(int width=0; width<bitmap.getWidth(); width += 10) {
|
||||
|
||||
colorSum += bitmap.getPixel(width, height);
|
||||
divisionValue++;
|
||||
|
||||
}
|
||||
colorSum += bitmap.getPixel(width, height);
|
||||
divisionValue++;
|
||||
}
|
||||
|
||||
// Calculate average color
|
||||
return getContrastColor(colorSum / divisionValue);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
return Color.rgb(255, 255, 255);
|
||||
}
|
||||
// Calculate average color
|
||||
return getContrastColor(colorSum / divisionValue);
|
||||
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public int getImageViewContrastColor(@NonNull ImageView imageView) {
|
||||
|
||||
return getBitmapContrastColor(((BitmapDrawable) imageView.getDrawable()).getBitmap());
|
||||
}
|
||||
|
||||
}
|
||||
|
61
app/src/main/java/org/mian/gitnex/helpers/Constants.java
Normal file
61
app/src/main/java/org/mian/gitnex/helpers/Constants.java
Normal file
@ -0,0 +1,61 @@
|
||||
package org.mian.gitnex.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class Constants {
|
||||
|
||||
// generic values
|
||||
public static final int resultLimitNewGiteaInstances = 25; // Gitea 1.12 and above
|
||||
public static final int resultLimitOldGiteaInstances = 10; // Gitea 1.11 and below
|
||||
public static final String defaultOldestTimestamp = "1970-01-01T00:00:00+00:00";
|
||||
|
||||
public static int getCurrentResultLimit(Context context) {
|
||||
|
||||
Version version = new Version(TinyDB.getInstance(context).getString("giteaVersion"));
|
||||
return version.higherOrEqual("1.12") ? resultLimitNewGiteaInstances : resultLimitOldGiteaInstances;
|
||||
|
||||
}
|
||||
|
||||
// tags
|
||||
public static final String tagMilestonesFragment = "MilestonesFragment";
|
||||
public static final String tagPullRequestsList = "PullRequestsListFragment";
|
||||
public static final String tagIssuesList = "IssuesListFragment";
|
||||
public static final String tagMilestonesAdapter = "MilestonesAdapter";
|
||||
public static final String draftsApi = "DraftsApi";
|
||||
public static final String repositoriesApi = "RepositoriesApi";
|
||||
public static final String replyToIssueActivity = "ReplyToIssueActivity";
|
||||
public static final String tagDraftsBottomSheet = "BottomSheetDraftsFragment";
|
||||
public static final String userAccountsApi = "UserAccountsApi";
|
||||
|
||||
// issues variables
|
||||
public static final int issuesPageInit = 1;
|
||||
public static final String issuesRequestType = "issues";
|
||||
|
||||
// pull request
|
||||
public static final int prPageInit = 1;
|
||||
|
||||
// milestone
|
||||
public static final int milestonesPageInit = 1;
|
||||
|
||||
// drafts
|
||||
public static final String draftTypeComment = "comment";
|
||||
public static final String draftTypeIssue = "Issue";
|
||||
public static final String draftTypePull = "Pull";
|
||||
|
||||
// polling - notifications
|
||||
public static final int minimumPollingDelay = 1;
|
||||
public static final int defaultPollingDelay = 15;
|
||||
public static final int maximumPollingDelay = 720;
|
||||
|
||||
public static final int maximumFileViewerSize = 3 * 1024 * 1024;
|
||||
|
||||
public static final String mainNotificationChannelId = "main_channel";
|
||||
public static final String downloadNotificationChannelId = "dl_channel";
|
||||
|
||||
public static final String[] fallbackReactions = new String[]{"+1", "-1", "laugh", "hooray", "confused", "heart", "rocket", "eyes"};
|
||||
|
||||
}
|
@ -113,7 +113,7 @@ public class ParseDiff {
|
||||
|
||||
// parse "-1,2 +2,3" and "-1 -3" and so on
|
||||
int oldStart = 0, newStart = 0;
|
||||
String diffPos[] = statsLine.split(" \\+");
|
||||
String[] diffPos = statsLine.split(" \\+");
|
||||
if(diffPos.length == 2) {
|
||||
oldStart = Integer.parseInt(diffPos[0].split(",")[0]);
|
||||
newStart = Integer.parseInt(diffPos[1].split(",")[0]);
|
||||
|
@ -1,53 +0,0 @@
|
||||
package org.mian.gitnex.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public abstract class StaticGlobalVariables {
|
||||
|
||||
// generic values
|
||||
public static int resultLimitNewGiteaInstances = 25; // Gitea 1.12 and above
|
||||
public static int resultLimitOldGiteaInstances = 10; // Gitea 1.11 and below
|
||||
public static String defaultOldestTimestamp = "1970-01-01T00:00:00+00:00";
|
||||
|
||||
public static int getCurrentResultLimit(Context context) {
|
||||
|
||||
Version version = new Version(TinyDB.getInstance(context).getString("giteaVersion"));
|
||||
return version.higherOrEqual("1.12") ? resultLimitNewGiteaInstances : resultLimitOldGiteaInstances;
|
||||
|
||||
}
|
||||
|
||||
// tags
|
||||
public static String tagMilestonesFragment = "MilestonesFragment";
|
||||
public static String tagPullRequestsList = "PullRequestsListFragment";
|
||||
public static String tagIssuesList = "IssuesListFragment";
|
||||
public static String tagMilestonesAdapter = "MilestonesAdapter";
|
||||
public static String draftsApi = "DraftsApi";
|
||||
public static String repositoriesApi = "RepositoriesApi";
|
||||
public static String replyToIssueActivity = "ReplyToIssueActivity";
|
||||
public static String tagDraftsBottomSheet = "BottomSheetDraftsFragment";
|
||||
public static String userAccountsApi = "UserAccountsApi";
|
||||
|
||||
// issues variables
|
||||
public static int issuesPageInit = 1;
|
||||
public static String issuesRequestType = "issues";
|
||||
|
||||
// pull request
|
||||
public static int prPageInit = 1;
|
||||
|
||||
// milestone
|
||||
public static int milestonesPageInit = 1;
|
||||
|
||||
// drafts
|
||||
public static String draftTypeComment = "comment";
|
||||
public static String draftTypeIssue = "Issue";
|
||||
public static String draftTypePull = "Pull";
|
||||
|
||||
// polling - notifications
|
||||
public static int minimumPollingDelay = 1;
|
||||
public static int defaultPollingDelay = 15;
|
||||
public static int maximumPollingDelay = 720;
|
||||
}
|
@ -6,7 +6,6 @@ import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import org.mian.gitnex.helpers.highlightjs.models.Language;
|
||||
import org.mian.gitnex.helpers.highlightjs.models.Theme;
|
||||
import org.mian.gitnex.helpers.highlightjs.utils.SourceUtils;
|
||||
@ -25,6 +24,8 @@ public class HighlightJsView extends WebView {
|
||||
private boolean showLineNumbers = true;
|
||||
private TextWrap textWrap = TextWrap.NO_WRAP;
|
||||
|
||||
private String source = "";
|
||||
|
||||
public HighlightJsView(Context context) {
|
||||
|
||||
super(context);
|
||||
@ -63,11 +64,15 @@ public class HighlightJsView extends WebView {
|
||||
getSettings().setSupportZoom(enable);
|
||||
}
|
||||
|
||||
public void setSource(String source) {
|
||||
public String getContent() {
|
||||
return source;
|
||||
}
|
||||
|
||||
source = (source == null) ? " " : source;
|
||||
public void setContent(String source) {
|
||||
|
||||
String html_content = SourceUtils.generateContent(source, theme.getName(), language.getName(), zoomSupport, showLineNumbers, textWrap);
|
||||
this.source = (source == null) ? "" : source;
|
||||
|
||||
String html_content = SourceUtils.generateContent(this.source, theme.getName(), language.getName(), zoomSupport, showLineNumbers, textWrap);
|
||||
loadDataWithBaseURL("file:///android_asset/", html_content, "text/html", "utf-8", null);
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,17 @@
|
||||
package org.mian.gitnex.notifications;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import androidx.work.Constraints;
|
||||
import androidx.work.ExistingPeriodicWorkPolicy;
|
||||
import androidx.work.NetworkType;
|
||||
import androidx.work.PeriodicWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -20,13 +24,52 @@ public class Notifications {
|
||||
|
||||
private static int notificationsSupported = -1;
|
||||
|
||||
private static void checkVersion(TinyDB tinyDB) {
|
||||
public static int uniqueNotificationId(Context context) {
|
||||
|
||||
String currentVersion = tinyDB.getString("giteaVersion");
|
||||
TinyDB tinyDB = TinyDB.getInstance(context);
|
||||
|
||||
if(tinyDB.getBoolean("loggedInMode") && !currentVersion.isEmpty()) {
|
||||
int previousNotificationId = tinyDB.getInt("previousNotificationId", 0);
|
||||
int nextPreviousNotificationId = previousNotificationId == Integer.MAX_VALUE ? 0 : previousNotificationId + 1;
|
||||
|
||||
tinyDB.putInt("previousNotificationId", nextPreviousNotificationId);
|
||||
return previousNotificationId;
|
||||
|
||||
}
|
||||
|
||||
public static void createChannels(Context context) {
|
||||
|
||||
TinyDB tinyDB = TinyDB.getInstance(context);
|
||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
|
||||
// Delete old notification channels
|
||||
notificationManager.deleteNotificationChannel(context.getPackageName()); // TODO Can be removed in future versions
|
||||
|
||||
// Create new notification channels
|
||||
NotificationChannel mainChannel = new NotificationChannel(Constants.mainNotificationChannelId, context.getString(R.string.mainNotificationChannelName), NotificationManager.IMPORTANCE_DEFAULT);
|
||||
mainChannel.setDescription(context.getString(R.string.mainNotificationChannelDescription));
|
||||
|
||||
if(tinyDB.getBoolean("notificationsEnableVibration", true)) {
|
||||
mainChannel.setVibrationPattern(new long[] { 1000, 1000 });
|
||||
mainChannel.enableVibration(true);
|
||||
} else {
|
||||
mainChannel.enableVibration(false);
|
||||
}
|
||||
|
||||
if(tinyDB.getBoolean("notificationsEnableLights", true)) {
|
||||
mainChannel.setLightColor(tinyDB.getInt("notificationsLightColor", Color.GREEN));
|
||||
mainChannel.enableLights(true);
|
||||
} else {
|
||||
mainChannel.enableLights(false);
|
||||
}
|
||||
|
||||
NotificationChannel downloadChannel = new NotificationChannel(Constants.downloadNotificationChannelId, context.getString(R.string.fileViewerNotificationChannelName), NotificationManager.IMPORTANCE_LOW);
|
||||
downloadChannel.setDescription(context.getString(R.string.fileViewerNotificationChannelDescription));
|
||||
|
||||
notificationManager.createNotificationChannel(mainChannel);
|
||||
notificationManager.createNotificationChannel(downloadChannel);
|
||||
|
||||
notificationsSupported = new Version(currentVersion).higherOrEqual("1.12.3") ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +99,7 @@ public class Notifications {
|
||||
constraints.setRequiresDeviceIdle(false);
|
||||
}
|
||||
|
||||
int pollingDelayMinutes = Math.max(tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay), 15);
|
||||
int pollingDelayMinutes = Math.max(tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay), 15);
|
||||
|
||||
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotificationsWorker.class, pollingDelayMinutes, TimeUnit.MINUTES)
|
||||
.setConstraints(constraints.build())
|
||||
@ -68,4 +111,15 @@ public class Notifications {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkVersion(TinyDB tinyDB) {
|
||||
|
||||
String currentVersion = tinyDB.getString("giteaVersion");
|
||||
|
||||
if(tinyDB.getBoolean("loggedInMode") && !currentVersion.isEmpty()) {
|
||||
|
||||
notificationsSupported = new Version(currentVersion).higherOrEqual("1.12.3") ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,11 @@
|
||||
package org.mian.gitnex.notifications;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.media.RingtoneManager;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
@ -20,7 +16,8 @@ import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.MainActivity;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@ -34,7 +31,6 @@ import retrofit2.Response;
|
||||
public class NotificationsWorker extends Worker {
|
||||
|
||||
private static final int MAXIMUM_NOTIFICATIONS = 100;
|
||||
private static final long[] VIBRATION_PATTERN = new long[]{ 1000, 1000 };
|
||||
|
||||
private final Context context;
|
||||
private final TinyDB tinyDB;
|
||||
@ -45,17 +41,16 @@ public class NotificationsWorker extends Worker {
|
||||
|
||||
this.context = context;
|
||||
this.tinyDB = TinyDB.getInstance(context);
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Result doWork() {
|
||||
|
||||
String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
|
||||
int notificationLoops = tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay) >= 15 ? 1 : Math.min(15 - tinyDB.getInt("pollingDelayMinutes"), 10);
|
||||
|
||||
int notificationLoops = tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay) >= 15 ? 1 : Math.min(15 - tinyDB.getInt("pollingDelayMinutes"), 10);
|
||||
|
||||
for(int i=0; i<notificationLoops; i++) {
|
||||
for(int i = 0; i < notificationLoops; i++) {
|
||||
|
||||
long startPollingTime = System.currentTimeMillis();
|
||||
|
||||
@ -65,7 +60,7 @@ public class NotificationsWorker extends Worker {
|
||||
|
||||
Call<List<NotificationThread>> call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.getNotificationThreads(token, false, new String[]{"unread"}, previousRefreshTimestamp,
|
||||
.getNotificationThreads(Authorization.get(context), false, new String[]{"unread"}, previousRefreshTimestamp,
|
||||
null, 1, MAXIMUM_NOTIFICATIONS);
|
||||
|
||||
Response<List<NotificationThread>> response = call.execute();
|
||||
@ -76,34 +71,24 @@ public class NotificationsWorker extends Worker {
|
||||
|
||||
List<NotificationThread> notificationThreads = response.body();
|
||||
|
||||
if(!notificationThreads.isEmpty()) {
|
||||
|
||||
if(!notificationThreads.isEmpty())
|
||||
sendNotification(notificationThreads);
|
||||
}
|
||||
|
||||
tinyDB.putString("previousRefreshTimestamp", AppUtil.getTimestampFromDate(context, new Date()));
|
||||
}
|
||||
else {
|
||||
|
||||
Log.e("onError", String.valueOf(response.code()));
|
||||
}
|
||||
}
|
||||
catch(Exception e) {
|
||||
|
||||
Log.e("onError", e.toString());
|
||||
}
|
||||
} catch(Exception ignored) {}
|
||||
|
||||
try {
|
||||
|
||||
if(notificationLoops > 1 && i < (notificationLoops - 1)) {
|
||||
|
||||
Thread.sleep(60000 - (System.currentTimeMillis() - startPollingTime));
|
||||
}
|
||||
}
|
||||
catch (InterruptedException ignored) {}
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
|
||||
return Result.success();
|
||||
|
||||
}
|
||||
|
||||
private void sendNotification(List<NotificationThread> notificationThreads) {
|
||||
@ -112,7 +97,6 @@ public class NotificationsWorker extends Worker {
|
||||
PendingIntent pendingIntent = getPendingIntent();
|
||||
|
||||
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
|
||||
attachNotificationChannel(notificationManagerCompat);
|
||||
|
||||
Notification summaryNotification = new NotificationCompat.Builder(context, context.getPackageName())
|
||||
.setContentTitle(context.getString(R.string.newMessages))
|
||||
@ -122,15 +106,13 @@ public class NotificationsWorker extends Worker {
|
||||
.setGroupSummary(true)
|
||||
.setAutoCancel(true)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setChannelId(Constants.mainNotificationChannelId)
|
||||
.build();
|
||||
|
||||
notificationManagerCompat.notify(summaryId, summaryNotification);
|
||||
|
||||
for(NotificationThread notificationThread : notificationThreads) {
|
||||
|
||||
NotificationManagerCompat notificationManagerCompat1 = NotificationManagerCompat.from(context);
|
||||
attachNotificationChannel(notificationManagerCompat1);
|
||||
|
||||
String subjectUrl = notificationThread.getSubject().getUrl();
|
||||
String issueId = context.getResources().getString(R.string.hash) + subjectUrl.substring(subjectUrl.lastIndexOf("/") + 1);
|
||||
String notificationHeader = issueId + " " + notificationThread.getSubject().getTitle() + " " + String.format(context.getResources().getString(R.string.notificationExtraInfo), notificationThread.getRepository().getFull_name(), notificationThread.getSubject().getType());
|
||||
@ -140,49 +122,8 @@ public class NotificationsWorker extends Worker {
|
||||
.setGroup(context.getPackageName())
|
||||
.setContentIntent(pendingIntent);
|
||||
|
||||
pushNotification(notificationManagerCompat1, builder1.build());
|
||||
}
|
||||
}
|
||||
notificationManagerCompat.notify(Notifications.uniqueNotificationId(context), builder1.build());
|
||||
|
||||
private void pushNotification(NotificationManagerCompat notificationManagerCompat, Notification notification) {
|
||||
|
||||
int previousNotificationId = tinyDB.getInt("previousNotificationId", 0);
|
||||
int nextPreviousNotificationId = previousNotificationId > 71951418 ? 0 : previousNotificationId + 1;
|
||||
|
||||
tinyDB.putInt("previousNotificationId", nextPreviousNotificationId);
|
||||
notificationManagerCompat.notify(previousNotificationId, notification);
|
||||
}
|
||||
|
||||
private void attachNotificationChannel(NotificationManagerCompat notificationManagerCompat) {
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
|
||||
NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName(), context.getString(R.string.appName),
|
||||
NotificationManager.IMPORTANCE_DEFAULT);
|
||||
|
||||
notificationChannel.setDescription(context.getString(R.string.notificationChannelDescription));
|
||||
|
||||
if(tinyDB.getBoolean("notificationsEnableVibration", true)) {
|
||||
|
||||
notificationChannel.setVibrationPattern(VIBRATION_PATTERN);
|
||||
notificationChannel.enableVibration(true);
|
||||
}
|
||||
else {
|
||||
|
||||
notificationChannel.enableVibration(false);
|
||||
}
|
||||
|
||||
if(tinyDB.getBoolean("notificationsEnableLights", true)) {
|
||||
|
||||
notificationChannel.setLightColor(tinyDB.getInt("notificationsLightColor", Color.GREEN));
|
||||
notificationChannel.enableLights(true);
|
||||
}
|
||||
else {
|
||||
|
||||
notificationChannel.enableLights(false);
|
||||
}
|
||||
|
||||
notificationManagerCompat.createNotificationChannel(notificationChannel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,6 +134,7 @@ public class NotificationsWorker extends Worker {
|
||||
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
|
||||
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
|
||||
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
||||
.setChannelId(Constants.mainNotificationChannelId)
|
||||
.setAutoCancel(true);
|
||||
|
||||
if(tinyDB.getBoolean("notificationsEnableLights", true)) {
|
||||
@ -201,11 +143,8 @@ public class NotificationsWorker extends Worker {
|
||||
}
|
||||
|
||||
if(tinyDB.getBoolean("notificationsEnableVibration", true)) {
|
||||
|
||||
builder.setVibrate(VIBRATION_PATTERN);
|
||||
}
|
||||
else {
|
||||
|
||||
builder.setVibrate(new long[]{ 1000, 1000 });
|
||||
} else {
|
||||
builder.setVibrate(null);
|
||||
}
|
||||
|
||||
@ -219,5 +158,6 @@ public class NotificationsWorker extends Worker {
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
|
||||
return PendingIntent.getActivity(context, 0, intent, 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@ -222,7 +223,7 @@ public class ReactionSpinner extends HorizontalScrollView {
|
||||
if(response.isSuccessful() && response.body() != null) {
|
||||
allowedReactions.addAll(Arrays.asList(response.body().getAllowed_reactions()));
|
||||
} else {
|
||||
allowedReactions.addAll(Arrays.asList("+1", "-1", "laugh", "hooray", "confused", "heart", "rocket", "eyes"));
|
||||
allowedReactions.addAll(Arrays.asList(Constants.fallbackReactions));
|
||||
}
|
||||
|
||||
return allowedReactions;
|
||||
|
@ -4,10 +4,7 @@
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M22,19a2,2 0,0 1,-2 2H4a2,2 0,0 1,-2 -2V5a2,2 0,0 1,2 -2h5l2,3h9a2,2 0,0 1,2 2z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="?attr/iconsColor"
|
||||
android:strokeLineCap="round"/>
|
||||
android:fillColor="?attr/iconsColor"
|
||||
android:pathData="M3.75,4.5a0.25,0.25 0,0 0,-0.25 0.25v14.5c0,0.138 0.112,0.25 0.25,0.25h16.5a0.25,0.25 0,0 0,0.25 -0.25V7.687a0.25,0.25 0,0 0,-0.25 -0.25h-8.471a1.75,1.75 0,0 1,-1.447 -0.765L8.928,4.61a0.25,0.25 0,0 0,-0.208 -0.11H3.75zM2,4.75C2,3.784 2.784,3 3.75,3h4.971c0.58,0 1.12,0.286 1.447,0.765l1.404,2.063a0.25,0.25 0,0 0,0.207 0.11h8.471c0.966,0 1.75,0.783 1.75,1.75V19.25A1.75,1.75 0,0 1,20.25 21H3.75A1.75,1.75 0,0 1,2 19.25V4.75z"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
@ -4,17 +4,7 @@
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M13,2H6a2,2 0,0 0,-2 2v16a2,2 0,0 0,2 2h12a2,2 0,0 0,2 -2V9z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="?attr/iconsColor"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M13,2l0,7l7,0"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="?attr/iconsColor"
|
||||
android:strokeLineCap="round"/>
|
||||
android:fillColor="?attr/iconsColor"
|
||||
android:pathData="M5,2.5a0.5,0.5 0,0 0,-0.5 0.5v18a0.5,0.5 0,0 0,0.5 0.5h14a0.5,0.5 0,0 0,0.5 -0.5L19.5,8.5h-4a2,2 0,0 1,-2 -2v-4L5,2.5zM15,2.5v4a0.5,0.5 0,0 0,0.5 0.5h4a0.5,0.5 0,0 0,-0.146 -0.336l-4.018,-4.018A0.5,0.5 0,0 0,15 2.5zM3,3a2,2 0,0 1,2 -2h9.982a2,2 0,0 1,1.414 0.586l4.018,4.018A2,2 0,0 1,21 7.018L21,21a2,2 0,0 1,-2 2L5,23a2,2 0,0 1,-2 -2L3,3z"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
@ -4,24 +4,10 @@
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="?attr/iconsColor"
|
||||
android:strokeLineCap="round"/>
|
||||
android:fillColor="?attr/iconsColor"
|
||||
android:pathData="M10.97,8.265a1.45,1.45 0,0 0,-0.487 0.57,0.75 0.75,0 0,1 -1.341,-0.67c0.2,-0.402 0.513,-0.826 0.997,-1.148C10.627,6.69 11.244,6.5 12,6.5c0.658,0 1.369,0.195 1.934,0.619a2.45,2.45 0,0 1,1.004 2.006c0,1.033 -0.513,1.72 -1.027,2.215 -0.19,0.183 -0.399,0.358 -0.579,0.508l-0.147,0.123a4.329,4.329 0,0 0,-0.435 0.409v1.37a0.75,0.75 0,1 1,-1.5 0v-1.473c0,-0.237 0.067,-0.504 0.247,-0.736 0.22,-0.28 0.486,-0.517 0.718,-0.714l0.183,-0.153 0.001,-0.001c0.172,-0.143 0.324,-0.27 0.47,-0.412 0.368,-0.355 0.569,-0.676 0.569,-1.136a0.953,0.953 0,0 0,-0.404 -0.806C12.766,8.118 12.384,8 12,8c-0.494,0 -0.814,0.121 -1.03,0.265zM13,17a1,1 0,1 1,-2 0,1 1,0 0,1 2,0z"/>
|
||||
<path
|
||||
android:pathData="M9.09,9a3,3 0,0 1,5.83 1c0,2 -3,3 -3,3"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="?attr/iconsColor"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M12,17L12.01,17"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="?attr/iconsColor"
|
||||
android:strokeLineCap="round"/>
|
||||
android:fillColor="?attr/iconsColor"
|
||||
android:pathData="M12,1C5.925,1 1,5.925 1,12s4.925,11 11,11 11,-4.925 11,-11S18.075,1 12,1zM2.5,12a9.5,9.5 0,1 1,19 0,9.5 9.5,0 0,1 -19,0z"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
10
app/src/main/res/drawable/ic_submodule.xml
Normal file
10
app/src/main/res/drawable/ic_submodule.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?attr/iconsColor"
|
||||
android:pathData="M2,4.75C2,3.784 2.784,3 3.75,3h4.965a1.75,1.75 0,0 1,1.456 0.78l1.406,2.109a0.25,0.25 0,0 0,0.208 0.111h8.465c0.966,0 1.75,0.784 1.75,1.75v11.5A1.75,1.75 0,0 1,20.25 21L3.75,21A1.75,1.75 0,0 1,2 19.25L2,4.75zM14.78,9.72a0.75,0.75 0,1 0,-1.06 1.06l1.72,1.72L6.75,12.5a0.75,0.75 0,0 0,0 1.5h8.69l-1.72,1.72a0.75,0.75 0,1 0,1.06 1.06l3,-3a0.75,0.75 0,0 0,0 -1.06l-3,-3z"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_symlink.xml
Normal file
10
app/src/main/res/drawable/ic_symlink.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?attr/iconsColor"
|
||||
android:pathData="M3,3a2,2 0,0 1,2 -2h9.982a2,2 0,0 1,1.414 0.586l4.018,4.018A2,2 0,0 1,21 7.018L21,21a2,2 0,0 1,-2 2L4.75,23a0.75,0.75 0,0 1,0 -1.5L19,21.5a0.5,0.5 0,0 0,0.5 -0.5L19.5,8.5h-4a2,2 0,0 1,-2 -2v-4L5,2.5a0.5,0.5 0,0 0,-0.5 0.5v6.25a0.75,0.75 0,0 1,-1.5 0L3,3zM15,2.5v4a0.5,0.5 0,0 0,0.5 0.5h4a0.5,0.5 0,0 0,-0.146 -0.336l-4.018,-4.018A0.5,0.5 0,0 0,15 2.5zM9.308,14.5l-2.104,-2.236a0.75,0.75 0,1 1,1.092 -1.028l3.294,3.5a0.75,0.75 0,0 1,0 1.028l-3.294,3.5a0.75,0.75 0,1 1,-1.092 -1.028L9.308,16L4.09,16a2.59,2.59 0,0 0,-2.59 2.59v3.16a0.75,0.75 0,0 1,-1.5 0v-3.16a4.09,4.09 0,0 1,4.09 -4.09h5.218z"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
@ -64,20 +64,21 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/singleFileContentsFrame"
|
||||
android:id="@+id/markdownFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:orientation="vertical">
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/singleFileContents"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp"
|
||||
android:textIsSelectable="true" />
|
||||
<TextView
|
||||
android:id="@+id/markdown"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -86,7 +87,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.github.barteksc.pdfviewer.PDFView
|
||||
android:id="@+id/pdfView"
|
||||
@ -97,14 +99,14 @@
|
||||
</LinearLayout>
|
||||
|
||||
<org.mian.gitnex.helpers.highlightjs.HighlightJsView
|
||||
android:id="@+id/singleCodeContents"
|
||||
android:id="@+id/contents"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.github.chrisbanes.photoview.PhotoView
|
||||
android:id="@+id/imageView"
|
||||
android:id="@+id/photo_view"
|
||||
android:visibility="gone"
|
||||
android:padding="16dp"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -69,7 +69,6 @@
|
||||
android:textSize="14sp"
|
||||
android:layout_marginStart="44dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:text="@string/settingsFileViewerSourceCodeSelectedText"
|
||||
android:textColor="?attr/selectedTextColor"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -46,10 +46,11 @@
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progress_bar"
|
||||
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/filesFrame"
|
||||
android:indeterminate="true"
|
||||
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
|
||||
app:indicatorColor="?attr/progressIndicatorColor" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -21,80 +21,72 @@
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<eightbitlab.com.blurview.BlurView
|
||||
android:id="@+id/blurView"
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutFrameAccount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:blurOverlayColor="@color/blurColor">
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/userAvatar"
|
||||
android:layout_width="54dp"
|
||||
android:layout_height="54dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
android:src="@mipmap/app_logo_round" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userFullName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userLogin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@color/colorWhite" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutFrameAccount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/userAvatar"
|
||||
android:layout_width="54dp"
|
||||
android:layout_height="54dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:id="@+id/userLanguageIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
android:src="@mipmap/app_logo_round" />
|
||||
android:src="@drawable/ic_language"
|
||||
app:tint="@color/colorWhite" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userFullName"
|
||||
android:id="@+id/userLanguage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userLogin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@color/colorWhite" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/userLanguageIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
android:src="@drawable/ic_language"
|
||||
app:tint="@color/colorWhite" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userLanguage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</eightbitlab.com.blurview.BlurView>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
61
app/src/main/res/layout/layout_last_commit.xml
Normal file
61
app/src/main/res/layout/layout_last_commit.xml
Normal file
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingRight="15dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/commiter_avatar"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/commit_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="2"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textStyle="bold"
|
||||
tools:text="Voluptatem vero ad quia voluptatum quisquam. Nihil earum et praesentium." />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/commit_sha"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:singleLine="true"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
app:drawableStartCompat="@drawable/ic_commit"
|
||||
app:drawableTint="?attr/primaryTextColor"
|
||||
tools:text="afcfb7c15a" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dividerColor" />
|
||||
|
||||
</LinearLayout>
|
@ -4,102 +4,83 @@
|
||||
android:id="@+id/relativeLayoutFrameIssuesList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_margin="15dp"
|
||||
android:orientation="vertical"
|
||||
android:background="?attr/primaryBackgroundColor">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/issueNumber"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible" />
|
||||
<ImageView
|
||||
android:id="@+id/assigneeAvatar"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
android:src="@drawable/ic_android" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/repoFullName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/mainFrame"
|
||||
<LinearLayout
|
||||
android:id="@+id/infoSection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_margin="15dp"
|
||||
android:layout_toEndOf="@+id/assigneeAvatar"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/assigneeAvatar"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
android:src="@drawable/ic_android" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/infoSection"
|
||||
android:id="@+id/frameIssueNameStatus"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@+id/assigneeAvatar"
|
||||
android:orientation="vertical">
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/issueTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top|center_vertical"
|
||||
android:textAlignment="gravity"
|
||||
android:text="@string/strFilter"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameCreatedDate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameIssueNameStatus"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/frameCommentsCount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/issueTitle"
|
||||
android:id="@+id/issueCommentsCount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top|center_vertical"
|
||||
android:textAlignment="gravity"
|
||||
android:text="@string/strFilter"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameCreatedDate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameCommentsCount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/issueCommentsCount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:drawablePadding="5dp"
|
||||
app:drawableStartCompat="@drawable/ic_comment"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/issueCreatedTime"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:gravity="start"
|
||||
android:drawablePadding="5dp"
|
||||
app:drawableStartCompat="@drawable/ic_comment"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/issueCreatedTime"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -5,119 +5,82 @@
|
||||
android:id="@+id/relativeLayoutFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_margin="15dp"
|
||||
android:orientation="vertical"
|
||||
android:background="?attr/primaryBackgroundColor">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prNumber"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"/>
|
||||
<ImageView
|
||||
android:id="@+id/assigneeAvatar"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
android:src="@drawable/ic_android" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prMergeable"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prHeadBranch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prIsFork"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prForkFullName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/mainFrame"
|
||||
<LinearLayout
|
||||
android:id="@+id/infoSection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_margin="15dp"
|
||||
android:layout_toEndOf="@+id/assigneeAvatar"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/assigneeAvatar"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
android:src="@drawable/ic_android" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/infoSection"
|
||||
android:id="@+id/framePrNameStatus"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@+id/assigneeAvatar"
|
||||
android:orientation="vertical">
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/framePrNameStatus"
|
||||
android:layout_width="match_parent"
|
||||
<TextView
|
||||
android:id="@+id/prTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top|center_vertical"
|
||||
android:textAlignment="gravity"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameCreatedDate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameCommentsCount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prCommentsCount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:drawablePadding="5dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp"
|
||||
app:drawableStartCompat="@drawable/ic_comment" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prCreatedTime"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
android:gravity="top|center_vertical"
|
||||
android:textAlignment="gravity"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/frameCreatedDate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameCommentsCount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prCommentsCount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:drawablePadding="5dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp"
|
||||
app:drawableStartCompat="@drawable/ic_comment" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/prCreatedTime"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/navHeaderFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp">
|
||||
@ -10,106 +11,79 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
android:scaleType="centerCrop" />
|
||||
android:scaleType="centerCrop"
|
||||
tools:srcCompat="@tools:sample/backgrounds/scenic" />
|
||||
|
||||
<eightbitlab.com.blurview.BlurView
|
||||
android:id="@+id/blurView"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:blurOverlayColor="@color/blurColor">
|
||||
android:gravity="bottom"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="20dp">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="bottom"
|
||||
android:paddingTop="16dp">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/userAvatar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxHeight="24dp"
|
||||
android:maxWidth="24dp"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:contentDescription="@string/generalImgContentText"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:paddingEnd="25dp"
|
||||
android:paddingStart="15dp"
|
||||
android:paddingTop="6dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/navRecyclerViewUserAccounts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:reverseLayout="true"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
<ImageView
|
||||
android:id="@+id/userAvatar"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/navRecyclerViewUserAccounts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="5dp"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight=".82"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="5dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userFullname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="10dp"
|
||||
android:textSize="18sp"
|
||||
android:textIsSelectable="true"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="5dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userEmail"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textIsSelectable="true"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:gravity="start"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="5dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="?attr/dividerColor" />
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:reverseLayout="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</eightbitlab.com.blurview.BlurView>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userFullname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="18sp"
|
||||
tools:text="Test user" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userEmail"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="start"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="14sp"
|
||||
tools:text="example@example.com" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="?attr/dividerColor" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -578,7 +578,7 @@
|
||||
<string name="downloadFile">Download This File</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 is not supported in file viewer. Download it instead from the three dotted menu?</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="deleteFileText">Delete %1$s</string>
|
||||
@ -674,7 +674,8 @@
|
||||
<string name="chooseColorSelectorHeader">Choose Color</string>
|
||||
<string name="newMessages">New messages</string>
|
||||
<string name="youHaveGotNewNotifications">You\'ve got %d new notifications.</string>
|
||||
<string name="notificationChannelDescription" translatable="false">This is the main notification channel of GitNex.</string>
|
||||
<string name="mainNotificationChannelName">Notifications</string>
|
||||
<string name="mainNotificationChannelDescription">This is the main notification channel of GitNex.</string>
|
||||
<string name="notificationExtraInfo" translatable="false">- %s (%s)</string>
|
||||
|
||||
<string name="isRead">Read</string>
|
||||
@ -742,4 +743,15 @@
|
||||
|
||||
<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>
|
||||
|
||||
</resources>
|
||||
|
@ -7,7 +7,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.2'
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user