mirror of
https://github.com/gitnex-org/gitnex.git
synced 2026-03-11 17:34:09 -05:00
Filter issues by labels and mentioned (me) (#1419)
Closes #933 Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1419 Co-authored-by: M M Arif <mmarif@swatian.com> Co-committed-by: M M Arif <mmarif@swatian.com>
This commit is contained in:
@@ -4,7 +4,9 @@ import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
@@ -12,23 +14,31 @@ import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
import com.google.android.flexbox.FlexboxLayout;
|
||||
import com.google.android.material.chip.Chip;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.android.material.tabs.TabLayoutMediator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.gitnex.tea4j.v2.models.Label;
|
||||
import org.gitnex.tea4j.v2.models.Milestone;
|
||||
import org.gitnex.tea4j.v2.models.Organization;
|
||||
import org.gitnex.tea4j.v2.models.Repository;
|
||||
@@ -90,6 +100,9 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
|
||||
private FragmentRefreshListener fragmentRefreshListenerFiles;
|
||||
private FragmentRefreshListener fragmentRefreshListenerFilterIssuesByMilestone;
|
||||
private FragmentRefreshListener fragmentRefreshListenerReleases;
|
||||
private FragmentRefreshListenerFilterIssuesByLabels fragmentRefreshListenerFilterIssuesByLabels;
|
||||
private final List<Label> labelsList = new ArrayList<>();
|
||||
private final Map<String, Boolean> selectedStates = new HashMap<>();
|
||||
private Dialog progressDialog;
|
||||
private MaterialAlertDialogBuilder materialAlertDialogBuilder;
|
||||
private Intent intentWiki;
|
||||
@@ -121,6 +134,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
|
||||
TextView toolbarTitle = findViewById(R.id.toolbar_title);
|
||||
toolbarTitle.setText(repository.getFullName());
|
||||
|
||||
fetchLabels();
|
||||
|
||||
setSupportActionBar(toolbar);
|
||||
Objects.requireNonNull(getSupportActionBar()).setTitle(repository.getName());
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
@@ -205,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) {
|
||||
@@ -221,11 +236,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
|
||||
filterMilestoneBottomSheet.show(
|
||||
getSupportFragmentManager(), "repoFilterMenuMilestoneBottomSheet");
|
||||
return true;
|
||||
} /*else if (id == R.id.switchBranches) {
|
||||
|
||||
chooseBranch();
|
||||
return true;
|
||||
}*/ else if (id == R.id.branchCommits) {
|
||||
} else if (id == R.id.branchCommits) {
|
||||
|
||||
Intent intent = repository.getIntent(ctx, CommitsActivity.class);
|
||||
|
||||
@@ -242,10 +253,49 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void fetchLabels() {
|
||||
Call<List<Label>> call =
|
||||
RetrofitClient.getApiInterface(this)
|
||||
.issueListLabels(repository.getOwner(), repository.getName(), 1, 50);
|
||||
call.enqueue(
|
||||
new Callback<>() {
|
||||
@Override
|
||||
public void onResponse(
|
||||
@NonNull Call<List<Label>> call,
|
||||
@NonNull Response<List<Label>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
labelsList.clear();
|
||||
labelsList.addAll(response.body());
|
||||
for (Label label : labelsList) {
|
||||
selectedStates.put(label.getName(), false); // Initialize states
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Label>> call, @NonNull Throwable t) {
|
||||
Toasty.error(
|
||||
RepoDetailActivity.this,
|
||||
getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@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();
|
||||
break;
|
||||
case "openWebRepo":
|
||||
AppUtil.openUrlInBrowser(this, repository.getRepository().getHtmlUrl());
|
||||
break;
|
||||
@@ -334,6 +384,63 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
|
||||
}
|
||||
}
|
||||
|
||||
private void showLabelFilterDialog() {
|
||||
|
||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||
View dialogView =
|
||||
LayoutInflater.from(this).inflate(R.layout.custom_filter_issues_by_labels, null);
|
||||
|
||||
FlexboxLayout labelsContainer = dialogView.findViewById(R.id.labelsContainer);
|
||||
Button filterButton = dialogView.findViewById(R.id.filterButton);
|
||||
|
||||
labelsContainer.removeAllViews();
|
||||
|
||||
for (Label label : labelsList) {
|
||||
Chip chip =
|
||||
(Chip)
|
||||
LayoutInflater.from(this)
|
||||
.inflate(
|
||||
R.layout.list_filter_issues_by_labels,
|
||||
labelsContainer,
|
||||
false);
|
||||
chip.setText(label.getName());
|
||||
chip.setCheckable(true);
|
||||
chip.setChecked(
|
||||
Boolean.TRUE.equals(selectedStates.getOrDefault(label.getName(), false)));
|
||||
|
||||
GradientDrawable dot = new GradientDrawable();
|
||||
dot.setShape(GradientDrawable.OVAL);
|
||||
dot.setSize(16, 16);
|
||||
dot.setColor(Color.parseColor("#" + label.getColor()));
|
||||
chip.setChipIcon(dot);
|
||||
|
||||
chip.setOnCheckedChangeListener(
|
||||
(buttonView, isChecked) -> {
|
||||
selectedStates.put(label.getName(), isChecked);
|
||||
});
|
||||
|
||||
labelsContainer.addView(chip);
|
||||
}
|
||||
|
||||
AlertDialog dialog = builder.setView(dialogView).create();
|
||||
|
||||
filterButton.setOnClickListener(
|
||||
v -> {
|
||||
String selectedLabels =
|
||||
selectedStates.entrySet().stream()
|
||||
.filter(Map.Entry::getValue)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.joining(","));
|
||||
if (getFragmentRefreshListenerFilterIssuesByLabels() != null) {
|
||||
getFragmentRefreshListenerFilterIssuesByLabels()
|
||||
.onRefresh(selectedLabels.isEmpty() ? null : selectedLabels);
|
||||
}
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void filterIssuesByMilestone() {
|
||||
|
||||
progressDialog = new Dialog(this);
|
||||
@@ -735,6 +842,39 @@ 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);
|
||||
}
|
||||
|
||||
public void setFragmentRefreshListenerFilterIssuesByLabels(
|
||||
FragmentRefreshListenerFilterIssuesByLabels listener) {
|
||||
this.fragmentRefreshListenerFilterIssuesByLabels = listener;
|
||||
}
|
||||
|
||||
public FragmentRefreshListenerFilterIssuesByLabels
|
||||
getFragmentRefreshListenerFilterIssuesByLabels() {
|
||||
return fragmentRefreshListenerFilterIssuesByLabels;
|
||||
}
|
||||
|
||||
// Issues milestone filter interface
|
||||
public FragmentRefreshListener getFragmentRefreshListenerFilterIssuesByMilestone() {
|
||||
return fragmentRefreshListenerFilterIssuesByMilestone;
|
||||
|
||||
@@ -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,42 +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");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ public class IssuesFragment extends Fragment {
|
||||
private int pageSize = Constants.issuesPageInit;
|
||||
private int resultLimit;
|
||||
private RepositoryContext repository;
|
||||
private String selectedLabels = null;
|
||||
private String mentionedBy;
|
||||
|
||||
public static IssuesFragment newInstance(RepositoryContext repository) {
|
||||
IssuesFragment f = new IssuesFragment();
|
||||
@@ -67,6 +69,7 @@ public class IssuesFragment extends Fragment {
|
||||
context = getContext();
|
||||
|
||||
repository = RepositoryContext.fromBundle(requireArguments());
|
||||
mentionedBy = repository.getMentionedBy();
|
||||
|
||||
boolean archived = repository.getRepository().isArchived();
|
||||
|
||||
@@ -89,7 +92,9 @@ public class IssuesFragment extends Fragment {
|
||||
requestType,
|
||||
repository.getIssueState().toString(),
|
||||
repository.getIssueMilestoneFilterName(),
|
||||
null);
|
||||
null,
|
||||
selectedLabels,
|
||||
mentionedBy);
|
||||
adapter.notifyDataChanged();
|
||||
},
|
||||
200));
|
||||
@@ -109,7 +114,9 @@ public class IssuesFragment extends Fragment {
|
||||
resultLimit,
|
||||
requestType,
|
||||
repository.getIssueState().toString(),
|
||||
repository.getIssueMilestoneFilterName());
|
||||
repository.getIssueMilestoneFilterName(),
|
||||
selectedLabels,
|
||||
mentionedBy);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -125,90 +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());
|
||||
}
|
||||
}));
|
||||
|
||||
fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE);
|
||||
fragmentIssuesBinding.noDataIssues.setVisibility(View.GONE);
|
||||
|
||||
loadInitial(
|
||||
repository.getOwner(),
|
||||
repository.getName(),
|
||||
resultLimit,
|
||||
requestType,
|
||||
issueState,
|
||||
repository.getIssueMilestoneFilterName(),
|
||||
null);
|
||||
fragmentIssuesBinding.recyclerView.setAdapter(adapter);
|
||||
});
|
||||
issueState -> refreshIssues(issueState, selectedLabels, mentionedBy));
|
||||
|
||||
((RepoDetailActivity) requireActivity())
|
||||
.setFragmentRefreshListenerFilterIssuesByMilestone(
|
||||
filterIssueByMilestone -> {
|
||||
issuesList.clear();
|
||||
filterIssueByMilestone ->
|
||||
refreshIssues(
|
||||
repository.getIssueState().toString(),
|
||||
selectedLabels,
|
||||
mentionedBy,
|
||||
filterIssueByMilestone));
|
||||
|
||||
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());
|
||||
}
|
||||
}));
|
||||
|
||||
fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE);
|
||||
fragmentIssuesBinding.noDataIssues.setVisibility(View.GONE);
|
||||
|
||||
loadInitial(
|
||||
repository.getOwner(),
|
||||
repository.getName(),
|
||||
resultLimit,
|
||||
requestType,
|
||||
((RepoDetailActivity) requireActivity())
|
||||
.setFragmentRefreshListenerFilterIssuesByLabels(
|
||||
filterLabels -> {
|
||||
selectedLabels = filterLabels;
|
||||
refreshIssues(
|
||||
repository.getIssueState().toString(),
|
||||
filterIssueByMilestone,
|
||||
null);
|
||||
fragmentIssuesBinding.recyclerView.setAdapter(adapter);
|
||||
selectedLabels,
|
||||
mentionedBy);
|
||||
});
|
||||
|
||||
((RepoDetailActivity) requireActivity())
|
||||
.setFragmentRefreshListenerFilterIssuesByMentions(
|
||||
username -> {
|
||||
mentionedBy = username;
|
||||
repository.setMentionedBy(username);
|
||||
refreshIssues(
|
||||
repository.getIssueState().toString(),
|
||||
selectedLabels,
|
||||
mentionedBy);
|
||||
});
|
||||
|
||||
loadInitial(
|
||||
@@ -218,7 +171,9 @@ public class IssuesFragment extends Fragment {
|
||||
requestType,
|
||||
repository.getIssueState().toString(),
|
||||
repository.getIssueMilestoneFilterName(),
|
||||
null);
|
||||
null,
|
||||
selectedLabels,
|
||||
mentionedBy);
|
||||
|
||||
getPinnedIssues(repository.getOwner(), repository.getName());
|
||||
|
||||
@@ -227,7 +182,6 @@ public class IssuesFragment extends Fragment {
|
||||
}
|
||||
|
||||
if (repository.getRepository().isHasIssues() && !archived) {
|
||||
|
||||
fragmentIssuesBinding.createNewIssue.setVisibility(View.VISIBLE);
|
||||
fragmentIssuesBinding.createNewIssue.setOnClickListener(
|
||||
v12 -> {
|
||||
@@ -237,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);
|
||||
|
||||
@@ -268,7 +219,6 @@ public class IssuesFragment extends Fragment {
|
||||
searchView.setOnQueryTextListener(
|
||||
new androidx.appcompat.widget.SearchView
|
||||
.OnQueryTextListener() {
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
loadInitial(
|
||||
@@ -278,7 +228,9 @@ public class IssuesFragment extends Fragment {
|
||||
requestType,
|
||||
repository.getIssueState().toString(),
|
||||
repository.getIssueMilestoneFilterName(),
|
||||
query);
|
||||
query,
|
||||
selectedLabels,
|
||||
mentionedBy);
|
||||
searchView.setQuery(null, false);
|
||||
searchItem.collapseActionView();
|
||||
return false;
|
||||
@@ -313,25 +265,98 @@ public class IssuesFragment extends Fragment {
|
||||
requestType,
|
||||
repository.getIssueState().toString(),
|
||||
repository.getIssueMilestoneFilterName(),
|
||||
null);
|
||||
"",
|
||||
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()) {
|
||||
@@ -368,7 +393,9 @@ public class IssuesFragment extends Fragment {
|
||||
String requestType,
|
||||
String issueState,
|
||||
String filterByMilestone,
|
||||
String query) {
|
||||
String query,
|
||||
String labels,
|
||||
String mentionedBy) {
|
||||
|
||||
Call<List<Issue>> call =
|
||||
RetrofitClient.getApiInterface(context)
|
||||
@@ -376,26 +403,24 @@ public class IssuesFragment extends Fragment {
|
||||
repoOwner,
|
||||
repoName,
|
||||
issueState,
|
||||
null,
|
||||
labels,
|
||||
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()) {
|
||||
@@ -433,7 +458,9 @@ public class IssuesFragment extends Fragment {
|
||||
int resultLimit,
|
||||
String requestType,
|
||||
String issueState,
|
||||
String filterByMilestone) {
|
||||
String filterByMilestone,
|
||||
String labels,
|
||||
String mentionedBy) {
|
||||
|
||||
fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
@@ -443,25 +470,24 @@ public class IssuesFragment extends Fragment {
|
||||
repoOwner,
|
||||
repoName,
|
||||
issueState,
|
||||
null,
|
||||
labels,
|
||||
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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,103 +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"/>
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
<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"/>
|
||||
|
||||
</LinearLayout>
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
<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">
|
||||
|
||||
<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>
|
||||
|
||||
39
app/src/main/res/layout/custom_filter_issues_by_labels.xml
Normal file
39
app/src/main/res/layout/custom_filter_issues_by_labels.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?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:orientation="vertical"
|
||||
android:padding="@dimen/dimen16dp">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:maxHeight="@dimen/dimen320dp">
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:id="@+id/labelsContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:flexWrap="wrap"
|
||||
app:justifyContent="flex_start"
|
||||
app:alignItems="flex_start"
|
||||
android:padding="@dimen/dimen4dp"/>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/filterButton"
|
||||
android:layout_width="wrap_content"
|
||||
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"
|
||||
android:textColor="@color/colorWhite" />
|
||||
|
||||
</LinearLayout>
|
||||
17
app/src/main/res/layout/list_filter_issues_by_labels.xml
Normal file
17
app/src/main/res/layout/list_filter_issues_by_labels.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.chip.Chip
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/labelChip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/dimen4dp"
|
||||
app:chipStartPadding="@dimen/dimen8dp"
|
||||
app:chipEndPadding="@dimen/dimen8dp"
|
||||
app:chipIconSize="@dimen/dimen16dp"
|
||||
app:chipIconVisible="true"
|
||||
app:checkedIconEnabled="false"
|
||||
app:chipMinHeight="@dimen/dimen32dp"
|
||||
app:textEndPadding="@dimen/dimen4dp"
|
||||
app:textStartPadding="@dimen/dimen4dp"
|
||||
style="@style/Widget.MaterialComponents.Chip.Choice"/>
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user