Filter issues if I am mentioned

This commit is contained in:
M M Arif
2025-03-17 00:45:17 +05:00
parent 2b8cd191fe
commit 1b8167786e
7 changed files with 331 additions and 306 deletions

View File

@@ -220,7 +220,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
} else if (id == R.id.filter) {
BottomSheetIssuesFilterFragment filterBottomSheet =
new BottomSheetIssuesFilterFragment();
BottomSheetIssuesFilterFragment.newInstance(repository);
filterBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuBottomSheet");
return true;
} else if (id == R.id.filterPr) {
@@ -269,8 +269,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
for (Label label : labelsList) {
selectedStates.put(label.getName(), false); // Initialize states
}
} else {
Toasty.error(RepoDetailActivity.this, getString(R.string.genericError));
}
}
@@ -286,6 +284,14 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
@Override
public void onButtonClicked(String text) {
if (text.startsWith("mentionedByMe:")) {
String usernameWithPrefix = text.substring("mentionedByMe:".length());
String username = "null".equals(usernameWithPrefix) ? null : usernameWithPrefix;
if (getFragmentRefreshListenerFilterIssuesByMentions() != null) {
getFragmentRefreshListenerFilterIssuesByMentions().onRefresh(username);
}
}
switch (text) {
case "filterByLabels":
showLabelFilterDialog();
@@ -416,7 +422,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
labelsContainer.addView(chip);
}
// Create the dialog
AlertDialog dialog = builder.setView(dialogView).create();
filterButton.setOnClickListener(
@@ -430,7 +435,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
getFragmentRefreshListenerFilterIssuesByLabels()
.onRefresh(selectedLabels.isEmpty() ? null : selectedLabels);
}
dialog.dismiss(); // Use the AlertDialog object to dismiss
dialog.dismiss();
});
dialog.show();
@@ -837,6 +842,24 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
});
}
// filter by mentioned
public interface FragmentRefreshListenerFilterIssuesByMentions {
void onRefresh(String username);
}
private FragmentRefreshListenerFilterIssuesByMentions
fragmentRefreshListenerFilterIssuesByMentions;
public void setFragmentRefreshListenerFilterIssuesByMentions(
FragmentRefreshListenerFilterIssuesByMentions listener) {
this.fragmentRefreshListenerFilterIssuesByMentions = listener;
}
public FragmentRefreshListenerFilterIssuesByMentions
getFragmentRefreshListenerFilterIssuesByMentions() {
return fragmentRefreshListenerFilterIssuesByMentions;
}
// filter issues by labels
public interface FragmentRefreshListenerFilterIssuesByLabels {
void onRefresh(String labels);

View File

@@ -10,6 +10,7 @@ import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.databinding.BottomSheetIssuesFilterBinding;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
import org.mian.gitnex.structs.BottomSheetListener;
/**
@@ -18,6 +19,16 @@ import org.mian.gitnex.structs.BottomSheetListener;
public class BottomSheetIssuesFilterFragment extends BottomSheetDialogFragment {
private BottomSheetListener bmListener;
private BottomSheetIssuesFilterBinding binding;
private RepositoryContext repository;
public static BottomSheetIssuesFilterFragment newInstance(RepositoryContext repository) {
BottomSheetIssuesFilterFragment fragment = new BottomSheetIssuesFilterFragment();
Bundle args = new Bundle();
args.putSerializable(RepositoryContext.INTENT_EXTRA, repository);
fragment.setArguments(args);
return fragment;
}
@Nullable @Override
public View onCreateView(
@@ -25,48 +36,90 @@ public class BottomSheetIssuesFilterFragment extends BottomSheetDialogFragment {
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
BottomSheetIssuesFilterBinding bottomSheetIssuesFilterBinding =
BottomSheetIssuesFilterBinding.inflate(inflater, container, false);
binding = BottomSheetIssuesFilterBinding.inflate(inflater, container, false);
if (((BaseActivity) requireActivity()).getAccount().requiresVersion("1.14.0")) {
bottomSheetIssuesFilterBinding.filterByMilestone.setVisibility(View.VISIBLE);
bottomSheetIssuesFilterBinding.filterByMilestone.setOnClickListener(
v1 -> {
bmListener.onButtonClicked("filterByMilestone");
dismiss();
});
if (getArguments() != null) {
repository =
(RepositoryContext)
getArguments().getSerializable(RepositoryContext.INTENT_EXTRA);
}
if (repository == null) {
throw new IllegalStateException("RepositoryContext is required");
}
bottomSheetIssuesFilterBinding.openIssues.setOnClickListener(
v1 -> {
bmListener.onButtonClicked("openIssues");
if (((BaseActivity) requireActivity()).getAccount().requiresVersion("1.14.0")) {
binding.milestoneChip.setVisibility(View.VISIBLE);
}
binding.openChip.setChecked(repository.getIssueState() == RepositoryContext.State.OPEN);
binding.closedChip.setChecked(repository.getIssueState() == RepositoryContext.State.CLOSED);
binding.mentionsChip.setChecked(repository.getMentionedBy() != null);
binding.openChip.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
if (isChecked && repository.getIssueState() != RepositoryContext.State.OPEN) {
repository.setIssueState(RepositoryContext.State.OPEN);
bmListener.onButtonClicked("openIssues");
dismiss();
} else if (!isChecked) {
buttonView.setChecked(true);
}
});
binding.closedChip.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
if (isChecked && repository.getIssueState() != RepositoryContext.State.CLOSED) {
repository.setIssueState(RepositoryContext.State.CLOSED);
bmListener.onButtonClicked("closedIssues");
dismiss();
} else if (!isChecked) {
buttonView.setChecked(true);
}
});
binding.mentionsChip.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
String username =
isChecked
? ((BaseActivity) requireActivity())
.getAccount()
.getAccount()
.getUserName()
: null;
repository.setMentionedBy(username);
bmListener.onButtonClicked(
"mentionedByMe:" + (username != null ? username : "null"));
dismiss();
});
bottomSheetIssuesFilterBinding.closedIssues.setOnClickListener(
v12 -> {
bmListener.onButtonClicked("closedIssues");
dismiss();
});
bottomSheetIssuesFilterBinding.filterByLabels.setOnClickListener(
binding.labelsChip.setOnClickListener(
v -> {
bmListener.onButtonClicked("filterByLabels");
dismiss();
});
return bottomSheetIssuesFilterBinding.getRoot();
binding.milestoneChip.setOnClickListener(
v -> {
bmListener.onButtonClicked("filterByMilestone");
dismiss();
});
return binding.getRoot();
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
bmListener = (BottomSheetListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context + " must implement BottomSheetListener");
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -51,6 +51,7 @@ public class IssuesFragment extends Fragment {
private int resultLimit;
private RepositoryContext repository;
private String selectedLabels = null;
private String mentionedBy;
public static IssuesFragment newInstance(RepositoryContext repository) {
IssuesFragment f = new IssuesFragment();
@@ -68,6 +69,7 @@ public class IssuesFragment extends Fragment {
context = getContext();
repository = RepositoryContext.fromBundle(requireArguments());
mentionedBy = repository.getMentionedBy();
boolean archived = repository.getRepository().isArchived();
@@ -91,7 +93,8 @@ public class IssuesFragment extends Fragment {
repository.getIssueState().toString(),
repository.getIssueMilestoneFilterName(),
null,
selectedLabels);
selectedLabels,
mentionedBy);
adapter.notifyDataChanged();
},
200));
@@ -112,7 +115,8 @@ public class IssuesFragment extends Fragment {
requestType,
repository.getIssueState().toString(),
repository.getIssueMilestoneFilterName(),
selectedLabels);
selectedLabels,
mentionedBy);
}
}));
@@ -128,140 +132,36 @@ public class IssuesFragment extends Fragment {
((RepoDetailActivity) requireActivity())
.setFragmentRefreshListener(
issueState -> {
issuesList.clear();
adapter = new IssuesAdapter(context, issuesList, "");
adapter.setLoadMoreListener(
() ->
fragmentIssuesBinding.recyclerView.post(
() -> {
if (issuesList.size() == resultLimit
|| pageSize == resultLimit) {
int page =
(issuesList.size()
+ resultLimit)
/ resultLimit;
loadMore(
repository.getOwner(),
repository.getName(),
page,
resultLimit,
requestType,
repository
.getIssueState()
.toString(),
repository
.getIssueMilestoneFilterName(),
selectedLabels);
}
}));
fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE);
fragmentIssuesBinding.noDataIssues.setVisibility(View.GONE);
loadInitial(
repository.getOwner(),
repository.getName(),
resultLimit,
requestType,
issueState,
repository.getIssueMilestoneFilterName(),
null,
selectedLabels);
fragmentIssuesBinding.recyclerView.setAdapter(adapter);
});
issueState -> refreshIssues(issueState, selectedLabels, mentionedBy));
((RepoDetailActivity) requireActivity())
.setFragmentRefreshListenerFilterIssuesByMilestone(
filterIssueByMilestone -> {
issuesList.clear();
adapter = new IssuesAdapter(context, issuesList, "");
adapter.setLoadMoreListener(
() ->
fragmentIssuesBinding.recyclerView.post(
() -> {
if (issuesList.size() == resultLimit
|| pageSize == resultLimit) {
int page =
(issuesList.size()
+ resultLimit)
/ resultLimit;
loadMore(
repository.getOwner(),
repository.getName(),
page,
resultLimit,
requestType,
repository
.getIssueState()
.toString(),
repository
.getIssueMilestoneFilterName(),
selectedLabels);
}
}));
fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE);
fragmentIssuesBinding.noDataIssues.setVisibility(View.GONE);
loadInitial(
repository.getOwner(),
repository.getName(),
resultLimit,
requestType,
repository.getIssueState().toString(),
filterIssueByMilestone,
null,
selectedLabels);
fragmentIssuesBinding.recyclerView.setAdapter(adapter);
});
filterIssueByMilestone ->
refreshIssues(
repository.getIssueState().toString(),
selectedLabels,
mentionedBy,
filterIssueByMilestone));
((RepoDetailActivity) requireActivity())
.setFragmentRefreshListenerFilterIssuesByLabels(
filterLabels -> {
selectedLabels = filterLabels; // Update selected labels
issuesList.clear();
adapter = new IssuesAdapter(context, issuesList, "");
adapter.setLoadMoreListener(
() ->
fragmentIssuesBinding.recyclerView.post(
() -> {
if (issuesList.size() == resultLimit
|| pageSize == resultLimit) {
int page =
(issuesList.size()
+ resultLimit)
/ resultLimit;
loadMore(
repository.getOwner(),
repository.getName(),
page,
resultLimit,
requestType,
repository
.getIssueState()
.toString(),
repository
.getIssueMilestoneFilterName(),
selectedLabels);
}
}));
fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE);
fragmentIssuesBinding.noDataIssues.setVisibility(View.GONE);
loadInitial(
repository.getOwner(),
repository.getName(),
resultLimit,
requestType,
selectedLabels = filterLabels;
refreshIssues(
repository.getIssueState().toString(),
repository.getIssueMilestoneFilterName(),
null,
selectedLabels);
fragmentIssuesBinding.recyclerView.setAdapter(adapter);
selectedLabels,
mentionedBy);
});
((RepoDetailActivity) requireActivity())
.setFragmentRefreshListenerFilterIssuesByMentions(
username -> {
mentionedBy = username;
repository.setMentionedBy(username);
refreshIssues(
repository.getIssueState().toString(),
selectedLabels,
mentionedBy);
});
loadInitial(
@@ -272,7 +172,8 @@ public class IssuesFragment extends Fragment {
repository.getIssueState().toString(),
repository.getIssueMilestoneFilterName(),
null,
selectedLabels);
selectedLabels,
mentionedBy);
getPinnedIssues(repository.getOwner(), repository.getName());
@@ -281,7 +182,6 @@ public class IssuesFragment extends Fragment {
}
if (repository.getRepository().isHasIssues() && !archived) {
fragmentIssuesBinding.createNewIssue.setVisibility(View.VISIBLE);
fragmentIssuesBinding.createNewIssue.setOnClickListener(
v12 -> {
@@ -291,18 +191,15 @@ public class IssuesFragment extends Fragment {
getContext(), CreateIssueActivity.class));
});
} else {
fragmentIssuesBinding.createNewIssue.setVisibility(View.GONE);
}
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.search_menu, menu);
menuInflater.inflate(R.menu.filter_menu, menu);
@@ -322,7 +219,6 @@ public class IssuesFragment extends Fragment {
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
loadInitial(
@@ -333,7 +229,8 @@ public class IssuesFragment extends Fragment {
repository.getIssueState().toString(),
repository.getIssueMilestoneFilterName(),
query,
selectedLabels);
selectedLabels,
mentionedBy);
searchView.setQuery(null, false);
searchItem.collapseActionView();
return false;
@@ -369,25 +266,97 @@ public class IssuesFragment extends Fragment {
repository.getIssueState().toString(),
repository.getIssueMilestoneFilterName(),
"",
selectedLabels);
selectedLabels,
mentionedBy);
getPinnedIssues(repository.getOwner(), repository.getName());
resumeIssues = false;
}
}
private void getPinnedIssues(String repoOwner, String repoName) {
private void refreshIssues(String issueState, String labels, String mentionedBy) {
issuesList.clear();
adapter = new IssuesAdapter(context, issuesList, "");
adapter.setLoadMoreListener(
() ->
fragmentIssuesBinding.recyclerView.post(
() -> {
if (issuesList.size() == resultLimit
|| pageSize == resultLimit) {
int page = (issuesList.size() + resultLimit) / resultLimit;
loadMore(
repository.getOwner(),
repository.getName(),
page,
resultLimit,
requestType,
issueState,
repository.getIssueMilestoneFilterName(),
labels,
mentionedBy);
}
}));
fragmentIssuesBinding.recyclerView.setAdapter(adapter);
fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE);
fragmentIssuesBinding.noDataIssues.setVisibility(View.GONE);
loadInitial(
repository.getOwner(),
repository.getName(),
resultLimit,
requestType,
issueState,
repository.getIssueMilestoneFilterName(),
null,
labels,
mentionedBy);
}
private void refreshIssues(
String issueState, String labels, String mentionedBy, String filterByMilestone) {
issuesList.clear();
adapter = new IssuesAdapter(context, issuesList, "");
adapter.setLoadMoreListener(
() ->
fragmentIssuesBinding.recyclerView.post(
() -> {
if (issuesList.size() == resultLimit
|| pageSize == resultLimit) {
int page = (issuesList.size() + resultLimit) / resultLimit;
loadMore(
repository.getOwner(),
repository.getName(),
page,
resultLimit,
requestType,
issueState,
filterByMilestone,
labels,
mentionedBy);
}
}));
fragmentIssuesBinding.recyclerView.setAdapter(adapter);
fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE);
fragmentIssuesBinding.noDataIssues.setVisibility(View.GONE);
loadInitial(
repository.getOwner(),
repository.getName(),
resultLimit,
requestType,
issueState,
filterByMilestone,
null,
labels,
mentionedBy);
}
private void getPinnedIssues(String repoOwner, String repoName) {
Call<List<Issue>> call =
RetrofitClient.getApiInterface(context).repoListPinnedIssues(repoOwner, repoName);
call.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<List<Issue>> call,
@NonNull Response<List<Issue>> response) {
if (response.code() == 200) {
assert response.body() != null;
if (!response.body().isEmpty()) {
@@ -425,7 +394,8 @@ public class IssuesFragment extends Fragment {
String issueState,
String filterByMilestone,
String query,
String labels) {
String labels,
String mentionedBy) {
Call<List<Issue>> call =
RetrofitClient.getApiInterface(context)
@@ -437,22 +407,20 @@ public class IssuesFragment extends Fragment {
query,
requestType,
filterByMilestone,
null,
null,
null,
null,
null,
null, // since
null, // before
null, // created_by
null, // assigned_by
mentionedBy, // mentioned_by
1,
resultLimit);
call.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<List<Issue>> call,
@NonNull Response<List<Issue>> response) {
if (response.code() == 200) {
assert response.body() != null;
if (!response.body().isEmpty()) {
@@ -491,7 +459,8 @@ public class IssuesFragment extends Fragment {
String requestType,
String issueState,
String filterByMilestone,
String labels) {
String labels,
String mentionedBy) {
fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE);
@@ -505,21 +474,20 @@ public class IssuesFragment extends Fragment {
null,
requestType,
filterByMilestone,
null,
null,
null,
null,
null,
null, // since
null, // before
null, // created_by
null, // assigned_by
mentionedBy, // mentioned_by
page,
resultLimit);
call.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<List<Issue>> call,
@NonNull Response<List<Issue>> response) {
if (response.code() == 200) {
List<Issue> result = response.body();
assert result != null;

View File

@@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import java.io.Serial;
import java.io.Serializable;
import java.util.Objects;
import org.gitnex.tea4j.v2.models.Permission;
@@ -34,6 +35,7 @@ public class RepositoryContext implements Serializable {
private boolean watched = false;
private int repositoryId = 0;
private Repository repositoryModel = null;
private String mentionedBy;
public RepositoryContext(org.gitnex.tea4j.v2.models.Repository repository, Context context) {
this.account = ((BaseActivity) context).getAccount();
@@ -57,37 +59,30 @@ public class RepositoryContext implements Serializable {
}
public State getIssueState() {
return issueState;
}
public void setIssueState(State issueState) {
this.issueState = issueState;
}
public State getMilestoneState() {
return milestoneState;
}
public void setMilestoneState(State milestoneState) {
this.milestoneState = milestoneState;
}
public State getPrState() {
return prState;
}
public void setPrState(State prState) {
this.prState = prState;
}
public org.gitnex.tea4j.v2.models.Repository getRepository() {
return repository;
}
@@ -99,12 +94,10 @@ public class RepositoryContext implements Serializable {
}
public String getBranchRef() {
return branchRef;
}
public void setBranchRef(String branchRef) {
this.branchRef = branchRef;
}
@@ -121,12 +114,10 @@ public class RepositoryContext implements Serializable {
}
public String getIssueMilestoneFilterName() {
return issueMilestoneFilterName;
}
public void setIssueMilestoneFilterName(String issueMilestoneFilterName) {
this.issueMilestoneFilterName = issueMilestoneFilterName;
}
@@ -151,45 +142,45 @@ public class RepositoryContext implements Serializable {
}
public boolean isStarred() {
return starred;
}
public void setStarred(boolean starred) {
this.starred = starred;
}
public boolean isWatched() {
return watched;
}
public void setWatched(boolean watched) {
this.watched = watched;
}
public int getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(int repositoryId) {
this.repositoryId = repositoryId;
}
public Repository getRepositoryModel() {
return repositoryModel;
}
public void setRepositoryModel(Repository repositoryModel) {
this.repositoryModel = repositoryModel;
}
public String getMentionedBy() {
return mentionedBy;
}
public void setMentionedBy(String mentionedBy) {
this.mentionedBy = mentionedBy;
}
public Repository loadRepositoryModel(Context context) {
repositoryModel =
Objects.requireNonNull(BaseApi.getInstance(context, RepositoriesApi.class))
@@ -208,17 +199,14 @@ public class RepositoryContext implements Serializable {
}
public boolean isReleasesViewTypeIsTag() {
return releasesViewTypeIsTag;
}
public void setReleasesViewTypeIsTag(boolean releasesViewTypeIsTag) {
this.releasesViewTypeIsTag = releasesViewTypeIsTag;
}
public void removeRepository() {
repository = null;
}
@@ -258,4 +246,15 @@ public class RepositoryContext implements Serializable {
return "closed";
}
}
@Serial
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
out.defaultWriteObject();
}
@Serial
private void readObject(java.io.ObjectInputStream in)
throws java.io.IOException, ClassNotFoundException {
in.defaultReadObject();
}
}

View File

@@ -9,116 +9,95 @@
android:paddingTop="@dimen/dimen6dp"
android:paddingBottom="@dimen/dimen12dp">
<androidx.core.widget.NestedScrollView
<LinearLayout
android:id="@+id/issuesFilterHeadFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/dimen8dp">
<LinearLayout
<TextView
android:id="@+id/bottomSheetHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:gravity="center"
android:text="@string/strFilter"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp"/>
<LinearLayout
android:id="@+id/issuesFilterHeadFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/dimen8dp">
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewFilledStyle"
android:layout_width="@dimen/dimen28dp"
android:layout_height="@dimen/dimen4dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen16dp"
app:cardCornerRadius="@dimen/dimen24dp"
app:cardElevation="@dimen/dimen0dp">
<TextView
android:id="@+id/bottomSheetHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/strFilter"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp"/>
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewFilledStyle"
android:layout_width="@dimen/dimen28dp"
android:layout_height="@dimen/dimen4dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen16dp"
app:cardCornerRadius="@dimen/dimen24dp"
app:cardElevation="@dimen/dimen0dp">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/fabColor" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/issuesFilterSection"
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/dimen4dp"
app:alignContent="center"
app:alignItems="flex_start"
app:flexWrap="wrap"
app:justifyContent="center">
android:background="?attr/fabColor" />
<TextView
android:id="@+id/filterByMilestone"
android:layout_width="@dimen/dimen132dp"
android:layout_height="@dimen/dimen100dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center"
android:padding="@dimen/dimen4dp"
android:text="@string/newIssueMilestoneTitle"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp"
app:drawableTopCompat="@drawable/ic_milestone"
app:layout_alignSelf="flex_start"/>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<TextView
android:id="@+id/openIssues"
android:layout_width="@dimen/dimen132dp"
android:layout_height="@dimen/dimen100dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center"
android:padding="@dimen/dimen4dp"
android:text="@string/isOpen"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp"
app:drawableTopCompat="@drawable/ic_issue"
app:layout_alignSelf="flex_start"/>
<com.google.android.material.chip.ChipGroup
android:id="@+id/stateChipGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:singleSelection="true"
android:paddingStart="@dimen/dimen16dp"
android:paddingEnd="@dimen/dimen16dp"
android:paddingBottom="@dimen/dimen8dp">
<TextView
android:id="@+id/closedIssues"
android:layout_width="@dimen/dimen132dp"
android:layout_height="@dimen/dimen100dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center"
android:padding="@dimen/dimen4dp"
android:text="@string/isClosed"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp"
app:drawableTopCompat="@drawable/ic_issue_closed"
app:layout_alignSelf="flex_start"/>
<com.google.android.material.chip.Chip
android:id="@+id/openChip"
style="@style/Widget.MaterialComponents.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/isOpen"
android:checked="true"/>
<TextView
android:id="@+id/filterByLabels"
android:layout_width="@dimen/dimen132dp"
android:layout_height="@dimen/dimen100dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center"
android:padding="@dimen/dimen4dp"
android:text="@string/labelTxt"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp"
app:drawableTopCompat="@drawable/ic_label"
app:layout_alignSelf="flex_start"/>
<com.google.android.material.chip.Chip
android:id="@+id/closedChip"
style="@style/Widget.MaterialComponents.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/isClosed"/>
</com.google.android.flexbox.FlexboxLayout>
</com.google.android.material.chip.ChipGroup>
</LinearLayout>
<com.google.android.material.chip.ChipGroup
android:id="@+id/filterChipGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:singleSelection="false"
android:padding="@dimen/dimen16dp">
</androidx.core.widget.NestedScrollView>
<com.google.android.material.chip.Chip
android:id="@+id/mentionsChip"
style="@style/Widget.MaterialComponents.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/im_mentioned"/>
<com.google.android.material.chip.Chip
android:id="@+id/labelsChip"
style="@style/Widget.MaterialComponents.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/newIssueLabelsTitle"/>
<com.google.android.material.chip.Chip
android:id="@+id/milestoneChip"
style="@style/Widget.MaterialComponents.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tabTextMl"
android:visibility="gone"/>
</com.google.android.material.chip.ChipGroup>
</LinearLayout>

View File

@@ -24,14 +24,16 @@
</androidx.core.widget.NestedScrollView>
<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/filterButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_height="@dimen/dimen54dp"
android:layout_marginStart="@dimen/dimen16dp"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginEnd="@dimen/dimen16dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:layout_gravity="end"
android:text="@string/strFilter"
app:backgroundTint="?attr/iconsColor"
android:textColor="?attr/primaryTextColor"/>
android:textColor="@color/colorWhite" />
</LinearLayout>

View File

@@ -946,4 +946,5 @@
<string name="search_matches_found">%1$d matches found</string>
<string name="search_no_matches">No matches found</string>
<string name="heatmap_contribution">%1$d contributions on %2$s</string>
<string name="im_mentioned">I\'m mentioned</string>
</resources>