mirror of
				https://codeberg.org/tom79/Fedilab.git
				synced 2025-10-20 11:20:16 +03:00 
			
		
		
		
	Hide messages instead of removing them and add fetch more support
This commit is contained in:
		
							parent
							
								
									6f288acbc9
								
							
						
					
					
						commit
						ab9b367a38
					
				
					 4 changed files with 157 additions and 21 deletions
				
			
		|  | @ -73,7 +73,6 @@ public class TimelineHelper { | ||||||
|      */ |      */ | ||||||
|     public static List<Status> filterStatus(Context context, List<Status> statuses, Timeline.TimeLineEnum filterTimeLineType) { |     public static List<Status> filterStatus(Context context, List<Status> statuses, Timeline.TimeLineEnum filterTimeLineType) { | ||||||
|         //A security to make sure filters have been fetched before displaying messages |         //A security to make sure filters have been fetched before displaying messages | ||||||
|         List<Status> statusesToRemove = new ArrayList<>(); |  | ||||||
|         if (!BaseMainActivity.filterFetched) { |         if (!BaseMainActivity.filterFetched) { | ||||||
|             MastodonFiltersService mastodonFiltersService = initv2(context); |             MastodonFiltersService mastodonFiltersService = initv2(context); | ||||||
|             List<Filter> filterList; |             List<Filter> filterList; | ||||||
|  | @ -132,12 +131,7 @@ public class TimelineHelper { | ||||||
|                                 content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content).toString(); |                                 content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content).toString(); | ||||||
|                             Matcher m = p.matcher(content); |                             Matcher m = p.matcher(content); | ||||||
|                             if (m.find()) { |                             if (m.find()) { | ||||||
| 
 |  | ||||||
|                                 if (filter.filter_action.equalsIgnoreCase("warn")) { |  | ||||||
|                                 status.filteredByApp = filter; |                                 status.filteredByApp = filter; | ||||||
|                                 } else { |  | ||||||
|                                     statusesToRemove.add(status); |  | ||||||
|                                 } |  | ||||||
|                                 continue; |                                 continue; | ||||||
|                             } |                             } | ||||||
|                             if (status.spoiler_text != null) { |                             if (status.spoiler_text != null) { | ||||||
|  | @ -148,21 +142,13 @@ public class TimelineHelper { | ||||||
|                                     spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text).toString(); |                                     spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text).toString(); | ||||||
|                                 Matcher ms = p.matcher(spoilerText); |                                 Matcher ms = p.matcher(spoilerText); | ||||||
|                                 if (ms.find()) { |                                 if (ms.find()) { | ||||||
|                                     if (filter.filter_action.equalsIgnoreCase("warn")) { |  | ||||||
|                                     status.filteredByApp = filter; |                                     status.filteredByApp = filter; | ||||||
|                                     } else { |  | ||||||
|                                         statusesToRemove.add(status); |  | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         if (statuses != null) { |  | ||||||
|             statuses.removeAll(statusesToRemove); |  | ||||||
|         } |         } | ||||||
|         return statuses; |         return statuses; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -127,6 +127,7 @@ import app.fedilab.android.client.entities.app.Timeline; | ||||||
| import app.fedilab.android.databinding.DrawerStatusArtBinding; | import app.fedilab.android.databinding.DrawerStatusArtBinding; | ||||||
| import app.fedilab.android.databinding.DrawerStatusBinding; | import app.fedilab.android.databinding.DrawerStatusBinding; | ||||||
| import app.fedilab.android.databinding.DrawerStatusFilteredBinding; | import app.fedilab.android.databinding.DrawerStatusFilteredBinding; | ||||||
|  | import app.fedilab.android.databinding.DrawerStatusFilteredHideBinding; | ||||||
| import app.fedilab.android.databinding.DrawerStatusHiddenBinding; | import app.fedilab.android.databinding.DrawerStatusHiddenBinding; | ||||||
| import app.fedilab.android.databinding.DrawerStatusNotificationBinding; | import app.fedilab.android.databinding.DrawerStatusNotificationBinding; | ||||||
| import app.fedilab.android.databinding.DrawerStatusReportBinding; | import app.fedilab.android.databinding.DrawerStatusReportBinding; | ||||||
|  | @ -156,6 +157,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> | ||||||
|     public static final int STATUS_VISIBLE = 1; |     public static final int STATUS_VISIBLE = 1; | ||||||
|     public static final int STATUS_ART = 2; |     public static final int STATUS_ART = 2; | ||||||
|     public static final int STATUS_FILTERED = 3; |     public static final int STATUS_FILTERED = 3; | ||||||
|  |     public static final int STATUS_FILTERED_HIDE = 4; | ||||||
|     private final List<Status> statusList; |     private final List<Status> statusList; | ||||||
|     private final boolean minified; |     private final boolean minified; | ||||||
|     private final Timeline.TimeLineEnum timelineType; |     private final Timeline.TimeLineEnum timelineType; | ||||||
|  | @ -2188,7 +2190,15 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> | ||||||
|             return STATUS_ART; |             return STATUS_ART; | ||||||
|         } else { |         } else { | ||||||
|             if (statusList.get(position).filteredByApp != null) { |             if (statusList.get(position).filteredByApp != null) { | ||||||
|  |                 if (statusList.get(position).filteredByApp.filter_action.equals("warn")) { | ||||||
|                     return STATUS_FILTERED; |                     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 { |             } else { | ||||||
|                 return isVisible(timelineType, statusList.get(position)) ? STATUS_VISIBLE : STATUS_HIDDEN; |                 return isVisible(timelineType, statusList.get(position)) ? STATUS_VISIBLE : STATUS_HIDDEN; | ||||||
|             } |             } | ||||||
|  | @ -2206,9 +2216,12 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> | ||||||
|         } else if (viewType == STATUS_ART) { //Art statuses |         } else if (viewType == STATUS_ART) { //Art statuses | ||||||
|             DrawerStatusArtBinding itemBinding = DrawerStatusArtBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); |             DrawerStatusArtBinding itemBinding = DrawerStatusArtBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); | ||||||
|             return new StatusViewHolder(itemBinding); |             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); |             DrawerStatusFilteredBinding itemBinding = DrawerStatusFilteredBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); | ||||||
|             return new StatusViewHolder(itemBinding); |             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 |         } else { //Classic statuses | ||||||
|             if (!minified) { |             if (!minified) { | ||||||
|                 DrawerStatusBinding itemBinding = DrawerStatusBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); |                 DrawerStatusBinding itemBinding = DrawerStatusBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); | ||||||
|  | @ -2245,13 +2258,80 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> | ||||||
|             StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class); |             StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class); | ||||||
|             SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class); |             SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class); | ||||||
|             statusManagement(context, statusesVM, searchVM, holder, this, statusList, status, timelineType, minified, canBeFederated, checkRemotely, fetchMoreCallBack); |             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) { |         } else if (viewHolder.getItemViewType() == STATUS_FILTERED) { | ||||||
|             StatusViewHolder holder = (StatusViewHolder) viewHolder; |             StatusViewHolder holder = (StatusViewHolder) viewHolder; | ||||||
|  | 
 | ||||||
|             holder.bindingFiltered.filteredText.setText(context.getString(R.string.filtered_by, status.filteredByApp.title)); |             holder.bindingFiltered.filteredText.setText(context.getString(R.string.filtered_by, status.filteredByApp.title)); | ||||||
|             holder.bindingFiltered.displayButton.setOnClickListener(v -> { |             holder.bindingFiltered.displayButton.setOnClickListener(v -> { | ||||||
|                 status.filteredByApp = null; |                 status.filteredByApp = null; | ||||||
|                 notifyItemChanged(position); |                 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) { |         } else if (viewHolder.getItemViewType() == STATUS_ART) { | ||||||
|             StatusViewHolder holder = (StatusViewHolder) viewHolder; |             StatusViewHolder holder = (StatusViewHolder) viewHolder; | ||||||
|             MastodonHelper.loadPPMastodon(holder.bindingArt.artPp, status.account); |             MastodonHelper.loadPPMastodon(holder.bindingArt.artPp, status.account); | ||||||
|  | @ -2352,7 +2432,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> | ||||||
|         DrawerStatusNotificationBinding bindingNotification; |         DrawerStatusNotificationBinding bindingNotification; | ||||||
|         DrawerStatusArtBinding bindingArt; |         DrawerStatusArtBinding bindingArt; | ||||||
|         DrawerStatusFilteredBinding bindingFiltered; |         DrawerStatusFilteredBinding bindingFiltered; | ||||||
| 
 |         DrawerStatusFilteredHideBinding bindingFilteredHide; | ||||||
|         StatusViewHolder(DrawerStatusBinding itemView) { |         StatusViewHolder(DrawerStatusBinding itemView) { | ||||||
|             super(itemView.getRoot()); |             super(itemView.getRoot()); | ||||||
|             binding = itemView; |             binding = itemView; | ||||||
|  | @ -2385,6 +2465,11 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> | ||||||
|             super(itemView.getRoot()); |             super(itemView.getRoot()); | ||||||
|             bindingFiltered = itemView; |             bindingFiltered = itemView; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         StatusViewHolder(DrawerStatusFilteredHideBinding itemView) { | ||||||
|  |             super(itemView.getRoot()); | ||||||
|  |             bindingFilteredHide = itemView; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ | ||||||
|             android:layout_height="wrap_content" |             android:layout_height="wrap_content" | ||||||
|             android:layout_gravity="center" |             android:layout_gravity="center" | ||||||
|             android:textSize="16sp" |             android:textSize="16sp" | ||||||
|             app:layout_constraintBottom_toBottomOf="parent" |             app:layout_constraintBottom_toTopOf="@+id/container_fetchmore" | ||||||
|             app:layout_constraintEnd_toStartOf="@+id/display_button" |             app:layout_constraintEnd_toStartOf="@+id/display_button" | ||||||
|             app:layout_constraintStart_toStartOf="parent" |             app:layout_constraintStart_toStartOf="parent" | ||||||
|             app:layout_constraintTop_toTopOf="parent" |             app:layout_constraintTop_toTopOf="parent" | ||||||
|  | @ -51,10 +51,29 @@ | ||||||
|             android:layout_height="wrap_content" |             android:layout_height="wrap_content" | ||||||
|             android:text="@string/show_anyway" |             android:text="@string/show_anyway" | ||||||
|             android:textColor="@color/cyanea_accent_dark_reference" |             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_constraintEnd_toEndOf="parent" | ||||||
|             app:layout_constraintStart_toEndOf="@+id/filtered_text" |             app:layout_constraintStart_toEndOf="@+id/filtered_text" | ||||||
|             app:layout_constraintTop_toTopOf="parent" |             app:layout_constraintTop_toTopOf="parent" | ||||||
|             app:strokeColor="@color/cyanea_accent_dark_reference" /> |             app:strokeColor="@color/cyanea_accent_dark_reference" /> | ||||||
|  | 
 | ||||||
|  |         <androidx.appcompat.widget.LinearLayoutCompat | ||||||
|  |             android:id="@+id/container_fetchmore" | ||||||
|  |             android:layout_width="match_parent" | ||||||
|  |             android:layout_height="wrap_content" | ||||||
|  |             app:layout_constraintBottom_toBottomOf="parent" | ||||||
|  |             app:layout_constraintEnd_toEndOf="parent" | ||||||
|  |             app:layout_constraintStart_toEndOf="@+id/filtered_text"> | ||||||
|  | 
 | ||||||
|  |             <include | ||||||
|  |                 android:id="@+id/layout_fetch_more" | ||||||
|  |                 layout="@layout/drawer_fetch_more" | ||||||
|  |                 android:visibility="gone" | ||||||
|  |                 app:layout_constraintBottom_toBottomOf="parent" | ||||||
|  |                 app:layout_constraintEnd_toEndOf="parent" | ||||||
|  |                 app:layout_constraintStart_toEndOf="@+id/filtered_text" | ||||||
|  |                 app:layout_constraintTop_toTopOf="parent" | ||||||
|  |                 tools:visibility="visible" /> | ||||||
|  |         </androidx.appcompat.widget.LinearLayoutCompat> | ||||||
|     </androidx.constraintlayout.widget.ConstraintLayout> |     </androidx.constraintlayout.widget.ConstraintLayout> | ||||||
| </com.google.android.material.card.MaterialCardView> | </com.google.android.material.card.MaterialCardView> | ||||||
							
								
								
									
										46
									
								
								app/src/main/res/layout/drawer_status_filtered_hide.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								app/src/main/res/layout/drawer_status_filtered_hide.xml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?><!-- | ||||||
|  |     Copyright 2022 Thomas Schneider | ||||||
|  | 
 | ||||||
|  |     This file is a part of Fedilab | ||||||
|  | 
 | ||||||
|  |     This program is free software; you can redistribute it and/or modify it under the terms of the | ||||||
|  |     GNU General Public License as published by the Free Software Foundation; either version 3 of the | ||||||
|  |     License, or (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |     Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even | ||||||
|  |     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||||||
|  |     Public License for more details. | ||||||
|  | 
 | ||||||
|  |     You should have received a copy of the GNU General Public License along with Fedilab; if not, | ||||||
|  |     see <http://www.gnu.org/licenses> | ||||||
|  | --> | ||||||
|  | <com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|  |     xmlns:tools="http://schemas.android.com/tools" | ||||||
|  |     android:id="@+id/cardview_container" | ||||||
|  |     android:layout_width="match_parent" | ||||||
|  |     android:layout_height="wrap_content" | ||||||
|  |     android:layout_marginHorizontal="@dimen/card_margin" | ||||||
|  |     android:layout_marginTop="@dimen/card_margin" | ||||||
|  |     android:clipChildren="false" | ||||||
|  |     android:clipToPadding="false" | ||||||
|  |     app:cardElevation="0dp"> | ||||||
|  | 
 | ||||||
|  |     <androidx.appcompat.widget.LinearLayoutCompat | ||||||
|  |         android:id="@+id/container_fetchmore" | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="wrap_content" | ||||||
|  |         android:orientation="vertical" | ||||||
|  |         android:padding="5dp"> | ||||||
|  | 
 | ||||||
|  |         <include | ||||||
|  |             android:id="@+id/layout_fetch_more" | ||||||
|  |             layout="@layout/drawer_fetch_more" | ||||||
|  |             android:visibility="gone" | ||||||
|  |             app:layout_constraintBottom_toBottomOf="parent" | ||||||
|  |             app:layout_constraintEnd_toEndOf="parent" | ||||||
|  |             app:layout_constraintStart_toEndOf="@+id/filtered_text" | ||||||
|  |             app:layout_constraintTop_toTopOf="parent" | ||||||
|  |             tools:visibility="visible" /> | ||||||
|  |     </androidx.appcompat.widget.LinearLayoutCompat> | ||||||
|  | </com.google.android.material.card.MaterialCardView> | ||||||
		Loading…
	
		Reference in a new issue