Refactor issues (#380)

new strings for tabs

Merge branch 'refactor-issues' of gitea.com:gitnex/GitNex into refactor-issues

Fix conflicts and files refactors

Merge branch 'master' into refactor-issues

Merge branch 'master' into refactor-issues

refactored closed issues in new tab

Added gitea ver check, minor ui fixes

Merge branch 'master' into refactor-issues

# Conflicts:
#	app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java

Refactored open issues

Added parent fragment

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/380
This commit is contained in:
M M Arif 2020-04-14 20:55:04 +00:00
parent b8d8b34b0e
commit 7caecadb32
27 changed files with 811 additions and 858 deletions

View File

@ -29,7 +29,7 @@ android {
configurations {
cleanedAnnotations
compile.exclude group: 'org.jetbrains' , module:'annotations'
compile.exclude group: 'org.jetbrains', module: 'annotations'
}
dependencies {

View File

@ -27,7 +27,7 @@ import com.mikepenz.fastadapter_extensions.items.ProgressItem;
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.items.CommitsItems;
import org.mian.gitnex.adapters.CommitsAdapter;
import org.mian.gitnex.models.Commits;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
@ -42,7 +42,7 @@ import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
* Author M M Arif
*/
public class CommitsActivity extends BaseActivity implements ItemFilterListener<CommitsItems> {
public class CommitsActivity extends BaseActivity implements ItemFilterListener<CommitsAdapter> {
private View.OnClickListener onClickListener;
private TextView noData;
@ -52,8 +52,8 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
private int resultLimit = 50;
private boolean loadNextFlag = false;
private List<CommitsItems> items = new ArrayList<>();
private FastItemAdapter<CommitsItems> fastItemAdapter;
private List<CommitsAdapter> items = new ArrayList<>();
private FastItemAdapter<CommitsAdapter> fastItemAdapter;
private ItemAdapter footerAdapter;
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
@ -103,7 +103,7 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
//noinspection unchecked
fastItemAdapter.addAdapter(1, footerAdapter);
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<CommitsItems>) (item, constraint) -> item.getCommitTitle().toLowerCase().contains(Objects.requireNonNull(constraint).toString().toLowerCase()));
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<CommitsAdapter>) (item, constraint) -> item.getCommitTitle().toLowerCase().contains(Objects.requireNonNull(constraint).toString().toLowerCase()));
fastItemAdapter.getItemFilter().withItemFilterListener(this);
@ -164,7 +164,7 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
for (int i = 0; i < response.body().size(); i++) {
items.add(new CommitsItems(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(), response.body().get(i).getHtml_url(),
items.add(new CommitsAdapter(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(), response.body().get(i).getHtml_url(),
response.body().get(i).getCommit().getCommitter().getName(), response.body().get(i).getCommit().getCommitter().getDate()));
}
@ -229,7 +229,7 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
for (int i = 0; i < response.body().size(); i++) {
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new CommitsItems(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(),
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new CommitsAdapter(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(),
response.body().get(i).getHtml_url(), response.body().get(i).getCommit().getCommitter().getName(),
response.body().get(i).getCommit().getCommitter().getDate()));
@ -304,7 +304,7 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
}
@Override
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<CommitsItems> results) {
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<CommitsAdapter> results) {
endlessRecyclerOnScrollListener.disable();
}

View File

@ -27,10 +27,9 @@ import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetRepoFragment;
import org.mian.gitnex.fragments.BranchesFragment;
import org.mian.gitnex.fragments.IssuesClosedFragment;
import org.mian.gitnex.fragments.CollaboratorsFragment;
import org.mian.gitnex.fragments.FilesFragment;
import org.mian.gitnex.fragments.IssuesOpenFragment;
import org.mian.gitnex.fragments.IssuesMainFragment;
import org.mian.gitnex.fragments.LabelsFragment;
import org.mian.gitnex.fragments.MilestonesFragment;
import org.mian.gitnex.fragments.PullRequestsFragment;
@ -126,7 +125,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
}
// only show Collaborators if you have permission to
final View collaboratorTab = vg.getChildAt(9);
final View collaboratorTab = vg.getChildAt(8);
if (tinyDb.getBoolean("isRepoAdmin")) {
collaboratorTab.setVisibility(View.VISIBLE);
}
@ -166,8 +165,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
// pull count
if (textViewBadgePull.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(4)).setCustomView(tabHeader4);
TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(4);
Objects.requireNonNull(tabLayout.getTabAt(3)).setCustomView(tabHeader4);
TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(3);
assert tabOpenPulls != null;
TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText);
openPullTabView.setTextColor(textColor);
@ -176,8 +175,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
// release count
if (VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) {
if(textViewBadgeRelease.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(6)).setCustomView(tabHeader6);
TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(6);
Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6);
TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5);
assert tabOpenRelease != null;
TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText);
openReleaseTabView.setTextColor(textColor);
@ -305,23 +304,20 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
case 1: // files
return FilesFragment.newInstance(repoOwner, repoName);
case 2: // issues
fragment = new IssuesOpenFragment();
fragment = new IssuesMainFragment();
break;
case 3: // closed issues
fragment = new IssuesClosedFragment();
break;
case 4: // pull requests
case 3: // pull requests
fragment = new PullRequestsFragment();
break;
case 5: // branches
case 4: // branches
return BranchesFragment.newInstance(repoOwner, repoName);
case 6: // releases
case 5: // releases
return ReleasesFragment.newInstance(repoOwner, repoName);
case 7: // milestones
case 6: // milestones
return MilestonesFragment.newInstance(repoOwner, repoName);
case 8: // labels
case 7: // labels
return LabelsFragment.newInstance(repoOwner, repoName);
case 9: // collaborators
case 8: // collaborators
return CollaboratorsFragment.newInstance(repoOwner, repoName);
}
assert fragment != null;
@ -330,7 +326,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
@Override
public int getCount() {
return 10;
return 9;
}
}

View File

@ -1,275 +0,0 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/**
* Author M M Arif
*/
public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private Context context;
private final int TYPE_LOAD = 0;
private List<Issues> issuesList;
private List<Issues> issuesListFull;
private ClosedIssuesAdapter.OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public ClosedIssuesAdapter(Context context, List<Issues> issuesListMain) {
this.context = context;
this.issuesList = issuesListMain;
issuesListFull = new ArrayList<>(issuesList);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD){
return new ClosedIssuesAdapter.IssuesHolder(inflater.inflate(R.layout.list_issues, parent,false));
}
else {
return new ClosedIssuesAdapter.LoadHolder(inflater.inflate(R.layout.row_load,parent,false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((ClosedIssuesAdapter.IssuesHolder)holder).bindData(issuesList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(issuesList.get(position).getTitle() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return issuesList.size();
}
class IssuesHolder extends RecyclerView.ViewHolder {
private TextView issueNumber;
private ImageView issueAssigneeAvatar;
private TextView issueTitle;
private TextView issueCreatedTime;
private TextView issueCommentsCount;
private RelativeLayout relativeLayoutFrame;
IssuesHolder(View itemView) {
super(itemView);
issueNumber = itemView.findViewById(R.id.issueNumber);
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
relativeLayoutFrame = itemView.findViewById(R.id.relativeLayoutFrame);
issueTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
}
});
frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
}
});
}
@SuppressLint("SetTextI18n")
void bindData(Issues issuesModel){
final TinyDB tinyDb = new TinyDB(context);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
/*if(issuesModel.getPull_request() != null) {
if (issuesModel.getPull_request().isMerged()) {
relativeLayoutFrame.setVisibility(View.GONE);
relativeLayoutFrame.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
}
}*/
if (!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} else {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context));
}
if (issuesModel.getUser().getAvatar_url() != null) {
PicassoService.getInstance(context).get().load(issuesModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} else {
PicassoService.getInstance(context).get().load(issuesModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
}
String issueNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle()));
issueNumber.setText(String.valueOf(issuesModel.getNumber()));
issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
issueCreatedTime.setText(TimeHelper.formatTime(issuesModel.getClosed_at(), new Locale(locale), timeFormat, context));
if(timeFormat.equals("pretty")) {
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getClosed_at()), context));
}
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(ClosedIssuesAdapter.OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
@Override
public Filter getFilter() {
return issuesFilter;
}
private Filter issuesFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Issues> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(issuesList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Issues item : issuesList) {
if (item.getTitle().toLowerCase().contains(filterPattern) || item.getBody().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
issuesList.clear();
issuesList.addAll((List) results.values);
notifyDataSetChanged();
}
};
}

View File

@ -1,4 +1,4 @@
package org.mian.gitnex.items;
package org.mian.gitnex.adapters;
import android.content.Context;
import android.text.Html;
@ -12,9 +12,6 @@ import org.mian.gitnex.R;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@ -23,7 +20,7 @@ import java.util.Locale;
* Author M M Arif
*/
public class CommitsItems extends AbstractItem<CommitsItems, CommitsItems.ViewHolder> {
public class CommitsAdapter extends AbstractItem<CommitsAdapter, CommitsAdapter.ViewHolder> {
final private Context ctx;
private String commitTitle;
@ -33,11 +30,11 @@ public class CommitsItems extends AbstractItem<CommitsItems, CommitsItems.ViewHo
private boolean isSelectable = true;
public CommitsItems(Context ctx) {
public CommitsAdapter(Context ctx) {
this.ctx = ctx;
}
public CommitsItems withNewItems(String commitTitle, String commitHtmlUrl, String commitCommitter, Date commitDate) {
public CommitsAdapter withNewItems(String commitTitle, String commitHtmlUrl, String commitCommitter, Date commitDate) {
this.setNewItems(commitTitle, commitHtmlUrl, commitCommitter, commitDate);
return this;
@ -75,7 +72,7 @@ public class CommitsItems extends AbstractItem<CommitsItems, CommitsItems.ViewHo
}
@Override
public CommitsItems withEnabled(boolean enabled) {
public CommitsAdapter withEnabled(boolean enabled) {
return null;
}
@ -85,7 +82,7 @@ public class CommitsItems extends AbstractItem<CommitsItems, CommitsItems.ViewHo
}
@Override
public CommitsItems withSelectable(boolean selectable) {
public CommitsAdapter withSelectable(boolean selectable) {
this.isSelectable = selectable;
return this;
@ -104,13 +101,13 @@ public class CommitsItems extends AbstractItem<CommitsItems, CommitsItems.ViewHo
@NonNull
@Override
public CommitsItems.ViewHolder getViewHolder(@NonNull View v) {
public CommitsAdapter.ViewHolder getViewHolder(@NonNull View v) {
return new CommitsItems.ViewHolder(v);
return new CommitsAdapter.ViewHolder(v);
}
public class ViewHolder extends FastAdapter.ViewHolder<CommitsItems> {
public class ViewHolder extends FastAdapter.ViewHolder<CommitsAdapter> {
final TinyDB tinyDb = new TinyDB(ctx);
final String locale = tinyDb.getString("locale");
@ -133,7 +130,7 @@ public class CommitsItems extends AbstractItem<CommitsItems, CommitsItems.ViewHo
}
@Override
public void bindView(CommitsItems item, @NonNull List<Object> payloads) {
public void bindView(CommitsAdapter item, @NonNull List<Object> payloads) {
commitTitleVw.setText(item.getCommitTitle());
commitCommitterVw.setText(ctx.getString(R.string.commitCommittedBy, item.getcommitCommitter()));
@ -150,7 +147,7 @@ public class CommitsItems extends AbstractItem<CommitsItems, CommitsItems.ViewHo
}
@Override
public void unbindView(@NonNull CommitsItems item) {
public void unbindView(@NonNull CommitsAdapter item) {
commitTitleVw.setText(null);
commitCommitterVw.setText(null);

View File

@ -1,271 +1,245 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.items.AbstractItem;
import com.mikepenz.fastadapter.listeners.ClickEventHook;
import com.mikepenz.fastadapter.utils.EventHookUtil;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/**
* Author M M Arif
*/
public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
public class IssuesAdapter extends AbstractItem<IssuesAdapter, IssuesAdapter.ViewHolder> {
final private Context ctx;
private String issueTitle;
private int issueNumber;
private String issueAssigneeAvatar;
private Date issueCreatedTime;
private int issueCommentsCount;
private String userFullname;
private String userLogin;
private boolean isSelectable = true;
public IssuesAdapter(Context ctx) {
this.ctx = ctx;
}
private Context context;
private final int TYPE_LOAD = 0;
private List<Issues> issuesList;
private List<Issues> issuesListFull;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public IssuesAdapter withNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) {
public IssuesAdapter(Context context, List<Issues> issuesListMain) {
this.setNewItems(issueTitle, issueNumber, issueAssigneeAvatar, issueCreatedTime, issueCommentsCount, userFullname, userLogin);
return this;
}
private void setNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) {
this.context = context;
this.issuesList = issuesListMain;
issuesListFull = new ArrayList<>(issuesList);
this.issueTitle = issueTitle;
this.issueNumber = issueNumber;
this.issueAssigneeAvatar = issueAssigneeAvatar;
this.issueCreatedTime = issueCreatedTime;
this.issueCommentsCount = issueCommentsCount;
this.userFullname = userFullname;
this.userLogin = userLogin;
}
private int getIssueNumber() {
return issueNumber;
}
}
public String getIssueTitle() {
return issueTitle;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
private String getIssueAssigneeAvatar() {
return issueAssigneeAvatar;
}
LayoutInflater inflater = LayoutInflater.from(context);
private Date getIssueCreatedTime() {
return issueCreatedTime;
}
private int getIssueCommentsCount() {
return issueCommentsCount;
}
private String getUserFullname() {
return userFullname;
}
private String getUserLogin() {
return userLogin;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public IssuesAdapter withEnabled(boolean enabled) {
return null;
}
@Override
public boolean isSelectable() {
return isSelectable;
}
@Override
public IssuesAdapter withSelectable(boolean selectable) {
this.isSelectable = selectable;
return this;
}
@Override
public int getType() {
return R.id.relativeLayoutFrameIssuesList;
}
if(viewType == TYPE_LOAD){
return new IssuesHolder(inflater.inflate(R.layout.list_issues, parent,false));
}
else {
return new LoadHolder(inflater.inflate(R.layout.row_load,parent,false));
}
@Override
public int getLayoutRes() {
return R.layout.list_issues;
}
}
@NonNull
@Override
public IssuesAdapter.ViewHolder getViewHolder(@NonNull View v) {
return new IssuesAdapter.ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
public class ViewHolder extends FastAdapter.ViewHolder<IssuesAdapter> {
if(position >= getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null) {
final TinyDB tinyDb = new TinyDB(ctx);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
isLoading = true;
loadMoreListener.onLoadMore();
private TextView issueNumber;
private ImageView issueAssigneeAvatar;
private TextView issueTitle;
private TextView issueCreatedTime;
private TextView issueCommentsCount;
}
public ViewHolder(View itemView) {
if(getItemViewType(position) == TYPE_LOAD) {
super(itemView);
((IssuesHolder)holder).bindData(issuesList.get(position));
issueNumber = itemView.findViewById(R.id.issueNumber);
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
}
}
}
@Override
public void bindView(@NonNull IssuesAdapter item, @NonNull List<Object> payloads) {
@Override
public int getItemViewType(int position) {
if (!item.getUserFullname().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserFullname(), ctx));
}
else {
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserLogin(), ctx));
}
if(issuesList.get(position).getTitle() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
PicassoService.getInstance(ctx).get().load(item.getIssueAssigneeAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
}
String issueNumber_ = "<font color='" + ctx.getResources().getColor(R.color.lightGray) + "'>" + ctx.getResources().getString(R.string.hash) + item.getIssueNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + item.getIssueTitle()));
@Override
public int getItemCount() {
issueNumber.setText(String.valueOf(item.getIssueNumber()));
issueCommentsCount.setText(String.valueOf(item.getIssueCommentsCount()));
return issuesList.size();
switch (timeFormat) {
}
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(item.getIssueCreatedTime());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(item.getIssueCreatedTime()), ctx));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(item.getIssueCreatedTime());
issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(item.getIssueCreatedTime());
issueCreatedTime.setText(createdTime);
break;
}
class IssuesHolder extends RecyclerView.ViewHolder {
}
private TextView issueNumber;
private ImageView issueAssigneeAvatar;
private TextView issueTitle;
private TextView issueCreatedTime;
private TextView issueCommentsCount;
private RelativeLayout relativeLayoutFrame;
}
IssuesHolder(View itemView) {
@Override
public void unbindView(@NonNull IssuesAdapter item) {
super(itemView);
issueTitle.setText(null);
issueCommentsCount.setText(null);
issueCreatedTime.setText(null);
issueNumber = itemView.findViewById(R.id.issueNumber);
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
relativeLayoutFrame = itemView.findViewById(R.id.relativeLayoutFrame);
}
issueTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
public static class IssueTitleClickEvent extends ClickEventHook<IssuesAdapter> {
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
@Nullable
@Override
public List<View> onBindMany(@NonNull RecyclerView.ViewHolder viewHolder) {
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
if (viewHolder instanceof IssuesAdapter.ViewHolder) {
return EventHookUtil.toList(((ViewHolder) viewHolder).issueTitle);
}
}
});
frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
return super.onBindMany(viewHolder);
Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
}
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
@Override
public void onClick(View v, int position, @NonNull FastAdapter<IssuesAdapter> fastAdapter, IssuesAdapter item) {
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
Context context = v.getContext();
}
});
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", item.getIssueNumber());
}
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", String.valueOf(item.getIssueNumber()));
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
@SuppressLint("SetTextI18n")
void bindData(Issues issuesModel){
}
final TinyDB tinyDb = new TinyDB(context);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
/*if(issuesModel.getPull_request() != null) {
if (!issuesModel.getPull_request().isMerged()) {
relativeLayoutFrame.setVisibility(View.GONE);
relativeLayoutFrame.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
}
}*/
if (!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} else {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context));
}
PicassoService.getInstance(context).get().load(issuesModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
String issueNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle()));
issueNumber.setText(String.valueOf(issuesModel.getNumber()));
issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
issueCreatedTime.setText(TimeHelper.formatTime(issuesModel.getCreated_at(), new Locale(locale), timeFormat, context));
if(timeFormat.equals("pretty")) {
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
}
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
@Override
public Filter getFilter() {
return issuesFilter;
}
private Filter issuesFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Issues> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(issuesList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Issues item : issuesList) {
if (item.getTitle().toLowerCase().contains(filterPattern) || item.getBody().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
issuesList.clear();
issuesList.addAll((List) results.values);
notifyDataSetChanged();
}
};
}
}

View File

@ -78,7 +78,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullNameMy.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString());
tinyDb.putBoolean("resumeIssues", true);
//tinyDb.putBoolean("resumeIssues", true);
//store if user is watching this repo
{

View File

@ -84,7 +84,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putString("repoType", repoType_.getText().toString());
tinyDb.putBoolean("resumeIssues", true);
//tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
//store if user is watching this repo

View File

@ -81,7 +81,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString());
tinyDb.putBoolean("resumeIssues", true);
//tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
//store if user is watching this repo

View File

@ -81,7 +81,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString());
tinyDb.putBoolean("resumeIssues", true);
//tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
//store if user is watching this repo

View File

@ -14,45 +14,51 @@ import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.ClosedIssuesAdapter;
import org.mian.gitnex.clients.IssuesService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.adapters.IssuesAdapter;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.mikepenz.fastadapter.IItemAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter;
import com.mikepenz.fastadapter.listeners.ItemFilterListener;
import com.mikepenz.fastadapter_extensions.items.ProgressItem;
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
/**
* Author M M Arif
*/
public class IssuesClosedFragment extends Fragment {
public class IssuesClosedFragment extends Fragment implements ItemFilterListener<IssuesAdapter> {
private Context ctx;
private ProgressBar mProgressBarClosed;
private RecyclerView recyclerViewClosed;
private List<Issues> issuesListClosed;
private ClosedIssuesAdapter adapterClosed;
private ApiInterface apiClosed;
private String TAG = "closedIssuesListFragment - ";
private Context context;
private int pageSize = 1;
private boolean loadNextFlag = false;
private String TAG = StaticGlobalVariables.tagIssuesListClosed;
private TextView noDataIssuesClosed;
private String issueState = "closed";
private int resultLimit = 50;
private String requestType = "issues" ;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private String requestType = StaticGlobalVariables.issuesRequestType;
private String issueState = StaticGlobalVariables.issueStateClosed;
private List<IssuesAdapter> items = new ArrayList<>();
private FastItemAdapter<IssuesAdapter> fastItemAdapter;
private ItemAdapter footerAdapter;
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
@Nullable
@Override
@ -62,71 +68,69 @@ public class IssuesClosedFragment extends Fragment {
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
String repoFullName = tinyDb.getString("repoFullName");
//Log.i("repoFullName", tinyDb.getString("repoFullName"));
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefreshClosed);
if (VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
context = getContext();
recyclerViewClosed = v.findViewById(R.id.recyclerViewClosed);
issuesListClosed = new ArrayList<>();
mProgressBarClosed = v.findViewById(R.id.progress_barClosed);
noDataIssuesClosed = v.findViewById(R.id.noDataIssuesClosed);
mProgressBarClosed = v.findViewById(R.id.progress_barClosed);
final SwipeRefreshLayout swipeRefreshLayout = v.findViewById(R.id.pullToRefreshClosed);
RecyclerView recyclerView = v.findViewById(R.id.recyclerViewClosed);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
fastItemAdapter = new FastItemAdapter<>();
fastItemAdapter.withSelectable(true);
footerAdapter = items();
//noinspection unchecked
fastItemAdapter.addAdapter(StaticGlobalVariables.issuesPageInit, footerAdapter);
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<IssuesAdapter>) (item, constraint) -> item.getIssueTitle().toLowerCase().contains(constraint.toString().toLowerCase()));
fastItemAdapter.getItemFilter().withItemFilterListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(fastItemAdapter);
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) {
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
public void onLoadMore(final int currentPage) {
swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, issueState, resultLimit, requestType);
adapterClosed.notifyDataChanged();
}
}, 200);
}
});
adapterClosed = new ClosedIssuesAdapter(getContext(), issuesListClosed);
adapterClosed.setLoadMoreListener(new ClosedIssuesAdapter.OnLoadMoreListener() {
@Override
public void onLoadMore() {
recyclerViewClosed.post(new Runnable() {
@Override
public void run() {
if(issuesListClosed.size() == 10 || pageSize == 10) {
int page = (issuesListClosed.size() + 10) / 10;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, issueState, resultLimit, requestType);
}
/*else {
Toasty.info(context, getString(R.string.noMoreData));
}*/
}
});
loadNext(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, issueState, requestType, currentPage);
}
};
swipeRefreshLayout.setOnRefreshListener(() -> {
mProgressBarClosed.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
swipeRefreshLayout.setRefreshing(false);
});
recyclerViewClosed.setHasFixedSize(true);
recyclerViewClosed.setLayoutManager(new LinearLayoutManager(context));
recyclerViewClosed.setAdapter(adapterClosed);
recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
apiClosed = IssuesService.createService(ApiInterface.class, instanceUrl, getContext());
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, issueState, resultLimit, requestType);
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, issueState, resultLimit, requestType);
fastItemAdapter.withEventHook(new IssuesAdapter.IssueTitleClickEvent());
assert savedInstanceState != null;
fastItemAdapter.withSavedInstanceState(savedInstanceState);
return v;
@ -137,25 +141,21 @@ public class IssuesClosedFragment extends Fragment {
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("resumeClosedIssues")) {
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, issueState, resultLimit, requestType);
mProgressBarClosed.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
tinyDb.putBoolean("resumeClosedIssues", false);
}
}
private void loadInitial(String token, String repoOwner, String repoName, String issueState, int resultLimit, String requestType) {
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, String issueState, int resultLimit, String requestType) {
Call<List<Issues>> call = apiClosed.getClosedIssues(token, repoOwner, repoName, 1, issueState, resultLimit, requestType);
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getClosedIssues(token, repoOwner, repoName, 1, issueState, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@ -167,27 +167,34 @@ public class IssuesClosedFragment extends Fragment {
assert response.body() != null;
if(response.body().size() > 0) {
issuesListClosed.clear();
issuesListClosed.addAll(response.body());
adapterClosed.notifyDataChanged();
if(response.body().size() == resultLimit) {
loadNextFlag = true;
}
for(int i = 0; i < response.body().size(); i++) {
items.add(new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
fastItemAdapter.add(items);
noDataIssuesClosed.setVisibility(View.GONE);
}
else {
issuesListClosed.clear();
adapterClosed.notifyDataChanged();
noDataIssuesClosed.setVisibility(View.VISIBLE);
}
mProgressBarClosed.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
Log.i(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
@ -195,95 +202,110 @@ public class IssuesClosedFragment extends Fragment {
}
private void loadMore(String token, String repoOwner, String repoName, int page, String issueState, int resultLimit, String requestType){
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String issueState, String requestType, final int currentPage) {
//add loading progress view
issuesListClosed.add(new Issues("load"));
adapterClosed.notifyItemInserted((issuesListClosed.size() - 1));
footerAdapter.clear();
//noinspection unchecked
footerAdapter.add(new ProgressItem().withEnabled(false));
Handler handler = new Handler();
Call<List<Issues>> call = apiClosed.getClosedIssues(token, repoOwner, repoName, page, issueState, resultLimit, requestType);
handler.postDelayed(() -> {
call.enqueue(new Callback<List<Issues>>() {
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getClosedIssues(token, repoOwner, repoName, currentPage + 1, issueState, resultLimit, requestType);
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
call.enqueue(new Callback<List<Issues>>() {
if(response.isSuccessful()){
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
//remove loading view
issuesListClosed.remove(issuesListClosed.size()-1);
if(response.isSuccessful()) {
List<Issues> result = response.body();
assert response.body() != null;
assert result != null;
if(result.size() > 0) {
if(response.body().size() > 0) {
pageSize = result.size();
issuesListClosed.addAll(result);
loadNextFlag = response.body().size() == resultLimit;
for(int i = 0; i < response.body().size(); i++) {
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
footerAdapter.clear();
mProgressBarClosed.setVisibility(View.GONE);
}
else {
footerAdapter.clear();
}
mProgressBarClosed.setVisibility(View.GONE);
}
else {
Toasty.info(context, getString(R.string.noMoreData));
adapterClosed.setMoreDataAvailable(false);
Log.i(TAG, String.valueOf(response.code()));
}
adapterClosed.notifyDataChanged();
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.i(TAG, t.toString());
}
Log.e(TAG, t.toString());
});
}
}, 1000);
if(!loadNextFlag) {
footerAdapter.clear();
}
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
//searchView.setQueryHint(getContext().getString(R.string.strFilter));
/*if(!connToInternet) {
return;
}*/
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapterClosed.getFilter().filter(newText);
return false;
fastItemAdapter.filter(newText);
return true;
}
});
endlessRecyclerOnScrollListener.enable();
}
@Override
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<IssuesAdapter> results) {
endlessRecyclerOnScrollListener.disable();
}
@Override
public void onReset() {
endlessRecyclerOnScrollListener.enable();
}
}

View File

@ -0,0 +1,155 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.google.android.material.tabs.TabLayout;
import org.mian.gitnex.R;
import org.mian.gitnex.util.TinyDB;
import java.util.Objects;
/**
* Author M M Arif
*/
public class IssuesMainFragment extends Fragment {
private Context ctx;
public IssuesMainFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_issues_main, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
SectionsPagerAdapter mSectionsPagerAdapter = new IssuesMainFragment.SectionsPagerAdapter(getChildFragmentManager());
ViewPager mViewPager = v.findViewById(R.id.issuesContainer);
mViewPager.setAdapter(mSectionsPagerAdapter);
Typeface myTypeface;
if(tinyDb.getInt("customFontId") == 0) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf");
}
else if (tinyDb.getInt("customFontId") == 1) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/manroperegular.ttf");
}
else if (tinyDb.getInt("customFontId") == 2) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf");
}
TabLayout tabLayout = v.findViewById(R.id.tabs);
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildCount = vgTab.getChildCount();
for (int i = 0; i < tabChildCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(myTypeface);
}
}
}
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
return v;
}
public static class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0: // open issues
fragment = new IssuesOpenFragment();
break;
case 1: // closed issues
fragment = new IssuesClosedFragment();
break;
}
assert fragment != null;
return fragment;
}
@Override
public int getCount() {
return 2;
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
Objects.requireNonNull(getActivity()).getMenuInflater().inflate(R.menu.repo_dotted_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
return true;
case R.id.repoMenu:
BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment();
bottomSheet.show(getChildFragmentManager(), "repoBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}

View File

@ -1,10 +1,10 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@ -22,266 +22,287 @@ import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.mikepenz.fastadapter.IItemAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter;
import com.mikepenz.fastadapter.listeners.ItemFilterListener;
import com.mikepenz.fastadapter_extensions.items.ProgressItem;
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.adapters.IssuesAdapter;
import org.mian.gitnex.clients.IssuesService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
/**
* Author M M Arif
*/
public class IssuesOpenFragment extends Fragment {
private ProgressBar mProgressBar;
private RecyclerView recyclerView;
private List<Issues> issuesList;
private IssuesAdapter adapter;
private ApiInterface api;
private String TAG = "IssuesListFragment - ";
private Context context;
private int pageSize = 1;
private TextView noDataIssues;
private int resultLimit = 50;
private String requestType = "issues";
public class IssuesOpenFragment extends Fragment implements ItemFilterListener<IssuesAdapter> {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
private ProgressBar mProgressBar;
private boolean loadNextFlag = false;
private String TAG = StaticGlobalVariables.tagIssuesListOpen;
private TextView noDataIssues;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private String requestType = StaticGlobalVariables.issuesRequestType;
final View v = inflater.inflate(R.layout.fragment_issues, container, false);
setHasOptionsMenu(true);
private List<IssuesAdapter> items = new ArrayList<>();
private FastItemAdapter<IssuesAdapter> fastItemAdapter;
private ItemAdapter footerAdapter;
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
TinyDB tinyDb = new TinyDB(getContext());
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
final View v = inflater.inflate(R.layout.fragment_issues, container, false);
setHasOptionsMenu(true);
context = getContext();
recyclerView = v.findViewById(R.id.recyclerView);
issuesList = new ArrayList<>();
TinyDB tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
mProgressBar = v.findViewById(R.id.progress_bar);
noDataIssues = v.findViewById(R.id.noDataIssues);
if (VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
noDataIssues = v.findViewById(R.id.noDataIssues);
mProgressBar = v.findViewById(R.id.progress_bar);
final SwipeRefreshLayout swipeRefreshLayout = v.findViewById(R.id.pullToRefresh);
swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, resultLimit, requestType);
adapter.notifyDataChanged();
RecyclerView recyclerView = v.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
}
}, 200);
}
});
fastItemAdapter = new FastItemAdapter<>();
fastItemAdapter.withSelectable(true);
adapter = new IssuesAdapter(getContext(), issuesList);
adapter.setLoadMoreListener(new IssuesAdapter.OnLoadMoreListener() {
@Override
public void onLoadMore() {
footerAdapter = items();
//noinspection unchecked
fastItemAdapter.addAdapter(StaticGlobalVariables.issuesPageInit, footerAdapter);
recyclerView.post(new Runnable() {
@Override
public void run() {
if(issuesList.size() == 10 || pageSize == 10) {
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<IssuesAdapter>) (item, constraint) -> item.getIssueTitle().toLowerCase().contains(constraint.toString().toLowerCase()));
int page = (issuesList.size() + 10) / 10;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, requestType);
fastItemAdapter.getItemFilter().withItemFilterListener(this);
}
/*else {
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(fastItemAdapter);
Toasty.info(context, getString(R.string.noMoreData));
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) {
}*/
}
});
@Override
public void onLoadMore(final int currentPage) {
}
});
loadNext(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, requestType, currentPage);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
}
api = IssuesService.createService(ApiInterface.class, instanceUrl, getContext());
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType);
};
return v;
swipeRefreshLayout.setOnRefreshListener(() -> {
}
mProgressBar.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
swipeRefreshLayout.setRefreshing(false);
@Override
public void onResume() {
});
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
if(tinyDb.getBoolean("resumeIssues")) {
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, requestType);
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType);
tinyDb.putBoolean("resumeIssues", false);
fastItemAdapter.withEventHook(new IssuesAdapter.IssueTitleClickEvent());
}
assert savedInstanceState != null;
fastItemAdapter.withSavedInstanceState(savedInstanceState);
}
return v;
private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String requestType) {
}
Call<List<Issues>> call = api.getIssues(token, repoOwner, repoName, 1, resultLimit, requestType);
@Override
public void onResume() {
call.enqueue(new Callback<List<Issues>>() {
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(tinyDb.getBoolean("resumeIssues")) {
if(response.isSuccessful()) {
mProgressBar.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
tinyDb.putBoolean("resumeIssues", false);
assert response.body() != null;
if(response.body().size() > 0) {
}
issuesList.clear();
issuesList.addAll(response.body());
adapter.notifyDataChanged();
noDataIssues.setVisibility(View.GONE);
}
}
else {
issuesList.clear();
adapter.notifyDataChanged();
noDataIssues.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String requestType) {
}
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getIssues(token, repoOwner, repoName, 1, resultLimit, requestType);
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
call.enqueue(new Callback<List<Issues>>() {
});
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
}
if(response.isSuccessful()) {
private void loadMore(String token, String repoOwner, String repoName, int page, int resultLimit, String requestType){
assert response.body() != null;
if(response.body().size() > 0) {
//add loading progress view
issuesList.add(new Issues("load"));
adapter.notifyItemInserted((issuesList.size() - 1));
if(response.body().size() == resultLimit) {
loadNextFlag = true;
}
Call<List<Issues>> call = api.getIssues(token, repoOwner, repoName, page, resultLimit, requestType);
for(int i = 0; i < response.body().size(); i++) {
items.add(new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
call.enqueue(new Callback<List<Issues>>() {
fastItemAdapter.add(items);
noDataIssues.setVisibility(View.GONE);
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
}
else {
noDataIssues.setVisibility(View.VISIBLE);
}
if(response.isSuccessful()){
mProgressBar.setVisibility(View.GONE);
//remove loading view
issuesList.remove(issuesList.size()-1);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
List<Issues> result = response.body();
}
assert result != null;
if(result.size() > 0) {
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
pageSize = result.size();
issuesList.addAll(result);
Log.e(TAG, t.toString());
}
}
else {
});
Toasty.info(context, getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
}
}
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String requestType, final int currentPage) {
adapter.notifyDataChanged();
footerAdapter.clear();
//noinspection unchecked
footerAdapter.add(new ProgressItem().withEnabled(false));
Handler handler = new Handler();
}
else {
handler.postDelayed(() -> {
Log.e(TAG, String.valueOf(response.code()));
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getIssues(token, repoOwner, repoName, currentPage + 1, resultLimit, requestType);
}
call.enqueue(new Callback<List<Issues>>() {
}
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
if(response.isSuccessful()) {
Log.e(TAG, t.toString());
assert response.body() != null;
}
if(response.body().size() > 0) {
});
}
loadNextFlag = response.body().size() == resultLimit;
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
for(int i = 0; i < response.body().size(); i++) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
//searchView.setQueryHint(getContext().getString(R.string.strFilter));
footerAdapter.clear();
noDataIssues.setVisibility(View.GONE);
/*if(!connToInternet) {
return;
}*/
}
else {
footerAdapter.clear();
}
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
mProgressBar.setVisibility(View.GONE);
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
@Override
public boolean onQueryTextChange(String newText) {
}
adapter.getFilter().filter(newText);
return false;
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
}
Log.i(TAG, t.toString());
}
});
});
}
}, 1000);
if(!loadNextFlag) {
footerAdapter.clear();
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
fastItemAdapter.filter(newText);
return true;
}
});
endlessRecyclerOnScrollListener.enable();
}
@Override
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<IssuesAdapter> results) {
endlessRecyclerOnScrollListener.disable();
}
@Override
public void onReset() {
endlessRecyclerOnScrollListener.enable();
}
}

View File

@ -100,7 +100,7 @@ public class ProfileFragment extends Fragment {
public static class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull

View File

@ -0,0 +1,18 @@
package org.mian.gitnex.helpers;
/**
* Author M M Arif
*/
public interface StaticGlobalVariables {
// issues variables
String tagIssuesListOpen = "IssuesListOpenFragment - ";
String tagIssuesListClosed = "IssuesListClosedFragment - ";
int issuesPageInit = 1;
int resultLimitNewGiteaInstances = 25; // Gitea 1.12 and above
int resultLimitOldGiteaInstances = 10; // Gitea 1.11 and below
String issuesRequestType = "issues";
String issueStateClosed = "closed";
}

View File

@ -77,7 +77,7 @@
android:background="@drawable/shape_inputs"
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:textColorHighlight="?attr/primaryTextColor"/>
android:textColorHighlight="?attr/primaryTextColor" />
<TextView
android:layout_width="match_parent"
@ -102,10 +102,10 @@
android:scrollbars="vertical"
android:gravity="top|start"
android:textSize="14sp"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:inputType="textCapSentences|textMultiLine"
android:textColorHighlight="@color/white" />
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:textColorHighlight="?attr/primaryTextColor" />
<TextView
android:layout_width="match_parent"
@ -124,8 +124,8 @@
android:textSize="14sp"
tools:ignore="Autofill"
android:background="@drawable/shape_inputs"
android:textColor="?attr/primaryTextColor"
android:textColorHint="?attr/primaryTextColor"
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:inputType="none"
android:textColorHighlight="?attr/primaryTextColor"/>
@ -180,8 +180,8 @@
android:textSize="14sp"
tools:ignore="Autofill"
android:background="@drawable/shape_inputs"
android:textColor="?attr/primaryTextColor"
android:textColorHint="?attr/primaryTextColor"
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:inputType="none"
android:textColorHighlight="?attr/primaryTextColor"/>
@ -203,8 +203,8 @@
android:textSize="14sp"
tools:ignore="Autofill"
android:background="@drawable/shape_inputs"
android:textColor="?attr/primaryTextColor"
android:textColorHint="?attr/primaryTextColor"
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:textColorHighlight="?attr/primaryTextColor"/>
<Button

View File

@ -22,7 +22,7 @@
android:id="@+id/toolbar"
app:titleTextColor="?attr/primaryTextColor"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:theme="@style/Widget.AppCompat.SearchView"
android:elevation="4dp">
<TextView

View File

@ -60,13 +60,7 @@
android:id="@+id/tabItem2_issues"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tab_text_issues" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tabItemCloseIssues"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tabItemCloseIssues" />
android:text="@string/pageTitleIssues" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tabItemPullRequests"

View File

@ -11,7 +11,7 @@
android:gravity="center"
android:textSize="16sp"
app:textAllCaps="true"
android:text="@string/tab_text_issues"
android:text="@string/pageTitleIssues"
android:textColor="@color/lightGray" />
<TextView

View File

@ -0,0 +1,48 @@
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"
android:id="@+id/issuesMain">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
app:tabMode="fixed"
app:tabTextAppearance="@style/customTabLayout"
android:layout_width="match_parent"
android:background="?attr/primaryBackgroundColor"
app:tabTextColor="?attr/primaryTextColor"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem
android:id="@+id/issuesTabOpen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tabIssueOpen" />
<com.google.android.material.tabs.TabItem
android:id="@+id/issuesTabClosed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tabIssueClosed" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/issuesContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>

View File

@ -16,7 +16,7 @@
<include
android:id="@+id/timeLayout"
layout="@layout/layout_settings_appearance" />
layout="@layout/settings_appearance" />
<View
android:id="@+id/fileViewDivider"
@ -30,7 +30,7 @@
<include
android:id="@+id/fileViewLayout"
layout="@layout/layout_settings_fileview"/>
layout="@layout/settings_fileview"/>
<View
android:id="@+id/securityDivider"
@ -44,7 +44,7 @@
<include
android:id="@+id/securityLayout"
layout="@layout/layout_settings_security" />
layout="@layout/settings_security" />
<View
android:id="@+id/translationDivider"
@ -58,7 +58,7 @@
<include
android:id="@+id/langLayout"
layout="@layout/layout_settings_languages" />
layout="@layout/settings_languages" />
</RelativeLayout>

View File

@ -2,7 +2,7 @@
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayoutFrame"
android:id="@+id/relativeLayoutFrameIssuesList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"

View File

@ -165,8 +165,8 @@
<string name="infoTabRepoZero" translatable="false">0</string>
<string name="infoTabRepoDefaultBranchText" translatable="false">master</string>
<string name="infoShowMoreInformation">Show more information</string>
<string name="infoMoreInformation">More information</string>
<string name="infoShowMoreInformation">Show More Information</string>
<string name="infoMoreInformation">More Information</string>
<string name="timeAtText">at</string>
<string name="hash" translatable="false">#</string>
@ -613,4 +613,7 @@
<string name="closeMilestone">Close Milestone</string>
<string name="openMilestone">Open Milestone</string>
<string name="milestoneStatusUpdate">Milestone status updated successfully</string>
<string name="tabIssueOpen">Open</string>
<string name="tabIssueClosed">Closed</string>
</resources>