mirror of
https://github.com/gitnex-org/gitnex.git
synced 2026-03-26 08:18:03 -05:00
Add pagination for filter labels
This commit is contained in:
@@ -76,6 +76,11 @@ JSON Configuration:
|
||||
}
|
||||
```
|
||||
|
||||
## HTTP Basic Auth
|
||||
|
||||
GitNex from version **12.0.0** supports HTTP Basic Authentication for servers behind reverse proxies (nginx, Apache).
|
||||
[Read the Wiki](https://codeberg.org/gitnex/GitNex/wiki/HTTP-Basic-Auth-for-Reverse-Proxies)
|
||||
|
||||
## Links
|
||||
|
||||
- [Website](https://gitnex.com)
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.widget.NestedScrollView;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
@@ -37,6 +38,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import org.gitnex.tea4j.v2.models.Label;
|
||||
import org.gitnex.tea4j.v2.models.Milestone;
|
||||
@@ -386,43 +388,129 @@ 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);
|
||||
LinearProgressIndicator progressIndicator = dialogView.findViewById(R.id.progressBar);
|
||||
|
||||
ViewGroup parent = (ViewGroup) labelsContainer.getParent();
|
||||
NestedScrollView scrollView = null;
|
||||
if (parent != null && parent.getParent() instanceof NestedScrollView) {
|
||||
scrollView = (NestedScrollView) parent.getParent();
|
||||
}
|
||||
|
||||
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)));
|
||||
final Map<String, Boolean> selectedStates = new HashMap<>();
|
||||
final int[] currentPage = {1};
|
||||
final boolean[] isLoading = {false};
|
||||
final int pageSize = 50;
|
||||
|
||||
GradientDrawable dot = new GradientDrawable();
|
||||
dot.setShape(GradientDrawable.OVAL);
|
||||
dot.setSize(16, 16);
|
||||
dot.setColor(Color.parseColor("#" + label.getColor()));
|
||||
chip.setChipIcon(dot);
|
||||
Consumer<List<Label>> addLabelsToView =
|
||||
(newLabels) -> {
|
||||
for (Label label : newLabels) {
|
||||
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.get(label.getName())));
|
||||
|
||||
chip.setOnCheckedChangeListener(
|
||||
(buttonView, isChecked) -> {
|
||||
selectedStates.put(label.getName(), isChecked);
|
||||
});
|
||||
GradientDrawable dot = new GradientDrawable();
|
||||
dot.setShape(GradientDrawable.OVAL);
|
||||
dot.setSize(16, 16);
|
||||
dot.setColor(Color.parseColor("#" + label.getColor()));
|
||||
chip.setChipIcon(dot);
|
||||
|
||||
labelsContainer.addView(chip);
|
||||
chip.setOnCheckedChangeListener(
|
||||
(buttonView, isChecked) -> {
|
||||
selectedStates.put(label.getName(), isChecked);
|
||||
});
|
||||
|
||||
labelsContainer.addView(chip);
|
||||
}
|
||||
};
|
||||
|
||||
Consumer<Integer> loadLabels =
|
||||
(page) -> {
|
||||
if (isLoading[0]) return;
|
||||
|
||||
isLoading[0] = true;
|
||||
progressIndicator.setVisibility(View.VISIBLE);
|
||||
|
||||
Call<List<Label>> call =
|
||||
RetrofitClient.getApiInterface(this)
|
||||
.issueListLabels(
|
||||
repository.getOwner(),
|
||||
repository.getName(),
|
||||
page,
|
||||
pageSize);
|
||||
|
||||
call.enqueue(
|
||||
new Callback<>() {
|
||||
@Override
|
||||
public void onResponse(
|
||||
@NonNull Call<List<Label>> call,
|
||||
@NonNull Response<List<Label>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
List<Label> newLabels = response.body();
|
||||
|
||||
if (page == 1) {
|
||||
selectedStates.clear();
|
||||
labelsContainer.removeAllViews();
|
||||
}
|
||||
|
||||
if (page == 1) {
|
||||
labelsList.clear();
|
||||
}
|
||||
labelsList.addAll(newLabels);
|
||||
|
||||
for (Label label : newLabels) {
|
||||
selectedStates.putIfAbsent(label.getName(), false);
|
||||
}
|
||||
|
||||
addLabelsToView.accept(newLabels);
|
||||
}
|
||||
|
||||
isLoading[0] = false;
|
||||
progressIndicator.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(
|
||||
@NonNull Call<List<Label>> call, @NonNull Throwable t) {
|
||||
isLoading[0] = false;
|
||||
progressIndicator.setVisibility(View.GONE);
|
||||
Toasty.error(
|
||||
RepoDetailActivity.this,
|
||||
getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (scrollView != null) {
|
||||
scrollView.setOnScrollChangeListener(
|
||||
(NestedScrollView.OnScrollChangeListener)
|
||||
(v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
|
||||
if (!isLoading[0] && v.getChildAt(0) != null) {
|
||||
View child = v.getChildAt(0);
|
||||
if (child.getBottom() <= (v.getHeight() + v.getScrollY())) {
|
||||
currentPage[0]++;
|
||||
loadLabels.accept(currentPage[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadLabels.accept(currentPage[0]);
|
||||
|
||||
AlertDialog dialog = builder.setView(dialogView).create();
|
||||
|
||||
filterButton.setOnClickListener(
|
||||
|
||||
@@ -7,20 +7,36 @@
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/dimen16dp">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
|
||||
app:indicatorColor="?attr/progressIndicatorColor"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<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"
|
||||
<LinearLayout
|
||||
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"/>
|
||||
android:orientation="vertical">
|
||||
|
||||
<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"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user