Show attachments in issue/pr. Fix fade out screen allocation bug

This commit is contained in:
M M Arif 2023-09-23 13:41:11 +05:00
parent 2d6e05a0af
commit 28bd7c19d3
8 changed files with 423 additions and 163 deletions

View File

@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/>
<application
android:name=".core.MainApplication"

View File

@ -27,16 +27,20 @@ import androidx.core.widget.ImageViewCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.amulyakhare.textdrawable.TextDrawable;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.vdurmont.emoji.EmojiParser;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import org.apache.commons.io.FilenameUtils;
import org.gitnex.tea4j.v2.models.Attachment;
import org.gitnex.tea4j.v2.models.EditIssueOption;
import org.gitnex.tea4j.v2.models.Issue;
import org.gitnex.tea4j.v2.models.IssueLabelsOption;
@ -55,6 +59,7 @@ import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityIssueDetailBinding;
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomImageViewDialogBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomPrInfoDialogBinding;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
@ -64,11 +69,13 @@ import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.DownloadService;
import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.UrlHelper;
import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.structs.BottomSheetListener;
import org.mian.gitnex.viewmodels.IssueCommentsViewModel;
@ -598,6 +605,7 @@ public class IssueDetailActivity extends BaseActivity
viewBinding.progressBar.setVisibility(View.GONE);
getSubscribed();
initWithIssue();
getAttachments();
return;
}
@ -1104,4 +1112,141 @@ public class IssueDetailActivity extends BaseActivity
}
});
}
private void getAttachments() {
Call<List<Attachment>> call =
RetrofitClient.getApiInterface(ctx)
.issueListIssueAttachments(
issue.getRepository().getOwner(),
issue.getRepository().getName(),
(long) issueIndex);
call.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<List<Attachment>> call,
@NonNull retrofit2.Response<List<Attachment>> response) {
List<Attachment> attachment = response.body();
if (response.code() == 200) {
assert attachment != null;
if (attachment.size() > 0) {
viewBinding.attachmentFrame.setVisibility(View.VISIBLE);
LinearLayout.LayoutParams paramsAttachment =
new LinearLayout.LayoutParams(96, 96);
paramsAttachment.setMargins(0, 0, 48, 0);
for (int i = 0; i < attachment.size(); i++) {
ImageView attachmentView = new ImageView(ctx);
MaterialCardView materialCardView = new MaterialCardView(ctx);
materialCardView.setLayoutParams(paramsAttachment);
materialCardView.setStrokeWidth(0);
materialCardView.setCardBackgroundColor(Color.TRANSPARENT);
if (Arrays.asList(
"bmp", "gif", "jpg", "jpeg", "png", "webp",
"heic", "heif")
.contains(
FilenameUtils.getExtension(
attachment.get(i).getName())
.toLowerCase())) {
PicassoService.getInstance(ctx)
.get()
.load(
UrlHelper.appendPath(
getAccount()
.getAccount()
.getInstanceUrl(),
"/attachments/")
+ attachment.get(i).getUuid())
.placeholder(R.drawable.loader_animated)
.resize(120, 120)
.centerCrop()
.error(R.drawable.ic_close)
.into(attachmentView);
viewBinding.attachmentsView.addView(materialCardView);
attachmentView.setLayoutParams(paramsAttachment);
materialCardView.addView(attachmentView);
int finalI1 = i;
materialCardView.setOnClickListener(
v1 -> {
CustomImageViewDialogBinding
imageViewDialogBinding =
CustomImageViewDialogBinding
.inflate(
LayoutInflater
.from(
ctx));
View view = imageViewDialogBinding.getRoot();
materialAlertDialogBuilder.setView(view);
materialAlertDialogBuilder.setNeutralButton(
getString(R.string.close), null);
PicassoService.getInstance(ctx)
.get()
.load(
UrlHelper.appendPath(
getAccount()
.getAccount()
.getInstanceUrl(),
"/attachments/")
+ attachment
.get(finalI1)
.getUuid())
.placeholder(R.drawable.loader_animated)
.resize(0, 1600)
.onlyScaleDown()
.centerCrop()
.error(R.drawable.ic_close)
.into(imageViewDialogBinding.imageView);
materialAlertDialogBuilder.create().show();
});
} else {
attachmentView.setImageResource(
R.drawable.ic_file_download);
attachmentView.setPadding(4, 4, 4, 4);
viewBinding.attachmentsView.addView(materialCardView);
attachmentView.setLayoutParams(paramsAttachment);
materialCardView.addView(attachmentView);
int finalI = i;
materialCardView.setOnClickListener(
v1 -> {
DownloadService downloadService =
new DownloadService();
downloadService.downloadFile(
ctx,
UrlHelper.appendPath(
getAccount()
.getAccount()
.getInstanceUrl(),
"/attachments/")
+ attachment
.get(finalI)
.getUuid(),
attachment.get(finalI).getName());
});
}
}
} else {
viewBinding.attachmentFrame.setVisibility(View.GONE);
}
}
}
@Override
public void onFailure(
@NonNull Call<List<Attachment>> call, @NonNull Throwable t) {}
});
}
}

View File

@ -0,0 +1,32 @@
package org.mian.gitnex.helpers;
import static android.content.Context.DOWNLOAD_SERVICE;
import android.app.DownloadManager;
import android.content.Context;
import android.net.Uri;
import android.os.Environment;
/**
* @author M M Arif
*/
public class DownloadService {
public void downloadFile(Context ctx, String fileUri, String filename) {
Uri uri = Uri.parse(fileUri);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
request.setNotificationVisibility(
DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setMimeType("*/*");
request.setTitle("Downloading " + filename + " via GitNex");
DownloadManager downloadManager = (DownloadManager) ctx.getSystemService(DOWNLOAD_SERVICE);
downloadManager.enqueue(request);
if (DownloadManager.STATUS_SUCCESSFUL == 8) {
Toasty.success(ctx, "Download completed");
}
}
}

View File

@ -41,7 +41,7 @@ public abstract class ViewPager2Transformers {
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));

View File

@ -0,0 +1,34 @@
<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="M14.5,2H6a2,2 0,0 0,-2 2v16a2,2 0,0 0,2 2h12a2,2 0,0 0,2 -2V7.5L14.5,2z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M14,2l0,6l6,0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M12,18v-6"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="m9,15 l3,3 3,-3"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
</vector>

View File

@ -3,10 +3,10 @@
android:shape="rectangle">
<corners
android:topLeftRadius="@dimen/dimen32dp"
android:topRightRadius="@dimen/dimen32dp"/>
android:topLeftRadius="@dimen/dimen28dp"
android:topRightRadius="@dimen/dimen28dp"/>
<padding android:top="@dimen/dimen24dp"/>
<padding android:top="@dimen/dimen28dp"/>
<solid android:color="?attr/primaryBackgroundColor"/>

View File

@ -132,197 +132,230 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/materialCardBackgroundColor"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
android:padding="@dimen/dimen12dp">
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewElevatedStyle"
android:layout_width="@dimen/dimen24dp"
android:layout_height="@dimen/dimen24dp"
app:cardCornerRadius="@dimen/dimen12dp"
app:cardElevation="@dimen/dimen0dp">
<ImageView
android:id="@+id/assigneeAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0"
android:contentDescription="@string/generalImgContentText"
tools:srcCompat="@tools:sample/avatars"
tools:ignore="TooDeepLayout" />
</com.google.android.material.card.MaterialCardView>
android:layout_height="wrap_content"
android:background="?attr/materialCardBackgroundColor"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
android:padding="@dimen/dimen12dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dimen16dp"
android:layout_marginRight="@dimen/dimen16dp"
android:layout_weight="1"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="middle"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="14sp"
android:textStyle="bold" />
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewElevatedStyle"
android:layout_width="@dimen/dimen24dp"
android:layout_height="@dimen/dimen24dp"
app:cardCornerRadius="@dimen/dimen12dp"
app:cardElevation="@dimen/dimen0dp">
<ImageView
android:id="@+id/assigneeAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0"
android:contentDescription="@string/generalImgContentText"
tools:srcCompat="@tools:sample/avatars"
tools:ignore="TooDeepLayout" />
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:layout_marginLeft="@dimen/dimen16dp"
android:layout_marginRight="@dimen/dimen16dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/issueCreatedTime"
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:textColor="?attr/hintColor"
android:textSize="12sp"
android:visibility="gone" />
android:ellipsize="middle"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/issueModified"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:text="@string/modifiedText"
android:textColor="?attr/hintColor"
android:textSize="12sp"
android:visibility="gone" />
android:orientation="horizontal">
<TextView
android:id="@+id/issueCreatedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:textColor="?attr/hintColor"
android:textSize="12sp"
android:visibility="gone" />
<TextView
android:id="@+id/issueModified"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="@string/modifiedText"
android:textColor="?attr/hintColor"
android:textSize="12sp"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/dueDateFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end|center_vertical"
android:orientation="horizontal"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="@dimen/dimen20dp"
<LinearLayout
android:id="@+id/dueDateFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_calendar" />
android:gravity="end|center_vertical"
android:orientation="horizontal"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<TextView
android:id="@+id/issueDueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen8dp"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
<ImageView
android:layout_width="@dimen/dimen20dp"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_calendar" />
</LinearLayout>
<TextView
android:id="@+id/issueDueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen8dp"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
<LinearLayout
android:id="@+id/milestoneFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end|center_vertical"
android:orientation="horizontal"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="@dimen/dimen20dp"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_milestone" />
<TextView
android:id="@+id/issueMilestone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen8dp"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
</LinearLayout>
<HorizontalScrollView
android:id="@+id/assigneesScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:foregroundGravity="right"
android:visibility="gone"
android:scrollbarThumbHorizontal="@android:color/transparent">
</LinearLayout>
<LinearLayout
android:id="@+id/frameAssignees"
android:layout_width="wrap_content"
android:id="@+id/milestoneFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end|center_vertical"
android:orientation="horizontal"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="@dimen/dimen20dp"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_milestone" />
<TextView
android:id="@+id/issueMilestone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen8dp"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
</LinearLayout>
<HorizontalScrollView
android:id="@+id/assigneesScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:foregroundGravity="right"
android:visibility="gone"
android:scrollbarThumbHorizontal="@android:color/transparent">
<LinearLayout
android:id="@+id/frameAssignees"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="@dimen/dimen10dp"
android:gravity="end"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/issueDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/dimen8dp"
android:autoLink="web"
android:gravity="start"
android:visibility="gone"
android:textColor="?attr/primaryTextColor"
android:textColorLink="@color/lightBlue"
android:textIsSelectable="true"
android:textSize="@dimen/dimen14sp" />
<HorizontalScrollView
android:id="@+id/labelsScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:foregroundGravity="right"
android:visibility="gone"
android:scrollbarThumbHorizontal="@android:color/transparent">
<LinearLayout
android:id="@+id/frameLabels"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen10dp"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:id="@+id/commentReactionBadges"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="@dimen/dimen10dp"
android:gravity="end"
android:orientation="horizontal"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:id="@+id/attachmentFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/materialCardBackgroundColor"
android:foreground="?android:attr/selectableItemBackground"
android:visibility="gone"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="@dimen/dimen1dp"
android:layout_marginTop="@dimen/dimen4dp"
android:background="?attr/dividerColor" />
<LinearLayout
android:id="@+id/attachmentsView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dimen12dp"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/issueDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/dimen8dp"
android:autoLink="web"
android:gravity="start"
android:visibility="gone"
android:textColor="?attr/primaryTextColor"
android:textColorLink="@color/lightBlue"
android:textIsSelectable="true"
android:textSize="@dimen/dimen14sp" />
<HorizontalScrollView
android:id="@+id/labelsScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:foregroundGravity="right"
android:visibility="gone"
android:scrollbarThumbHorizontal="@android:color/transparent">
<LinearLayout
android:id="@+id/frameLabels"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen10dp"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:id="@+id/commentReactionBadges"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen10dp"
android:orientation="horizontal"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/dimen32dp"
android:layout_gravity="center"
android:contentDescription="@string/generalImgContentText" />
</LinearLayout>