diff --git a/app/src/main/java/org/mian/gitnex/adapters/ActivitiesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/ActivitiesAdapter.java
index f504b64d..8864aae4 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/ActivitiesAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/ActivitiesAdapter.java
@@ -124,8 +124,6 @@ class DashboardHolder extends RecyclerView.ViewHolder {
private final ImageView typeIcon;
private final TextView dashText;
private final LinearLayout dashTextFrame;
- private LinearLayout dashboardLayoutCardsFrame;
- private MaterialCardView cardLayout;
private Activity activityObject;
@@ -138,8 +136,9 @@ class DashboardHolder extends RecyclerView.ViewHolder {
createdTime = itemView.findViewById(R.id.created_time);
dashText = itemView.findViewById(R.id.text);
dashTextFrame = itemView.findViewById(R.id.dash_text_frame);
- dashboardLayoutCardsFrame = itemView.findViewById(R.id.dashboardLayoutCardsFrame);
- cardLayout = itemView.findViewById(R.id.cardLayout);
+ LinearLayout dashboardLayoutCardsFrame =
+ itemView.findViewById(R.id.dashboardLayoutCardsFrame);
+ MaterialCardView cardLayout = itemView.findViewById(R.id.cardLayout);
new Handler()
.postDelayed(
@@ -397,9 +396,11 @@ private String getString() {
String content = activityObject.getContent();
String id;
- if (content.trim().startsWith("[")) {
+ int arrayStart = content.trim().indexOf("[\"");
+ if (arrayStart != -1) {
try {
- String cleanContent = content.trim().substring(1, content.length() - 1);
+ String jsonPart = content.trim().substring(arrayStart);
+ String cleanContent = jsonPart.substring(1, jsonPart.length() - 1);
String[] contentParts = cleanContent.split(",", 2);
id = contentParts[0].trim();
@@ -501,30 +502,19 @@ void bindData(Activity activity, int position) {
+ activity.getRepo().getFullName()
+ "";
+ String branch =
+ ""
+ + activity.getRefName()
+ .substring(activity.getRefName().lastIndexOf("/") + 1)
+ .trim()
+ + "";
if (activity.getContent().isEmpty()) {
- String branch =
- ""
- + activity.getRefName()
- .substring(
- activity.getRefName().lastIndexOf("/") + 1)
- .trim()
- + "";
typeString =
String.format(context.getString(R.string.createdBranch), branch);
} else {
- String branch =
- ""
- + activity.getRefName()
- .substring(
- activity.getRefName().lastIndexOf("/") + 1)
- .trim()
- + "";
typeString = String.format(context.getString(R.string.pushedTo), branch);
JSONObject commitsObj = null;
@@ -611,15 +601,45 @@ void bindData(Activity activity, int position) {
} else if (activity.getOpType().getValue().contains("issue")) {
String id;
- String content;
- String[] contentParts = activity.getContent().split("\\|");
- if (contentParts.length > 1) {
+ String content = "";
+ String rawContent = activity.getContent().trim();
+
+ int arrayStart = rawContent.indexOf("[\"");
+ if (arrayStart != -1) {
+ try {
+ String jsonPart = rawContent.substring(arrayStart);
+ String cleanContent = jsonPart.substring(1, jsonPart.length() - 1);
+ String[] contentParts = cleanContent.split(",", 2);
+ id = contentParts[0].trim();
+
+ if (id.startsWith("\"") && id.endsWith("\"")) {
+ id = id.substring(1, id.length() - 1);
+ }
+
+ if (contentParts.length > 1) {
+ content = contentParts[1].trim();
+ if (content.startsWith("\"") && content.endsWith("\"")) {
+ content = content.substring(1, content.length() - 1);
+ }
+ }
+ } catch (Exception e) {
+ String[] contentParts = rawContent.split("\\|");
+ id = contentParts[0];
+ if (contentParts.length > 1) {
+ content = contentParts[1];
+ }
+ }
+ } else {
+ String[] contentParts = rawContent.split("\\|");
id = contentParts[0];
- content = contentParts[1];
+ if (contentParts.length > 1) {
+ content = contentParts[1];
+ }
+ }
+
+ if (!content.isEmpty()) {
dashTextFrame.setVisibility(View.VISIBLE);
dashText.setText(EmojiParser.parseToUnicode(content));
- } else {
- id = contentParts[0];
}
if (activity.getOpType().getValue().equalsIgnoreCase("create_issue")) {
@@ -678,15 +698,45 @@ void bindData(Activity activity, int position) {
} else if (activity.getOpType().getValue().contains("pull")) {
String id;
- String content;
- String[] contentParts = activity.getContent().split("\\|");
- if (contentParts.length > 1) {
+ String content = "";
+ String rawContent = activity.getContent().trim();
+
+ int arrayStart = rawContent.indexOf("[\"");
+ if (arrayStart != -1) {
+ try {
+ String jsonPart = rawContent.substring(arrayStart);
+ String cleanContent = jsonPart.substring(1, jsonPart.length() - 1);
+ String[] contentParts = cleanContent.split(",", 2);
+ id = contentParts[0].trim();
+
+ if (id.startsWith("\"") && id.endsWith("\"")) {
+ id = id.substring(1, id.length() - 1);
+ }
+
+ if (contentParts.length > 1) {
+ content = contentParts[1].trim();
+ if (content.startsWith("\"") && content.endsWith("\"")) {
+ content = content.substring(1, content.length() - 1);
+ }
+ }
+ } catch (Exception e) {
+ String[] contentParts = rawContent.split("\\|");
+ id = contentParts[0];
+ if (contentParts.length > 1) {
+ content = contentParts[1];
+ }
+ }
+ } else {
+ String[] contentParts = rawContent.split("\\|");
id = contentParts[0];
- content = contentParts[1];
+ if (contentParts.length > 1) {
+ content = contentParts[1];
+ }
+ }
+
+ if (!content.isEmpty()) {
dashTextFrame.setVisibility(View.VISIBLE);
dashText.setText(EmojiParser.parseToUnicode(content));
- } else {
- id = contentParts[0];
}
if (activity.getOpType().getValue().equalsIgnoreCase("create_pull_request")) {
@@ -804,10 +854,36 @@ void bindData(Activity activity, int position) {
}
} else if (activity.getOpType().getValue().contains("branch")) {
- String content;
- String[] contentParts = activity.getContent().split("\\|");
- if (contentParts.length > 1) {
- content = contentParts[1];
+ String content = "";
+ String rawContent = activity.getContent().trim();
+
+ int arrayStart = rawContent.indexOf("[\"");
+ if (arrayStart != -1) {
+ try {
+ String jsonPart = rawContent.substring(arrayStart);
+ String cleanContent = jsonPart.substring(1, jsonPart.length() - 1);
+ String[] contentParts = cleanContent.split(",", 2);
+
+ if (contentParts.length > 1) {
+ content = contentParts[1].trim();
+ if (content.startsWith("\"") && content.endsWith("\"")) {
+ content = content.substring(1, content.length() - 1);
+ }
+ }
+ } catch (Exception e) {
+ String[] contentParts = rawContent.split("\\|");
+ if (contentParts.length > 1) {
+ content = contentParts[1];
+ }
+ }
+ } else {
+ String[] contentParts = rawContent.split("\\|");
+ if (contentParts.length > 1) {
+ content = contentParts[1];
+ }
+ }
+
+ if (!content.isEmpty()) {
dashTextFrame.setVisibility(View.VISIBLE);
dashText.setText(EmojiParser.parseToUnicode(content));
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
index e8cd36db..001d8cbd 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
@@ -3,6 +3,7 @@
import static org.mian.gitnex.helpers.AppUtil.isNightModeThemeDynamic;
import android.annotation.SuppressLint;
+import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -27,6 +28,8 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.text.HtmlCompat;
@@ -35,10 +38,12 @@
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.CustomTarget;
+import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
@@ -75,7 +80,7 @@
import retrofit2.Callback;
/**
- * @author M M Arif
+ * @author mmarif
*/
public class IssueCommentsAdapter extends RecyclerView.Adapter {
@@ -102,7 +107,7 @@ public IssueCommentsAdapter(
this.issuesComments = issuesCommentsMain;
this.onInteractedListener = onInteractedListener;
tinyDB = TinyDB.getInstance(ctx);
- locale = ctx.getResources().getConfiguration().locale;
+ locale = ctx.getResources().getConfiguration().getLocales().get(0);
this.issue = issue;
}
@@ -241,6 +246,8 @@ class IssueCommentViewHolder extends RecyclerView.ViewHolder {
private TimelineComment issueComment;
private final LinearLayout timelineDividerView;
private final FrameLayout timelineLine2;
+ private final List> glideTargets = new ArrayList<>();
+ private boolean isAttachedToWindow = false;
private IssueCommentViewHolder(View view) {
@@ -263,14 +270,15 @@ private IssueCommentViewHolder(View view) {
String token = ((BaseActivity) context).getAccount().getAccount().getToken();
- new Handler()
- .postDelayed(
- () -> {
- if (issueComment != null) {
- getAttachments(issueComment.getId(), view, token);
- }
- },
- 250);
+ Handler handler = new Handler();
+
+ handler.postDelayed(
+ () -> {
+ if (issueComment != null) {
+ getAttachments(issueComment.getId(), view, token, this);
+ }
+ },
+ 250);
menu.setOnClickListener(
v -> {
@@ -467,6 +475,9 @@ private IssueCommentViewHolder(View view) {
void bindData(TimelineComment timelineComment) {
+ clearGlideRequests();
+ isAttachedToWindow = true;
+
if (timelineComment != null) {
Typeface typeface = AppUtil.getTypeface(context);
@@ -1139,7 +1150,6 @@ else if (issueComment.getType().equalsIgnoreCase("added_deadline")
}
}
- // TODO pretty-print
if (issueComment.getType().equalsIgnoreCase("added_deadline")) {
start.setText(
context.getString(
@@ -1364,12 +1374,7 @@ else if (issueComment.getType().equalsIgnoreCase("pin")) {
author.setText(issueComment.getUser().getLogin());
- Glide.with(context)
- .load(issueComment.getUser().getAvatarUrl())
- .diskCacheStrategy(DiskCacheStrategy.ALL)
- .placeholder(R.drawable.loader_animated)
- .centerCrop()
- .into(avatar);
+ loadAvatarSafely(issueComment.getUser().getAvatarUrl(), avatar);
Markdown.render(
context, issueComment.getBody(), comment, issue.getRepository());
@@ -1401,9 +1406,41 @@ else if (issueComment.getType().equalsIgnoreCase("pin")) {
commentView.setVisibility(View.GONE);
}
}
+
+ private void loadAvatarSafely(String avatarUrl, ImageView avatarView) {
+ if (isActivityValid()) {
+ Target target =
+ Glide.with(context)
+ .load(avatarUrl)
+ .diskCacheStrategy(DiskCacheStrategy.ALL)
+ .placeholder(R.drawable.loader_animated)
+ .centerCrop()
+ .into(avatarView);
+
+ glideTargets.add(target);
+ }
+ }
+
+ private boolean isActivityValid() {
+ if (context instanceof Activity activity) {
+ return !activity.isFinishing() && !activity.isDestroyed();
+ }
+ return true;
+ }
+
+ void clearGlideRequests() {
+ if (context != null && isActivityValid()) {
+ for (Target> target : glideTargets) {
+ Glide.with(context).clear(target);
+ }
+ }
+ glideTargets.clear();
+ isAttachedToWindow = false;
+ }
}
- private void getAttachments(Long issueIndex, View view, String token) {
+ private void getAttachments(
+ Long issueIndex, View view, String token, IssueCommentViewHolder holder) {
LinearLayout attachmentFrame = view.findViewById(R.id.attachmentFrame);
LinearLayout attachmentsView = view.findViewById(R.id.attachmentsView);
@@ -1423,6 +1460,10 @@ public void onResponse(
@NonNull Call> call,
@NonNull retrofit2.Response> response) {
+ if (holder == null || !holder.isAttachedToWindow) {
+ return;
+ }
+
List attachment = response.body();
if (response.code() == 200) {
@@ -1453,16 +1494,24 @@ public void onResponse(
attachment.get(i).getName())
.toLowerCase())) {
- Glide.with(context)
- .load(
- attachment.get(i).getBrowserDownloadUrl()
- + "?token="
- + token)
- .diskCacheStrategy(DiskCacheStrategy.ALL)
- .placeholder(R.drawable.loader_animated)
- .centerCrop()
- .error(R.drawable.ic_close)
- .into(attachmentView);
+ if (holder.isActivityValid()) {
+ Target target =
+ Glide.with(context)
+ .load(
+ attachment
+ .get(i)
+ .getBrowserDownloadUrl()
+ + "?token="
+ + token)
+ .diskCacheStrategy(
+ DiskCacheStrategy.ALL)
+ .placeholder(R.drawable.loader_animated)
+ .centerCrop()
+ .error(R.drawable.ic_close)
+ .into(attachmentView);
+
+ holder.glideTargets.add(target);
+ }
attachmentsView.addView(materialCardView);
attachmentView.setLayoutParams(paramsAttachment);
@@ -1475,7 +1524,8 @@ public void onResponse(
attachment
.get(finalI1)
.getBrowserDownloadUrl(),
- token));
+ token,
+ holder));
} else {
@@ -1508,7 +1558,11 @@ public void onFailure(
});
}
- private void imageViewDialog(String url, String token) {
+ private void imageViewDialog(String url, String token, IssueCommentViewHolder holder) {
+
+ if (holder == null || !holder.isActivityValid()) {
+ return;
+ }
MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(
@@ -1521,28 +1575,65 @@ private void imageViewDialog(String url, String token) {
materialAlertDialogBuilder.setNeutralButton(context.getString(R.string.close), null);
- Glide.with(context)
- .asBitmap()
- .load(url + "?token=" + token)
- .diskCacheStrategy(DiskCacheStrategy.ALL)
- .placeholder(R.drawable.loader_animated)
- .centerCrop()
- .error(R.drawable.ic_close)
- .dontAnimate()
- .into(
- new CustomTarget() {
- @Override
- public void onResourceReady(
- @NonNull Bitmap resource,
- Transition super Bitmap> transition) {
- imageViewDialogBinding.imageView.setImageBitmap(resource);
- imageViewDialogBinding.imageView.buildDrawingCache();
- }
+ CustomTarget target =
+ new CustomTarget() {
+ @Override
+ public void onResourceReady(
+ @NonNull Bitmap resource, Transition super Bitmap> transition) {
+ if (holder.isAttachedToWindow) {
+ imageViewDialogBinding.imageView.setImageBitmap(resource);
+ imageViewDialogBinding.imageView.buildDrawingCache();
+ }
+ }
+
+ @Override
+ public void onLoadCleared(Drawable placeholder) {
+ if (holder.isAttachedToWindow) {
+ imageViewDialogBinding.imageView.setImageDrawable(placeholder);
+ }
+ }
+
+ @Override
+ public void onLoadFailed(@Nullable Drawable errorDrawable) {
+ super.onLoadFailed(errorDrawable);
+ if (holder.isAttachedToWindow) {
+ imageViewDialogBinding.imageView.setImageDrawable(errorDrawable);
+ }
+ }
+ };
+
+ holder.glideTargets.add(target);
+
+ if (holder.isActivityValid()) {
+ Glide.with(context)
+ .asBitmap()
+ .load(url + "?token=" + token)
+ .diskCacheStrategy(DiskCacheStrategy.ALL)
+ .placeholder(R.drawable.loader_animated)
+ .error(R.drawable.ic_close)
+ .dontAnimate()
+ .into(target);
+ }
- @Override
- public void onLoadCleared(Drawable placeholder) {}
- });
+ AlertDialog dialog = materialAlertDialogBuilder.create();
+
+ dialog.setOnDismissListener(
+ dialogInterface -> {
+ if (holder.isActivityValid()) {
+ Glide.with(context).clear(target);
+ holder.glideTargets.remove(target);
+ }
+ });
- materialAlertDialogBuilder.create().show();
+ dialog.show();
+ }
+
+ @Override
+ public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
+ super.onViewRecycled(holder);
+
+ if (holder instanceof IssueCommentViewHolder) {
+ ((IssueCommentViewHolder) holder).clearGlideRequests();
+ }
}
}