From ab9b367a38c33d2fbdee5f470144ee0225d186b0 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 27 Nov 2022 12:27:31 +0100 Subject: [PATCH] Hide messages instead of removing them and add fetch more support --- .../android/helper/TimelineHelper.java | 18 +--- .../android/ui/drawer/StatusAdapter.java | 91 ++++++++++++++++++- .../res/layout/drawer_status_filtered.xml | 23 ++++- .../layout/drawer_status_filtered_hide.xml | 46 ++++++++++ 4 files changed, 157 insertions(+), 21 deletions(-) create mode 100644 app/src/main/res/layout/drawer_status_filtered_hide.xml diff --git a/app/src/main/java/app/fedilab/android/helper/TimelineHelper.java b/app/src/main/java/app/fedilab/android/helper/TimelineHelper.java index 02ce2b2f..2f0366d7 100644 --- a/app/src/main/java/app/fedilab/android/helper/TimelineHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/TimelineHelper.java @@ -73,7 +73,6 @@ public class TimelineHelper { */ public static List filterStatus(Context context, List statuses, Timeline.TimeLineEnum filterTimeLineType) { //A security to make sure filters have been fetched before displaying messages - List statusesToRemove = new ArrayList<>(); if (!BaseMainActivity.filterFetched) { MastodonFiltersService mastodonFiltersService = initv2(context); List filterList; @@ -132,12 +131,7 @@ public class TimelineHelper { content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content).toString(); Matcher m = p.matcher(content); if (m.find()) { - - if (filter.filter_action.equalsIgnoreCase("warn")) { - status.filteredByApp = filter; - } else { - statusesToRemove.add(status); - } + status.filteredByApp = filter; continue; } if (status.spoiler_text != null) { @@ -148,22 +142,14 @@ public class TimelineHelper { spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text).toString(); Matcher ms = p.matcher(spoilerText); if (ms.find()) { - if (filter.filter_action.equalsIgnoreCase("warn")) { - status.filteredByApp = filter; - } else { - statusesToRemove.add(status); - } + status.filteredByApp = filter; } } } } } - } } - if (statuses != null) { - statuses.removeAll(statusesToRemove); - } return statuses; } diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java index c583b75c..c258ca1a 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java @@ -127,6 +127,7 @@ import app.fedilab.android.client.entities.app.Timeline; import app.fedilab.android.databinding.DrawerStatusArtBinding; import app.fedilab.android.databinding.DrawerStatusBinding; import app.fedilab.android.databinding.DrawerStatusFilteredBinding; +import app.fedilab.android.databinding.DrawerStatusFilteredHideBinding; import app.fedilab.android.databinding.DrawerStatusHiddenBinding; import app.fedilab.android.databinding.DrawerStatusNotificationBinding; import app.fedilab.android.databinding.DrawerStatusReportBinding; @@ -156,6 +157,7 @@ public class StatusAdapter extends RecyclerView.Adapter public static final int STATUS_VISIBLE = 1; public static final int STATUS_ART = 2; public static final int STATUS_FILTERED = 3; + public static final int STATUS_FILTERED_HIDE = 4; private final List statusList; private final boolean minified; private final Timeline.TimeLineEnum timelineType; @@ -2188,7 +2190,15 @@ public class StatusAdapter extends RecyclerView.Adapter return STATUS_ART; } else { if (statusList.get(position).filteredByApp != null) { - return STATUS_FILTERED; + if (statusList.get(position).filteredByApp.filter_action.equals("warn")) { + return STATUS_FILTERED; + } else { //These messages should not be displayed unless they contain a fetch more button + if (!statusList.get(position).isFetchMore) { + return STATUS_HIDDEN; + } else { + return STATUS_FILTERED_HIDE; + } + } } else { return isVisible(timelineType, statusList.get(position)) ? STATUS_VISIBLE : STATUS_HIDDEN; } @@ -2206,9 +2216,12 @@ public class StatusAdapter extends RecyclerView.Adapter } else if (viewType == STATUS_ART) { //Art statuses DrawerStatusArtBinding itemBinding = DrawerStatusArtBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); return new StatusViewHolder(itemBinding); - } else if (viewType == STATUS_FILTERED) { //Art statuses + } else if (viewType == STATUS_FILTERED) { //Filtered warn DrawerStatusFilteredBinding itemBinding = DrawerStatusFilteredBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); return new StatusViewHolder(itemBinding); + } else if (viewType == STATUS_FILTERED_HIDE) { //Filtered hide + DrawerStatusFilteredHideBinding itemBinding = DrawerStatusFilteredHideBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); + return new StatusViewHolder(itemBinding); } else { //Classic statuses if (!minified) { DrawerStatusBinding itemBinding = DrawerStatusBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); @@ -2245,13 +2258,80 @@ public class StatusAdapter extends RecyclerView.Adapter StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class); SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class); statusManagement(context, statusesVM, searchVM, holder, this, statusList, status, timelineType, minified, canBeFederated, checkRemotely, fetchMoreCallBack); + } else if (viewHolder.getItemViewType() == STATUS_FILTERED_HIDE) { + StatusViewHolder holder = (StatusViewHolder) viewHolder; + + if (status.isFetchMore && fetchMoreCallBack != null) { + holder.bindingFilteredHide.layoutFetchMore.fetchMoreContainer.setVisibility(View.VISIBLE); + holder.bindingFilteredHide.layoutFetchMore.fetchMoreMin.setOnClickListener(v -> { + status.isFetchMore = false; + notifyItemChanged(holder.getBindingAdapterPosition()); + if (holder.getBindingAdapterPosition() < statusList.size() - 1) { + String fromId; + if (status.positionFetchMore == Status.PositionFetchMore.TOP) { + fromId = statusList.get(holder.getBindingAdapterPosition() + 1).id; + } else { + fromId = status.id; + } + fetchMoreCallBack.onClickMinId(fromId, status); + } + }); + holder.bindingFilteredHide.layoutFetchMore.fetchMoreMax.setOnClickListener(v -> { + //We hide the button + status.isFetchMore = false; + String fromId; + if (status.positionFetchMore == Status.PositionFetchMore.TOP) { + fromId = statusList.get(holder.getBindingAdapterPosition()).id; + } else { + fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id; + } + fetchMoreCallBack.onClickMaxId(fromId, status); + notifyItemChanged(holder.getBindingAdapterPosition()); + }); + } else { + holder.bindingFilteredHide.layoutFetchMore.fetchMoreContainer.setVisibility(View.GONE); + } + } else if (viewHolder.getItemViewType() == STATUS_FILTERED) { StatusViewHolder holder = (StatusViewHolder) viewHolder; + holder.bindingFiltered.filteredText.setText(context.getString(R.string.filtered_by, status.filteredByApp.title)); holder.bindingFiltered.displayButton.setOnClickListener(v -> { status.filteredByApp = null; notifyItemChanged(position); }); + + if (status.isFetchMore && fetchMoreCallBack != null) { + holder.bindingFiltered.layoutFetchMore.fetchMoreContainer.setVisibility(View.VISIBLE); + holder.bindingFiltered.layoutFetchMore.fetchMoreMin.setOnClickListener(v -> { + status.isFetchMore = false; + notifyItemChanged(holder.getBindingAdapterPosition()); + if (holder.getBindingAdapterPosition() < statusList.size() - 1) { + String fromId; + if (status.positionFetchMore == Status.PositionFetchMore.TOP) { + fromId = statusList.get(holder.getBindingAdapterPosition() + 1).id; + } else { + fromId = status.id; + } + fetchMoreCallBack.onClickMinId(fromId, status); + } + }); + holder.bindingFiltered.layoutFetchMore.fetchMoreMax.setOnClickListener(v -> { + //We hide the button + status.isFetchMore = false; + String fromId; + if (status.positionFetchMore == Status.PositionFetchMore.TOP) { + fromId = statusList.get(holder.getBindingAdapterPosition()).id; + } else { + fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id; + } + fetchMoreCallBack.onClickMaxId(fromId, status); + notifyItemChanged(holder.getBindingAdapterPosition()); + }); + } else { + holder.bindingFiltered.layoutFetchMore.fetchMoreContainer.setVisibility(View.GONE); + } + } else if (viewHolder.getItemViewType() == STATUS_ART) { StatusViewHolder holder = (StatusViewHolder) viewHolder; MastodonHelper.loadPPMastodon(holder.bindingArt.artPp, status.account); @@ -2352,7 +2432,7 @@ public class StatusAdapter extends RecyclerView.Adapter DrawerStatusNotificationBinding bindingNotification; DrawerStatusArtBinding bindingArt; DrawerStatusFilteredBinding bindingFiltered; - + DrawerStatusFilteredHideBinding bindingFilteredHide; StatusViewHolder(DrawerStatusBinding itemView) { super(itemView.getRoot()); binding = itemView; @@ -2385,6 +2465,11 @@ public class StatusAdapter extends RecyclerView.Adapter super(itemView.getRoot()); bindingFiltered = itemView; } + + StatusViewHolder(DrawerStatusFilteredHideBinding itemView) { + super(itemView.getRoot()); + bindingFilteredHide = itemView; + } } diff --git a/app/src/main/res/layout/drawer_status_filtered.xml b/app/src/main/res/layout/drawer_status_filtered.xml index 5bf1f85c..b8b490dc 100644 --- a/app/src/main/res/layout/drawer_status_filtered.xml +++ b/app/src/main/res/layout/drawer_status_filtered.xml @@ -38,7 +38,7 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:textSize="16sp" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@+id/container_fetchmore" app:layout_constraintEnd_toStartOf="@+id/display_button" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" @@ -51,10 +51,29 @@ android:layout_height="wrap_content" android:text="@string/show_anyway" android:textColor="@color/cyanea_accent_dark_reference" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@+id/container_fetchmore" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/filtered_text" app:layout_constraintTop_toTopOf="parent" app:strokeColor="@color/cyanea_accent_dark_reference" /> + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/drawer_status_filtered_hide.xml b/app/src/main/res/layout/drawer_status_filtered_hide.xml new file mode 100644 index 00000000..0cf9ff4e --- /dev/null +++ b/app/src/main/res/layout/drawer_status_filtered_hide.xml @@ -0,0 +1,46 @@ + + + + + + + + \ No newline at end of file