implement adapter, fragment, viewmodel for dashboard. Add draft icon for PRs

This commit is contained in:
M M Arif 2023-08-30 10:58:14 +05:00
parent a696bb8f42
commit 3e010361b1
13 changed files with 1221 additions and 32 deletions

View File

@ -700,6 +700,20 @@ public class IssueDetailActivity extends BaseActivity
viewBinding.issuePrState,
ColorStateList.valueOf(
ctx.getResources().getColor(R.color.iconIssuePrClosedColor, null)));
} else if (issue.getIssue().getTitle().contains("[WIP]")
|| issue.getIssue().getTitle().contains("[wip]")) { // draft
viewBinding.issuePrState.setImageResource(R.drawable.ic_draft);
ImageViewCompat.setImageTintList(
viewBinding.issuePrState,
ColorStateList.valueOf(
ctx.getResources().getColor(R.color.colorWhite, null)));
viewBinding.issuePrState.setBackgroundResource(R.drawable.shape_draft_release);
viewBinding.issuePrState.setPadding(
R.dimen.dimen8dp, R.dimen.dimen2dp, R.dimen.dimen8dp, R.dimen.dimen2dp);
viewBinding.toolbarTitle.setPadding(
R.dimen.dimen16dp, R.dimen.dimen0dp, R.dimen.dimen0dp, R.dimen.dimen0dp);
} else { // open
viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request);
@ -1034,7 +1048,7 @@ public class IssueDetailActivity extends BaseActivity
RetrofitClient.getApiInterface(this)
.repoGetPullRequest(repoOwner, repoName, (long) issueIndex)
.enqueue(
new Callback<PullRequest>() {
new Callback<>() {
@Override
public void onResponse(

View File

@ -0,0 +1,736 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.text.HtmlCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.vdurmont.emoji.EmojiParser;
import java.util.List;
import java.util.Locale;
import org.gitnex.tea4j.v2.models.Activity;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
/**
* @author M M Arif
*/
public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
TinyDB tinyDb;
private List<Activity> activityList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public DashboardAdapter(List<Activity> dataList, Context ctx) {
this.context = ctx;
this.activityList = dataList;
this.tinyDb = TinyDB.getInstance(ctx);
}
@NonNull @Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
return new DashboardAdapter.DashboardHolder(
inflater.inflate(R.layout.list_dashboard_activity, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (position >= getItemCount() - 1
&& isMoreDataAvailable
&& !isLoading
&& loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
((DashboardAdapter.DashboardHolder) holder).bindData(activityList.get(position));
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getItemCount() {
return activityList.size();
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
if (!isMoreDataAvailable) {
loadMoreListener.onLoadFinished();
}
}
@SuppressLint("NotifyDataSetChanged")
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
loadMoreListener.onLoadFinished();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<Activity> list) {
activityList = list;
notifyDataChanged();
}
public interface OnLoadMoreListener {
void onLoadMore();
void onLoadFinished();
}
class DashboardHolder extends RecyclerView.ViewHolder {
private final ImageView userAvatar;
private final TextView typeDetails;
private final TextView createdTime;
private final ImageView typeIcon;
private final TextView dashText;
private final LinearLayout dashTextFrame;
private Activity activityObject;
DashboardHolder(View itemView) {
super(itemView);
userAvatar = itemView.findViewById(R.id.user_avatar);
typeDetails = itemView.findViewById(R.id.type_details);
typeIcon = itemView.findViewById(R.id.type_icon);
createdTime = itemView.findViewById(R.id.created_time);
dashText = itemView.findViewById(R.id.text);
dashTextFrame = itemView.findViewById(R.id.dash_text_frame);
/*new Handler()
.postDelayed(
() -> {
if (!AppUtil.checkGhostUsers(issueObject.getUser().getLogin())) {
issueAssigneeAvatar.setOnLongClickListener(
loginId -> {
AppUtil.copyToClipboard(
context,
issueObject.getUser().getLogin(),
context.getString(
R.string.copyLoginIdToClipBoard,
issueObject.getUser().getLogin()));
return true;
});
issueAssigneeAvatar.setOnClickListener(
v -> {
Intent intent =
new Intent(context, ProfileActivity.class);
intent.putExtra(
"username",
issueObject.getUser().getLogin());
context.startActivity(intent);
});
}
},
500);*/
}
@SuppressLint("SetTextI18n")
void bindData(Activity activity) {
this.activityObject = activity;
Locale locale = context.getResources().getConfiguration().locale;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context)
.get()
.load(activity.getActUser().getAvatarUrl())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(imgRadius, 0))
.resize(120, 120)
.centerCrop()
.into(userAvatar);
String username =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getActUser().getLogin()
+ "</font>";
String headerString = "";
String typeString = "";
if (activity.getOpType().contains("repo")) {
if (activity.getOpType().equalsIgnoreCase("create_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "created repository";
typeIcon.setImageResource(R.drawable.ic_repo);
} else if (activity.getOpType().equalsIgnoreCase("rename_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "renamed repository from " + activity.getContent() + " to";
typeIcon.setImageResource(R.drawable.ic_repo);
} else if (activity.getOpType().equalsIgnoreCase("star_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "starred";
typeIcon.setImageResource(R.drawable.ic_star);
} else if (activity.getOpType().equalsIgnoreCase("transfer_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "transferred repository " + activity.getContent() + " to";
typeIcon.setImageResource(R.drawable.ic_arrow_up);
} else if (activity.getOpType().equalsIgnoreCase("commit_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
if (activity.getContent().isEmpty()) {
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(
activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "created branch " + branch + " in";
} else {
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(
activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "pushed to " + branch + " at";
}
typeIcon.setImageResource(R.drawable.ic_commit);
}
} else if (activity.getOpType().contains("issue")) {
String id = "";
String content = "";
String[] contentParts = activity.getContent().split("\\|");
if (contentParts.length > 1) {
id = contentParts[0];
content = contentParts[1];
dashTextFrame.setVisibility(View.VISIBLE);
dashText.setText(EmojiParser.parseToUnicode(content));
} else {
id = contentParts[0];
}
if (activity.getOpType().equalsIgnoreCase("create_issue")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "opened issue";
typeIcon.setImageResource(R.drawable.ic_issue);
} else if (activity.getOpType().equalsIgnoreCase("comment_issue")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "commented on issue";
typeIcon.setImageResource(R.drawable.ic_comment);
} else if (activity.getOpType().equalsIgnoreCase("close_issue")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "closed issue";
typeIcon.setImageResource(R.drawable.ic_issue_closed);
} else if (activity.getOpType().equalsIgnoreCase("reopen_issue")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "reopened issue";
typeIcon.setImageResource(R.drawable.ic_reopen);
}
} else if (activity.getOpType().contains("pull")) {
String id = "";
String content = "";
String[] contentParts = activity.getContent().split("\\|");
if (contentParts.length > 1) {
id = contentParts[0];
content = contentParts[1];
dashTextFrame.setVisibility(View.VISIBLE);
dashText.setText(EmojiParser.parseToUnicode(content));
} else {
id = contentParts[0];
}
if (activity.getOpType().equalsIgnoreCase("create_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "created pull request";
typeIcon.setImageResource(R.drawable.ic_pull_request);
} else if (activity.getOpType().equalsIgnoreCase("close_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "closed pull request";
typeIcon.setImageResource(R.drawable.ic_issue_closed);
} else if (activity.getOpType().equalsIgnoreCase("reopen_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "reopened pull request";
typeIcon.setImageResource(R.drawable.ic_reopen);
} else if (activity.getOpType().equalsIgnoreCase("merge_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "merged pull request";
typeIcon.setImageResource(R.drawable.ic_pull_request);
} else if (activity.getOpType().equalsIgnoreCase("approve_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "approved";
typeIcon.setImageResource(R.drawable.ic_done);
} else if (activity.getOpType().equalsIgnoreCase("reject_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "suggested changes for";
typeIcon.setImageResource(R.drawable.ic_diff);
} else if (activity.getOpType().equalsIgnoreCase("comment_pull")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "commented on pull request";
typeIcon.setImageResource(R.drawable.ic_comment);
} else if (activity.getOpType().equalsIgnoreCase("auto_merge_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "automatically merged pull request";
typeIcon.setImageResource(R.drawable.ic_issue_closed);
}
} else if (activity.getOpType().contains("branch")) {
String id = "";
String content = "";
String[] contentParts = activity.getContent().split("\\|");
if (contentParts.length > 1) {
id = contentParts[0];
content = contentParts[1];
dashTextFrame.setVisibility(View.VISIBLE);
dashText.setText(EmojiParser.parseToUnicode(content));
} else {
id = contentParts[0];
}
if (activity.getOpType().equalsIgnoreCase("delete_branch")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "deleted branch " + branch + " at";
typeIcon.setImageResource(R.drawable.ic_commit);
}
} else if (activity.getOpType().contains("tag")) {
if (activity.getOpType().equalsIgnoreCase("push_tag")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "pushed tag " + branch + " to";
typeIcon.setImageResource(R.drawable.ic_commit);
} else if (activity.getOpType().equalsIgnoreCase("delete_tag")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "deleted tag " + branch + " from";
typeIcon.setImageResource(R.drawable.ic_commit);
}
} else if (activity.getOpType().contains("release")) {
if (activity.getOpType().equalsIgnoreCase("publish_release")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "released " + branch + " at";
typeIcon.setImageResource(R.drawable.ic_tag);
}
} else if (activity.getOpType().contains("mirror")) {
if (activity.getOpType().equalsIgnoreCase("mirror_sync_push")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "synced commits to " + headerString + " at";
typeIcon.setImageResource(R.drawable.ic_tag);
} else if (activity.getOpType().equalsIgnoreCase("mirror_sync_create")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "synced new reference " + headerString + " to";
typeIcon.setImageResource(R.drawable.ic_tag);
} else if (activity.getOpType().equalsIgnoreCase("mirror_sync_delete")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "synced and deleted reference " + headerString + " at";
typeIcon.setImageResource(R.drawable.ic_tag);
}
} else {
dashTextFrame.setVisibility(View.GONE);
dashText.setVisibility(View.GONE);
}
typeDetails.setText(
HtmlCompat.fromHtml(
username + " " + typeString + " " + headerString,
HtmlCompat.FROM_HTML_MODE_LEGACY));
/*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));
this.issueObject = issue;
this.issueCommentsCount.setText(String.valueOf(issue.getComments()));
Intent intentIssueDetail =
new IssueContext(issueObject, ((RepoDetailActivity) context).repository)
.getIntent(context, IssueDetailActivity.class);*/
/*itemView.setOnClickListener(layoutView -> context.startActivity(intentIssueDetail));
frameLabels.setOnClickListener(v -> context.startActivity(intentIssueDetail));
frameLabelsDots.setOnClickListener(v -> context.startActivity(intentIssueDetail));*/
/*LinearLayout.LayoutParams params =
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(0, 0, 15, 0);
Typeface typeface = AppUtil.getTypeface(context);*/
this.createdTime.setText(TimeHelper.formatTime(activity.getCreated(), locale));
this.createdTime.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(activity.getCreated()),
context));
/*if (issue.getLabels() != null) {
if (!tinyDb.getBoolean("showLabelsInList", false)) { // default
labelsScrollViewWithText.setVisibility(View.GONE);
labelsScrollViewDots.setVisibility(View.VISIBLE);
frameLabelsDots.removeAllViews();
for (int i = 0; i < issue.getLabels().size(); i++) {
String labelColor = issue.getLabels().get(i).getColor();
int color = Color.parseColor("#" + labelColor);
ImageView labelsView = new ImageView(context);
frameLabelsDots.setOrientation(LinearLayout.HORIZONTAL);
frameLabelsDots.setGravity(Gravity.START | Gravity.TOP);
labelsView.setLayoutParams(params);
TextDrawable drawable =
TextDrawable.builder()
.beginConfig()
.useFont(typeface)
.width(54)
.height(54)
.endConfig()
.buildRound("", color);
labelsView.setImageDrawable(drawable);
frameLabelsDots.addView(labelsView);
}
} else {
labelsScrollViewDots.setVisibility(View.GONE);
labelsScrollViewWithText.setVisibility(View.VISIBLE);
frameLabels.removeAllViews();
for (int i = 0; i < issue.getLabels().size(); i++) {
String labelColor = issue.getLabels().get(i).getColor();
String labelName = issue.getLabels().get(i).getName();
int color = Color.parseColor("#" + labelColor);
ImageView labelsView = new ImageView(context);
frameLabels.setOrientation(LinearLayout.HORIZONTAL);
frameLabels.setGravity(Gravity.START | Gravity.TOP);
labelsView.setLayoutParams(params);
int height = AppUtil.getPixelsFromDensity(context, 20);
int textSize = AppUtil.getPixelsFromScaledDensity(context, 12);
TextDrawable drawable =
TextDrawable.builder()
.beginConfig()
.useFont(typeface)
.textColor(new ColorInverter().getContrastColor(color))
.fontSize(textSize)
.width(
LabelWidthCalculator.calculateLabelWidth(
labelName,
typeface,
textSize,
AppUtil.getPixelsFromDensity(context, 8)))
.height(height)
.endConfig()
.buildRoundRect(
labelName,
color,
AppUtil.getPixelsFromDensity(context, 18));
labelsView.setImageDrawable(drawable);
frameLabels.addView(labelsView);
}
}
}*/
/*if (issue.getComments() > 15) {
commentIcon.setImageDrawable(
ContextCompat.getDrawable(context, R.drawable.ic_flame));
commentIcon.setColorFilter(
context.getResources().getColor(R.color.releasePre, null));
}*/
/*this.issueCreatedTime.setText(TimeHelper.formatTime(issue.getCreatedAt(), locale));
this.issueCreatedTime.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(issue.getCreatedAt()),
context));*/
}
}
}

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Handler;
@ -18,6 +19,7 @@ import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.text.HtmlCompat;
import androidx.core.widget.ImageViewCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.vdurmont.emoji.EmojiParser;
@ -106,6 +108,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
private final ImageView assigneeAvatar;
private final TextView prTitle;
private final ImageView issuePrState;
private final TextView prCreatedTime;
private final TextView prCommentsCount;
private final HorizontalScrollView labelsScrollViewWithText;
@ -120,6 +123,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
super(itemView);
assigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
prTitle = itemView.findViewById(R.id.prTitle);
issuePrState = itemView.findViewById(R.id.issuePrState);
prCommentsCount = itemView.findViewById(R.id.prCommentsCount);
prCreatedTime = itemView.findViewById(R.id.prCreatedTime);
labelsScrollViewWithText = itemView.findViewById(R.id.labelsScrollViewWithText);
@ -284,6 +288,23 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
+ pullRequest.getNumber()
+ "</font>";
if (pullRequest.getTitle().contains("[WIP]")
|| pullRequest.getTitle().contains("[wip]")) {
this.issuePrState.setVisibility(View.VISIBLE);
this.issuePrState.setImageResource(R.drawable.ic_draft);
ImageViewCompat.setImageTintList(
this.issuePrState,
ColorStateList.valueOf(
context.getResources().getColor(R.color.colorWhite, null)));
this.issuePrState.setBackgroundResource(R.drawable.shape_draft_release);
this.issuePrState.setPadding(
R.dimen.dimen8dp, R.dimen.dimen2dp, R.dimen.dimen8dp, R.dimen.dimen2dp);
this.prTitle.setPadding(
R.dimen.dimen16dp, R.dimen.dimen0dp, R.dimen.dimen0dp, R.dimen.dimen0dp);
} else {
this.issuePrState.setVisibility(View.GONE);
}
this.prTitle.setText(
HtmlCompat.fromHtml(
prNumber_ + " " + EmojiParser.parseToUnicode(pullRequest.getTitle()),

View File

@ -9,60 +9,68 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import java.util.ArrayList;
import java.util.List;
import org.gitnex.tea4j.v2.models.Activity;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.adapters.NotesAdapter;
import org.mian.gitnex.database.models.Notes;
import org.mian.gitnex.databinding.FragmentNotesBinding;
import org.mian.gitnex.adapters.DashboardAdapter;
import org.mian.gitnex.databinding.FragmentDashboardBinding;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.viewmodels.DashboardViewModel;
/**
* @author M M Arif
*/
public class DashboardFragment extends Fragment {
private FragmentNotesBinding binding;
private Context ctx;
private NotesAdapter adapter;
private List<Notes> notesList;
protected TinyDB tinyDB;
private DashboardViewModel dashboardViewModel;
private FragmentDashboardBinding binding;
private DashboardAdapter adapter;
private List<Activity> activityList;
private int page = 1;
private String username;
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentNotesBinding.inflate(inflater, container, false);
binding = FragmentDashboardBinding.inflate(inflater, container, false);
ctx = getContext();
Context ctx = getContext();
setHasOptionsMenu(true);
((MainActivity) requireActivity())
.setActionBarTitle(getResources().getString(R.string.dashboard));
notesList = new ArrayList<>();
activityList = new ArrayList<>();
dashboardViewModel = new ViewModelProvider(this).get(DashboardViewModel.class);
username = ((BaseActivity) requireActivity()).getAccount().getAccount().getUserName();
binding.recyclerView.setHasFixedSize(true);
binding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
binding.recyclerView.setPadding(0, 0, 0, 220);
binding.recyclerView.setClipToPadding(false);
adapter = new NotesAdapter(ctx, notesList);
adapter = new DashboardAdapter(activityList, ctx);
binding.pullToRefresh.setOnRefreshListener(
() ->
new Handler(Looper.getMainLooper())
.postDelayed(
() -> {
notesList.clear();
activityList.clear();
binding.pullToRefresh.setRefreshing(false);
binding.progressBar.setVisibility(View.VISIBLE);
// fetchDataAsync();
fetchDataAsync(username);
},
250));
// fetchDataAsync();
fetchDataAsync(username);
return binding.getRoot();
}
@ -70,6 +78,46 @@ public class DashboardFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
// fetchDataAsync();
fetchDataAsync(username);
}
private void fetchDataAsync(String username) {
dashboardViewModel
.getActivitiesList(username, getContext(), binding)
.observe(
getViewLifecycleOwner(),
activityListMain -> {
adapter = new DashboardAdapter(activityListMain, getContext());
adapter.setLoadMoreListener(
new DashboardAdapter.OnLoadMoreListener() {
@Override
public void onLoadMore() {
page += 1;
dashboardViewModel.loadMoreActivities(
username, page, getContext(), adapter, binding);
binding.progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onLoadFinished() {
binding.progressBar.setVisibility(View.GONE);
}
});
if (adapter.getItemCount() > 0) {
binding.recyclerView.setAdapter(adapter);
binding.noData.setVisibility(View.GONE);
} else {
adapter.notifyDataChanged();
binding.recyclerView.setAdapter(adapter);
binding.noData.setVisibility(View.VISIBLE);
}
binding.progressBar.setVisibility(View.GONE);
});
}
}

View File

@ -0,0 +1,114 @@
package org.mian.gitnex.viewmodels;
import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.List;
import org.gitnex.tea4j.v2.models.Activity;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.DashboardAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.FragmentDashboardBinding;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.Toasty;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* @author M M Arif
*/
public class DashboardViewModel extends ViewModel {
private MutableLiveData<List<Activity>> activityList;
private int resultLimit;
public LiveData<List<Activity>> getActivitiesList(
String username, Context ctx, FragmentDashboardBinding binding) {
activityList = new MutableLiveData<>();
resultLimit = Constants.getCurrentResultLimit(ctx);
loadActivityList(username, ctx, binding);
return activityList;
}
public void loadActivityList(String username, Context ctx, FragmentDashboardBinding binding) {
Call<List<Activity>> call =
RetrofitClient.getApiInterface(ctx)
.userListActivityFeeds(username, false, null, 1, resultLimit);
call.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<List<Activity>> call,
@NonNull Response<List<Activity>> response) {
if (response.isSuccessful()) {
activityList.postValue(response.body());
} else {
binding.progressBar.setVisibility(View.GONE);
Toasty.error(ctx, ctx.getString(R.string.genericError));
}
}
@Override
public void onFailure(
@NonNull Call<List<Activity>> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getString(R.string.genericServerResponseError));
}
});
}
public void loadMoreActivities(
String username,
int page,
Context ctx,
DashboardAdapter adapter,
FragmentDashboardBinding binding) {
Call<List<Activity>> call =
RetrofitClient.getApiInterface(ctx)
.userListActivityFeeds(username, false, null, page, resultLimit);
call.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<List<Activity>> call,
@NonNull Response<List<Activity>> response) {
if (response.isSuccessful()) {
List<Activity> list = activityList.getValue();
assert list != null;
assert response.body() != null;
if (response.body().size() != 0) {
list.addAll(response.body());
adapter.updateList(list);
} else {
adapter.setMoreDataAvailable(false);
}
} else {
binding.progressBar.setVisibility(View.GONE);
Toasty.error(ctx, ctx.getString(R.string.genericError));
}
}
@Override
public void onFailure(
@NonNull Call<List<Activity>> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getString(R.string.genericServerResponseError));
}
});
}
}

View File

@ -0,0 +1,48 @@
<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="M6,18m-2,0a2,2 0,1 0,4 0a2,2 0,1 0,-4 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M6,6m-2,0a2,2 0,1 0,4 0a2,2 0,1 0,-4 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M18,18m-2,0a2,2 0,1 0,4 0a2,2 0,1 0,-4 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M6,8v8"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M18,11h0.01"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M18,6h0.01"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
</vector>

View File

@ -8,7 +8,7 @@
</solid>
<corners
android:radius="18dp">
android:radius="@dimen/dimen6dp">
</corners>
</shape>

View File

@ -8,7 +8,7 @@
</solid>
<corners
android:radius="18dp">
android:radius="@dimen/dimen6dp">
</corners>
</shape>

View File

@ -8,7 +8,7 @@
</solid>
<corners
android:radius="18dp">
android:radius="@dimen/dimen6dp">
</corners>
</shape>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".activities.RepoDetailActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:padding="@dimen/dimen8dp">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</FrameLayout>
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
app:indicatorColor="?attr/progressIndicatorColor" />
<TextView
android:id="@+id/noData"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/dimen16dp"
android:text="@string/noDataFound"
android:textColor="?attr/primaryTextColor"
android:gravity="center"
android:textSize="@dimen/dimen18sp"
android:visibility="gone" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,139 @@
<?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:id="@+id/relativeLayoutFrameIssuesList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/dimen4dp"
android:paddingBottom="@dimen/dimen4dp"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?attr/materialCardViewElevatedStyle"
app:cardElevation="@dimen/dimen0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackground"
android:background="?attr/materialCardBackgroundColor"
android:padding="@dimen/dimen12dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/info_section"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<com.google.android.material.card.MaterialCardView
android:layout_width="@dimen/dimen24dp"
android:layout_height="@dimen/dimen24dp"
style="?attr/materialCardViewElevatedStyle"
app:cardElevation="@dimen/dimen0dp"
android:layout_marginEnd="@dimen/dimen12dp"
app:cardCornerRadius="@dimen/dimen12dp">
<ImageView
android:id="@+id/user_avatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/generalImgContentText"
tools:src="@tools:sample/avatars"/>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:id="@+id/header_detail_section"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/type_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="top|center_vertical"
android:text="@string/newIssueTitle"
android:textAlignment="gravity"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp"
tools:text="Id illum odio repellat omnis fuga deserunt aut. Ut est aut similique qui incidunt quia et." />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/dash_text_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone"
android:layout_marginTop="@dimen/dimen16dp">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/dash_info_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:layout_marginTop="@dimen/dimen16dp">
<TextView
android:id="@+id/created_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp"
tools:text="25.08.2023" />
<LinearLayout
android:id="@+id/type"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginStart="@dimen/dimen10dp"
android:layout_marginEnd="@dimen/dimen0dp"
android:layout_weight="1"
android:gravity="end"
android:orientation="horizontal"
android:paddingStart="@dimen/dimen4dp"
android:paddingEnd="@dimen/dimen0dp"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/type_icon"
android:layout_width="@dimen/dimen16dp"
android:layout_height="@dimen/dimen16dp"
android:layout_marginStart="@dimen/dimen2dp"
android:layout_marginEnd="@dimen/dimen4dp"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_comment"
app:tint="?attr/iconsColor" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>

View File

@ -54,15 +54,33 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/prTitle"
android:layout_width="wrap_content"
<LinearLayout
android:id="@+id/titleStateSection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top|center_vertical"
android:textAlignment="gravity"
android:text="@string/newIssueTitle"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp" />
android:orientation="horizontal">
<ImageView
android:id="@+id/issuePrState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
android:paddingStart="@dimen/dimen0dp"
android:paddingEnd="@dimen/dimen8dp"
android:src="@drawable/ic_issue"
android:visibility="gone" />
<TextView
android:id="@+id/prTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="top|center_vertical"
android:textAlignment="gravity"
android:text="@string/newIssueTitle"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
<HorizontalScrollView
android:id="@+id/labelsScrollViewDots"

View File

@ -112,8 +112,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_stable_release"
android:paddingStart="@dimen/dimen8dp"
android:paddingEnd="@dimen/dimen8dp"
android:paddingStart="@dimen/dimen6dp"
android:paddingEnd="@dimen/dimen6dp"
android:paddingTop="@dimen/dimen2dp"
android:paddingBottom="@dimen/dimen2dp"
android:textColor="@color/colorWhite"
android:textSize="@dimen/dimen14sp" />