Implementing BottomSheetFragment for commenting on issues and pull requests. (#555)

change to server error on onFailure

Fix keyboard move issue

Fix statusbar color, remove social, enhance other things

Merge branch 'master' into bottomsheet-issue-comments

Merge branch 'master' of https://codeberg.org/gitnex/GitNex into bottomsheet-issue-comments

 Conflicts:
	app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java

Making it work.

Merge branch 'master' of https://codeberg.org/gitnex/GitNex into bottomsheet-issue-comments

Merge branch 'master' of https://codeberg.org/gitnex/GitNex into bottomsheet-issue-comments

Merge branch 'master' of https://codeberg.org/gitnex/GitNex into bottomsheet-issue-comments

First major changes.

Merge branch 'master' of https://codeberg.org/gitnex/GitNex into bottomsheet-issue-comments

Cleanup.

Simplifying title.

Adding BottomSheetFragment layout for future changes.

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: opyale <opyale@noreply.gitea.io>
Co-authored-by: opyale <example@example.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/555
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
This commit is contained in:
opyale 2020-10-12 20:11:23 +02:00 committed by M M Arif
parent d346d68b4f
commit cafb29f8b7
39 changed files with 697 additions and 318 deletions

View File

@ -0,0 +1,80 @@
package org.mian.gitnex.actions;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* @author opyale
*/
public class ActionResult<R> {
public enum Status { SUCCESS, FAILED }
private final BlockingQueue<Boolean> blockingQueue;
private final List<OnFinishedListener<R>> onFinishedListeners;
private boolean invalidated = false;
public ActionResult() {
blockingQueue = new ArrayBlockingQueue<>(1);
onFinishedListeners = new ArrayList<>();
}
public void finish(@NonNull Status status) {
finish(status, null);
}
public void finish(@NonNull Status status, R result) {
try {
if(blockingQueue.poll(5, TimeUnit.SECONDS)) {
for(OnFinishedListener<R> onFinishedListener : onFinishedListeners)
onFinishedListener.onFinished(status, result);
}
} catch (InterruptedException ignored) {}
}
public void invalidate() {
if(invalidated) throw new IllegalStateException("Already invalidated");
this.invalidated = true;
}
@SafeVarargs
public synchronized final void accept(@NonNull OnFinishedListener<R>... onFinishedListeners) {
invalidate();
this.blockingQueue.add(true);
this.onFinishedListeners.addAll(Arrays.asList(onFinishedListeners));
}
public synchronized final void discard() {
invalidate();
this.blockingQueue.add(false);
}
public static class None {}
public interface OnFinishedListener<R> {
void onFinished(Status status, R result);
}
}

View File

@ -12,8 +12,10 @@ import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Permission;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
@ -154,8 +156,55 @@ public class CollaboratorActions {
public void onFailure(@NonNull Call<Permission> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
public static ActionResult<List<Collaborators>> getCollaborators(Context context) {
ActionResult<List<Collaborators>> actionResult = new ActionResult<>();
TinyDB tinyDb = new TinyDB(context);
String instanceUrl = tinyDb.getString("instanceUrl");
String loginUid = tinyDb.getString("loginUid");
String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoOwner = parts[0];
String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, context)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@Override
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
if (response.isSuccessful()) {
assert response.body() != null;
actionResult.finish(ActionResult.Status.SUCCESS, response.body());
}
else {
actionResult.finish(ActionResult.Status.FAILED);
}
}
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
actionResult.finish(ActionResult.Status.FAILED);
}
});
return actionResult;
}
}

View File

@ -1,11 +1,9 @@
package org.mian.gitnex.actions;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.helpers.AlertDialogs;
@ -13,6 +11,7 @@ import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.IssueComments;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.models.UpdateIssueState;
import retrofit2.Call;
import retrofit2.Callback;
@ -53,8 +52,6 @@ public class IssueActions {
DraftsApi draftsApi = new DraftsApi(ctx);
draftsApi.deleteSingleDraft((int) draftIdOnCreate);
((ReplyToIssueActivity) ctx).finish();
}
}
else if(response.code() == 401) {
@ -83,7 +80,7 @@ public class IssueActions {
@Override
public void onFailure(@NonNull Call<IssueComments> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
}
});
@ -157,7 +154,7 @@ public class IssueActions {
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
}
});
@ -217,7 +214,7 @@ public class IssueActions {
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.success(ctx, ctx.getString(R.string.unsubscribedSuccessfully));
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
}
});
@ -277,9 +274,69 @@ public class IssueActions {
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getString(R.string.unsubscriptionError));
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
}
});
}
public static ActionResult<ActionResult.None> reply(Context context, String comment, int issueIndex) {
ActionResult<ActionResult.None> actionResult = new ActionResult<>();
TinyDB tinyDb = new TinyDB(context);
String instanceUrl = tinyDb.getString("instanceUrl");
String loginUid = tinyDb.getString("loginUid");
String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoOwner = parts[0];
String repoName = parts[1];
Issues issueComment = new Issues(comment);
Call<Issues> call = RetrofitClient
.getInstance(instanceUrl, context)
.getApiInterface()
.replyCommentToIssue(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueComment);
call.enqueue(new Callback<Issues>() {
@Override
public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
if(response.code() == 201) {
actionResult.finish(ActionResult.Status.SUCCESS);
tinyDb.putBoolean("commentPosted", true);
tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("resumePullRequests", true);
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(context, context.getString(R.string.alertDialogTokenRevokedTitle),
context.getString(R.string.alertDialogTokenRevokedMessage),
context.getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
context.getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
actionResult.finish(ActionResult.Status.FAILED);
}
}
@Override
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
}
});
return actionResult;
}
}

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@ -75,7 +76,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
AdminGetUsersViewModel.loadUsersList(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
@ -116,7 +117,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
new Handler().postDelayed(() -> {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if(searchFilter) {

View File

@ -17,7 +17,9 @@ import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.notifications.NotificationsMaster;
import static org.acra.ReportField.*;
import static org.acra.ReportField.ANDROID_VERSION;
import static org.acra.ReportField.PHONE_MODEL;
import static org.acra.ReportField.STACK_TRACE;
/**
* Author M M Arif
@ -145,7 +147,6 @@ public abstract class BaseActivity extends AppCompatActivity {
ACRA.init(getApplication(), ACRABuilder);
}
}
protected abstract int getLayoutResourceId();

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Menu;
@ -101,7 +102,7 @@ public class CommitsActivity extends BaseActivity {
recyclerView = findViewById(R.id.recyclerView);
commitsList = new ArrayList<>();
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName, resultLimit);

View File

@ -122,7 +122,7 @@ public class FileDiffActivity extends BaseActivity {
toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount)));
}
FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, fileContentsArray);
FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, getSupportFragmentManager(), fileContentsArray);
mListView.setAdapter(adapter);
mProgressBar.setVisibility(View.GONE);

View File

@ -2,7 +2,6 @@ package org.mian.gitnex.activities;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
@ -43,6 +42,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityIssueDetailBinding;
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.fragments.BottomSheetSingleIssueFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
@ -162,7 +162,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(viewBinding.recyclerView.getContext(), DividerItemDecoration.VERTICAL);
viewBinding.recyclerView.addItemDecoration(dividerItemDecoration);
viewBinding.addNewComment.setOnClickListener(v -> startActivity(new Intent(ctx, ReplyToIssueActivity.class)));
viewBinding.addNewComment.setOnClickListener(v -> BottomSheetReplyFragment.newInstance(new Bundle()).show(getSupportFragmentManager(), "replyBottomSheet"));
labelsAdapter = new LabelsListAdapter(labelsList, IssueDetailActivity.this, currentLabelsIds);
assigneesAdapter = new AssigneesListAdapter(ctx, assigneesList, IssueDetailActivity.this, currentAssignees);
@ -542,7 +542,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.divider.setVisibility(View.VISIBLE);
}
adapter = new IssueCommentsAdapter(ctx, issueCommentsMain);
adapter = new IssueCommentsAdapter(ctx, getSupportFragmentManager(), issueCommentsMain);
viewBinding.recyclerView.setAdapter(adapter);
});

View File

@ -218,7 +218,6 @@ public class ReplyToIssueActivity extends BaseActivity {
DraftsApi.updateDraft(draftText, (int) draftIdOnCreate, commentId); //updateDraftByIssueIdAsyncTask(draftText, issueNumber, repositoryId, commentId);
}
}
private long returnDraftId(String draftText) {

View File

@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Menu;
@ -106,7 +107,7 @@ public class RepoForksActivity extends BaseActivity {
DividerItemDecoration.VERTICAL);
recyclerView.addItemDecoration(dividerItemDecoration);
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
loadInitial(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, pageSize, resultLimit);

View File

@ -12,8 +12,6 @@ import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FilesData;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
@ -21,7 +19,6 @@ import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.notifications.NotificationsMaster;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
/**
* Author M M Arif
@ -99,10 +96,7 @@ public class SettingsSecurityActivity extends BaseActivity {
// clear cache setter
File cacheDir = appCtx.getCacheDir();
long size__ = FilesData.getFileSizeRecursively(new HashSet<>(), cacheDir);
if(size__ > 0) {
clearCacheSelected.setText(String.valueOf(AppUtil.formatFileSizeInDetail(size__)));
}
clearCacheSelected.setText(FileUtils.byteCountToDisplaySize((int) FileUtils.sizeOfDirectory(cacheDir)));
// clear cache
clearCacheFrame.setOnClickListener(v1 -> {

View File

@ -2,7 +2,7 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import android.view.LayoutInflater;
@ -11,11 +11,12 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.database.models.DraftWithRepository;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.List;
@ -27,6 +28,7 @@ import java.util.List;
public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsViewHolder> {
private List<DraftWithRepository> draftsList;
private FragmentManager fragmentManager;
private Context mCtx;
class DraftsViewHolder extends RecyclerView.ViewHolder {
@ -69,16 +71,17 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
itemView.setOnClickListener(itemEdit -> {
Intent intent = new Intent(mCtx, ReplyToIssueActivity.class);
intent.putExtra("commentBody", draftText.getText().toString());
intent.putExtra("issueNumber", issueNumber.getText().toString());
intent.putExtra("repositoryId", repoId.getText().toString());
intent.putExtra("draftTitle", repoInfo.getText().toString());
intent.putExtra("commentId", commentId.getText().toString());
intent.putExtra("draftId", draftId.getText().toString());
Bundle bundle = new Bundle();
if(!commentId.getText().toString().equalsIgnoreCase("")) {
intent.putExtra("commentAction", "edit");
bundle.putString("commentBody", draftText.getText().toString());
bundle.putString("issueNumber", issueNumber.getText().toString());
bundle.putString("repositoryId", repoId.getText().toString());
bundle.putString("draftTitle", repoInfo.getText().toString());
bundle.putString("commentId", commentId.getText().toString());
bundle.putString("draftId", draftId.getText().toString());
if(!commentId.getText().toString().isEmpty()) {
bundle.putString("commentAction", "edit");
}
TinyDB tinyDb = new TinyDB(mCtx);
@ -86,7 +89,7 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
tinyDb.putLong("repositoryId", Long.parseLong(repoId.getText().toString()));
//tinyDb.putString("issueType", issueType.getText().toString());
mCtx.startActivity(intent);
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
});
@ -94,8 +97,9 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
}
public DraftsAdapter(Context mCtx, List<DraftWithRepository> draftsListMain) {
public DraftsAdapter(Context mCtx, FragmentManager fragmentManager, List<DraftWithRepository> draftsListMain) {
this.mCtx = mCtx;
this.fragmentManager = fragmentManager;
this.draftsList = draftsListMain;
}

View File

@ -10,8 +10,8 @@ import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Files;
import java.util.ArrayList;
@ -165,7 +165,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
holder.dirTypeImage.setVisibility(View.GONE);
holder.unknownTypeImage.setVisibility(View.GONE);
holder.fileInfo.setVisibility(View.VISIBLE);
holder.fileInfo.setText(AppUtil.formatFileSizeInDetail(currentItem.getSize()));
holder.fileInfo.setText(FileUtils.byteCountToDisplaySize(currentItem.getSize()));
}
else if(currentItem.getType().equals("dir")) {
holder.dirTypeImage.setVisibility(View.VISIBLE);

View File

@ -2,8 +2,8 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
@ -12,8 +12,9 @@ import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.fragment.app.FragmentManager;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.helpers.DiffTextView;
import org.mian.gitnex.models.FileDiffView;
import java.util.List;
@ -36,11 +37,13 @@ public class FilesDiffAdapter extends BaseAdapter {
private static int COLOR_FONT;
private Context context;
private FragmentManager fragmentManager;
private List<FileDiffView> fileDiffViews;
public FilesDiffAdapter(Context context, List<FileDiffView> fileDiffViews) {
public FilesDiffAdapter(Context context, FragmentManager fragmentManager, List<FileDiffView> fileDiffViews) {
this.context = context;
this.fragmentManager = fragmentManager;
this.fileDiffViews = fileDiffViews;
selectedViews = new ConcurrentSkipListMap<>();
@ -201,12 +204,11 @@ public class FilesDiffAdapter extends BaseAdapter {
selectedViews.clear();
Intent intent = new Intent(context, ReplyToIssueActivity.class);
intent.putExtra("commentBody", stringBuilder.toString());
intent.putExtra("cursorToEnd", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle bundle = new Bundle();
bundle.putString("commentBody", stringBuilder.toString());
bundle.putBoolean("cursorToEnd", true);
context.startActivity(intent);
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
}

View File

@ -7,6 +7,7 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.View;
@ -14,14 +15,15 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.gson.JsonElement;
import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
@ -60,11 +62,13 @@ import retrofit2.Callback;
public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdapter.IssueCommentViewHolder> {
private List<IssueComments> issuesComments;
private FragmentManager fragmentManager;
private Context mCtx;
public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) {
public IssueCommentsAdapter(Context mCtx, FragmentManager fragmentManager, List<IssueComments> issuesCommentsMain) {
this.mCtx = mCtx;
this.fragmentManager = fragmentManager;
this.issuesComments = issuesCommentsMain;
}
@ -126,11 +130,12 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
commentMenuEdit.setOnClickListener(ediComment -> {
Intent intent = new Intent(ctx, ReplyToIssueActivity.class);
intent.putExtra("commentId", commendId.getText());
intent.putExtra("commentAction", "edit");
intent.putExtra("commentBody", commendBodyRaw.getText());
ctx.startActivity(intent);
Bundle bundle = new Bundle();
bundle.putString("commentId", commendId.getText().toString());
bundle.putString("commentAction", "edit");
bundle.putString("commentBody", commendBodyRaw.getText().toString());
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
dialog.dismiss();
});
@ -187,13 +192,12 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
stringBuilder.append("\n");
Intent intent = new Intent(ctx, ReplyToIssueActivity.class);
intent.putExtra("commentBody", stringBuilder.toString());
intent.putExtra("cursorToEnd", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle bundle = new Bundle();
bundle.putString("commentBody", stringBuilder.toString());
bundle.putBoolean("cursorToEnd", true);
dialog.dismiss();
ctx.startActivity(intent);
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
});

View File

@ -0,0 +1,214 @@
package org.mian.gitnex.fragments;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R;
import org.mian.gitnex.actions.ActionResult;
import org.mian.gitnex.actions.IssueActions;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.Objects;
/**
* @author opyale
*/
public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
private TinyDB tinyDB;
private DraftsApi draftsApi;
private int repositoryId;
private int currentActiveAccountId;
private int issueNumber;
private long draftId;
private TextView draftsHint;
@Override
public void onAttach(@NonNull Context context) {
tinyDB = new TinyDB(context);
draftsApi = new DraftsApi(context);
repositoryId = (int) tinyDB.getLong("repositoryId", 0);
currentActiveAccountId = tinyDB.getInt("currentActiveAccountId");
issueNumber = Integer.parseInt(tinyDB.getString("issueNumber"));
super.onAttach(context);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bottom_sheet_reply_layout, container, false);
Bundle arguments = requireArguments();
draftsHint = view.findViewById(R.id.drafts_hint);
EditText commentContent = view.findViewById(R.id.comment);
TextView toolbarTitle = view.findViewById(R.id.toolbar_title);
ImageButton close = view.findViewById(R.id.close);
ImageButton drafts = view.findViewById(R.id.drafts);
ImageButton send = view.findViewById(R.id.send);
send.setEnabled(false);
if(Objects.equals(arguments.getString("commentAction"), "edit")) {
send.setVisibility(View.GONE);
}
if(arguments.getString("draftId") != null) {
draftId = Long.parseLong(arguments.getString("draftId"));
}
if(!tinyDB.getString("issueTitle").isEmpty()) {
toolbarTitle.setText(tinyDB.getString("issueTitle"));
}
else if(arguments.getString("draftTitle") != null) {
toolbarTitle.setText(arguments.getString("draftTitle"));
}
if(arguments.getString("commentBody") != null) {
send.setEnabled(true);
send.setAlpha(1f);
commentContent.setText(arguments.getString("commentBody"));
if(arguments.getBoolean("cursorToEnd", false)) {
commentContent.setSelection(commentContent.length());
}
}
commentContent.requestFocus();
commentContent.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
String text = commentContent.getText().toString();
if(text.isEmpty()) {
send.setEnabled(false);
send.setAlpha(0.5f);
saveDraft(null, true);
}
else {
send.setEnabled(true);
send.setAlpha(1f);
saveDraft(text, false);
}
}
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
close.setOnClickListener(v -> dismiss());
drafts.setOnClickListener(v -> {
Intent intent = new Intent(getContext(), MainActivity.class);
intent.putExtra("launchFragment", "drafts");
startActivity(intent);
dismiss();
});
send.setOnClickListener(v -> IssueActions
.reply(getContext(), commentContent.getText().toString(), issueNumber)
.accept((status, result) -> {
if(status == ActionResult.Status.SUCCESS) {
Toasty.success(getContext(), getString(R.string.commentSuccess));
tinyDB.putBoolean("commentPosted", true);
tinyDB.putBoolean("resumeIssues", true);
tinyDB.putBoolean("resumePullRequests", true);
if(draftId != 0 && tinyDB.getBoolean("draftsCommentsDeletionEnabled")) {
draftsApi.deleteSingleDraft((int) draftId);
}
dismiss();
}
else {
Toasty.error(getContext(), getString(R.string.commentError));
dismiss();
}
}));
return view;
}
private void saveDraft(String text, boolean remove) {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f);
valueAnimator.setDuration(500);
valueAnimator.addUpdateListener(animation -> {
float value = (Float) animation.getAnimatedValue();
if(value == 0f) {
draftsHint.setVisibility((remove) ? View.GONE : View.VISIBLE);
}
draftsHint.setAlpha(value);
});
if(remove) {
draftsApi.deleteSingleDraft((int) draftId);
draftId = 0;
valueAnimator.reverse();
}
else {
if(draftId == 0) {
draftId = draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, text, StaticGlobalVariables.draftTypeComment, "TODO");
} else {
DraftsApi.updateDraft(text, (int) draftId, "TODO");
}
draftsHint.setVisibility(View.VISIBLE);
valueAnimator.start();
}
}
public static BottomSheetReplyFragment newInstance(Bundle bundle) {
BottomSheetReplyFragment fragment = new BottomSheetReplyFragment();
fragment.setArguments(bundle);
return fragment;
}
}

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -66,11 +67,9 @@ public class DraftsFragment extends Fragment {
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
adapter = new DraftsAdapter(getContext(), draftsList_);
adapter = new DraftsAdapter(getContext(), getChildFragmentManager(), draftsList_);
currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
draftsList_.clear();
fetchDataAsync(currentActiveAccountId);

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -87,7 +88,7 @@ public class IssuesFragment extends Fragment {
mProgressBar = v.findViewById(R.id.progress_bar);
noDataIssues = v.findViewById(R.id.noDataIssues);
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState"));

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -87,18 +88,12 @@ public class LabelsFragment extends Fragment {
mProgressBar = v.findViewById(R.id.progress_bar);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
LabelsViewModel.loadLabelsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getContext());
}
}, 200);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
LabelsViewModel.loadLabelsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getContext());
}, 200));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -94,7 +95,7 @@ public class MilestonesFragment extends Fragment {
viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
viewBinding.recyclerView.setAdapter(adapter);
viewBinding.pullToRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
viewBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
dataList.clear();
viewBinding.pullToRefresh.setRefreshing(false);

View File

@ -4,6 +4,7 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -130,10 +131,11 @@ public class MyRepositoriesFragment extends Fragment {
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
MyRepositoriesViewModel.loadMyReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), userLogin, getContext(), pageSize, resultLimit);
}, 50));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), userLogin, pageSize, resultLimit);

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -99,18 +100,12 @@ public class OrganizationsFragment extends Fragment {
}
});
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
OrganizationListViewModel.loadOrgsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext());
}
}, 50);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
OrganizationListViewModel.loadOrgsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext());
}, 50));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -88,18 +89,12 @@ public class ProfileEmailsFragment extends Fragment {
mProgressBar = v.findViewById(R.id.progress_bar);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
ProfileEmailsViewModel.loadEmailsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext());
}
}, 200);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
ProfileEmailsViewModel.loadEmailsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext());
}, 200));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -88,18 +89,12 @@ public class ProfileFollowersFragment extends Fragment {
mProgressBar = v.findViewById(R.id.progress_bar);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
ProfileFollowersViewModel.loadFollowersList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext());
}
}, 200);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
ProfileFollowersViewModel.loadFollowersList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext());
}, 200));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -88,18 +89,12 @@ public class ProfileFollowingFragment extends Fragment {
mProgressBar = v.findViewById(R.id.progress_bar);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
ProfileFollowingViewModel.loadFollowingList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext());
}
}, 200);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
ProfileFollowingViewModel.loadFollowingList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext());
}, 200));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -88,7 +89,7 @@ public class PullRequestsFragment extends Fragment {
mProgressBar = v.findViewById(R.id.progress_bar);
noData = v.findViewById(R.id.noData);
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit);

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -88,18 +89,12 @@ public class ReleasesFragment extends Fragment {
mProgressBar = v.findViewById(R.id.progress_bar);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
ReleasesViewModel.loadReleasesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getContext());
}
}, 50);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
ReleasesViewModel.loadReleasesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getContext());
}, 50));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);

View File

@ -18,13 +18,13 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.TimeHelper;
@ -283,13 +283,7 @@ public class RepoInfoFragment extends Fragment {
repoMetaForks.setText(repoInfo.getForks_count());
repoMetaWatchers.setText(repoInfo.getWatchers_count());
if(repoInfo.getSize() != 0) {
repoMetaSize.setText(AppUtil.formatFileSize(repoInfo.getSize()));
}
else {
repoMetaSize.setText("0 B");
}
repoMetaSize.setText(FileUtils.byteCountToDisplaySize((int) repoInfo.getSize()));
repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx));
if(timeFormat.equals("pretty")) {

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -92,18 +93,12 @@ public class RepositoriesByOrgFragment extends Fragment {
mProgressBar = v.findViewById(R.id.progress_bar);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
RepositoriesByOrgViewModel.loadOrgRepos(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, getContext(), pageSize, resultLimit);
}
}, 200);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
RepositoriesByOrgViewModel.loadOrgRepos(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, getContext(), pageSize, resultLimit);
}, 200));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, pageSize, resultLimit);

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -98,10 +99,11 @@ public class RepositoriesFragment extends Fragment {
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
RepositoriesListViewModel.loadReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext(), pageSize, resultLimit);
}, 50));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), pageSize, resultLimit);

View File

@ -4,6 +4,7 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -127,18 +128,12 @@ public class StarredRepositoriesFragment extends Fragment {
}
});
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
StarredRepositoriesViewModel.loadStarredReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext(), pageSize, resultLimit);
}
}, 50);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
StarredRepositoriesViewModel.loadStarredReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext(), pageSize, resultLimit);
}, 50));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), pageSize, resultLimit);

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.fragments;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -90,18 +91,12 @@ public class TeamsByOrgFragment extends Fragment {
mProgressBar = v.findViewById(R.id.progress_bar);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
TeamsByOrgViewModel.loadTeamsByOrgList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, getContext());
}
}, 200);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
TeamsByOrgViewModel.loadTeamsByOrgList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, getContext());
}, 200));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName);

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -57,7 +58,7 @@ public class UserAccountsFragment extends Fragment {
adapter = new UserAccountsAdapter(getContext(), userAccountsList);
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
userAccountsList.clear();
swipeRefresh.setRefreshing(false);

View File

@ -13,7 +13,6 @@ import android.view.View;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
@ -123,33 +122,6 @@ public class AppUtil {
}
public static String formatFileSize(long size) {
String repoSize = size + " B";
double m = size / 1024.0;
double g = ((size / 1024.0) / 1024.0);
double t = (((size / 1024.0) / 1024.0) / 1024.0);
DecimalFormat dec = new DecimalFormat("0.00");
if(t > 1) {
repoSize = dec.format(t).concat(" TB");
}
else if(g > 1) {
repoSize = dec.format(g).concat(" GB");
}
else if(m > 1) {
repoSize = dec.format(m).concat(" MB");
}
else if((double) size > 1) {
repoSize = dec.format((double) size).concat(" KB");
}
return repoSize;
}
public static String getTimestampFromDate(Context context, Date date) {
TinyDB tinyDB = new TinyDB(context);
@ -159,37 +131,6 @@ public class AppUtil {
}
public static String formatFileSizeInDetail(long size) {
String fileSize = null;
double k = size / 1024.0;
double m = ((size / 1024.0) / 1024.0);
double g = (((size / 1024.0) / 1024.0) / 1024.0);
double t = ((((size / 1024.0) / 1024.0) / 1024.0) / 1024.0);
DecimalFormat dec = new DecimalFormat("0.00");
if(t > 1) {
fileSize = dec.format(t).concat(" TB");
}
else if(g > 1) {
fileSize = dec.format(g).concat(" GB");
}
else if(m > 1) {
fileSize = dec.format(m).concat(" MB");
}
else if(k > 1) {
fileSize = dec.format(k).concat(" KB");
}
else if((double) size > 1) {
fileSize = dec.format((double) size).concat(" B");
}
return fileSize;
}
public static String customDateFormat(String customDate) {
String[] parts = customDate.split("-");

View File

@ -1,12 +1,5 @@
package org.mian.gitnex.helpers;
import java.io.File;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
* Author M M Arif
*/
@ -16,69 +9,5 @@ public class FilesData {
public static int returnOnlyNumber(String fileSize) {
return Integer.parseInt(fileSize.substring(0, fileSize.indexOf(" ")));
}
public static long getFileSizeRecursively(Set<File> alreadySeen, File dirDirectory) {
long fileSize = 0;
for (File filItem : Objects.requireNonNull(dirDirectory.listFiles())) {
if (filItem.isDirectory()) {
fileSize += getFileSize(filItem);
}
else {
alreadySeen.add(new File(filItem.getName()));
fileSize += filItem.length();
}
}
return fileSize;
}
private static long getFileSize(File subDirectory) {
long fileSize = 0;
Deque<File> unprocessedDirs = new ArrayDeque<>();
unprocessedDirs.add(subDirectory);
Set<File> alreadySeen = new HashSet<>();
while (!unprocessedDirs.isEmpty()) {
File dir = unprocessedDirs.removeFirst();
for (File filItem : Objects.requireNonNull(dir.listFiles())) {
if (filItem.isDirectory()) {
unprocessedDirs.addFirst(filItem);
}
else {
if (! alreadySeen.contains(filItem.getName())) {
alreadySeen.add(new File(filItem.getName()));
fileSize += filItem.length();
}
}
}
}
return fileSize;
}
}

View File

@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M22,2L11,13"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M22,2l-7,20l-4,-9l-9,-4l20,-7z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,119 @@
<?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:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryBackgroundColor"
app:contentInsetEnd="15dp"
app:contentInsetStart="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<ImageButton
android:id="@+id/close"
android:layout_width="26dp"
android:layout_height="26dp"
android:layout_marginEnd="15dp"
android:layout_weight="0"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/close"
android:src="@drawable/ic_close" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:text="@string/commentButtonText"
android:textColor="?attr/primaryTextColor"
android:textSize="20sp" />
<ImageButton
android:id="@+id/drafts"
android:layout_width="26dp"
android:layout_height="26dp"
android:layout_marginStart="15dp"
android:layout_weight="0"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/close"
android:src="@drawable/ic_drafts" />
<ImageButton
android:id="@+id/send"
android:layout_width="26dp"
android:layout_height="26dp"
android:layout_marginStart="15dp"
android:layout_weight="0"
android:alpha=".5"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/close"
android:enabled="false"
android:src="@drawable/ic_send" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:isScrollContainer="true"
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_inputs"
android:inputType="textMultiLine|textImeMultiLine"
android:maxLines="5"
android:padding="10dp"
android:scrollbars="vertical"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/primaryTextColor"
android:textColorHint="?attr/primaryBackgroundColor"
android:textSize="16sp"
android:labelFor="@+id/comment"
android:autofillHints="@string/commentButtonText" />
<TextView
android:id="@+id/drafts_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="@string/draftSaved"
android:textColor="?attr/hintColor"
android:textSize="12sp"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -628,7 +628,7 @@
<string name="draftsDeleteSuccess">Drafts deleted successfully</string>
<string name="draftsSingleDeleteSuccess">Draft deleted successfully</string>
<string name="deleteAllDraftsDialogMessage">This will delete all the drafts for this account. \n\nProceed with deletion?</string>
<string name="draftSaved">Draft saved</string>
<string name="draftSaved">Draft was saved automatically.</string>
<string name="appearanceHintText">Themes, fonts, badges, code block theme</string>
<string name="fileViewerHintText">PDF mode, source code theme</string>

View File

@ -133,15 +133,22 @@
</style>
<style name="AppThemeDarkBottomSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize</item>
<item name="bottomSheetStyle">@style/AppBottomSheetModalStyle</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppThemeLightBottomSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize</item>
<item name="bottomSheetStyle">@style/AppBottomSheetModalStyle</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppBottomSheetModalStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/shape_bottom_sheet_top_corners</item>
<item name="behavior_peekHeight">420dp</item>
</style>
<style name="AppThemeLightSearchAutoCompleteTextView" parent="Widget.AppCompat.Light.AutoCompleteTextView">