some fixes with fetch more

This commit is contained in:
Thomas 2022-09-27 18:01:06 +02:00
parent a8f0125a8f
commit 2dc19277a7
9 changed files with 87 additions and 138 deletions

View File

@ -98,7 +98,6 @@ public class Status implements Serializable, Cloneable {
public boolean isExpended = false;
public boolean isTruncated = true;
public boolean isFetchMore = false;
public boolean isFetchMoreHidden = false;
public boolean isMediaDisplayed = false;
public boolean isMediaObfuscated = true;
public boolean isChecked = false;

View File

@ -72,7 +72,7 @@ public class ContextAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class);
SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class);
StatusAdapter.StatusViewHolder holder = (StatusAdapter.StatusViewHolder) viewHolder;
statusManagement(context, statusesVM, searchVM, holder, this, statusList, status, Timeline.TimeLineEnum.UNKNOWN, false, true);
statusManagement(context, statusesVM, searchVM, holder, this, statusList, status, Timeline.TimeLineEnum.UNKNOWN, false, true, null);
//Hide/Show specific view
}

View File

@ -42,7 +42,6 @@ import app.fedilab.android.R;
import app.fedilab.android.activities.ProfileActivity;
import app.fedilab.android.client.entities.api.Notification;
import app.fedilab.android.client.entities.app.Timeline;
import app.fedilab.android.databinding.DrawerFetchMoreBinding;
import app.fedilab.android.databinding.DrawerFollowBinding;
import app.fedilab.android.databinding.DrawerStatusNotificationBinding;
import app.fedilab.android.databinding.NotificationsRelatedAccountsBinding;
@ -62,9 +61,8 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
private final int TYPE_FAVOURITE = 4;
private final int TYPE_POLL = 5;
private final int TYPE_STATUS = 6;
private final int NOTIFICATION_FETCH_MORE = 7;
private final int TYPE_REACTION = 8;
public FetchMoreCallBack fetchMoreCallBack;
public StatusAdapter.FetchMoreCallBack fetchMoreCallBack;
private Context context;
public NotificationAdapter(List<Notification> notificationList) {
@ -81,9 +79,6 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
@Override
public int getItemViewType(int position) {
if (notificationList.get(position).isFetchMore) {
return NOTIFICATION_FETCH_MORE;
}
String type = notificationList.get(position).type;
switch (type) {
case "follow":
@ -113,9 +108,6 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
if (viewType == TYPE_FOLLOW || viewType == TYPE_FOLLOW_REQUEST) {
DrawerFollowBinding itemBinding = DrawerFollowBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new ViewHolderFollow(itemBinding);
} else if (viewType == NOTIFICATION_FETCH_MORE) { //Fetch more button
DrawerFetchMoreBinding itemBinding = DrawerFetchMoreBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new StatusAdapter.StatusViewHolder(itemBinding);
} else {
DrawerStatusNotificationBinding itemBinding = DrawerStatusNotificationBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new StatusAdapter.StatusViewHolder(itemBinding);
@ -164,25 +156,22 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
// start the new activity
context.startActivity(intent, options.toBundle());
});
} else if (viewHolder.getItemViewType() == NOTIFICATION_FETCH_MORE) {
StatusAdapter.StatusViewHolder holder = (StatusAdapter.StatusViewHolder) viewHolder;
holder.bindingFetchMore.fetchMoreContainer.setEnabled(!notification.isFetchMoreHidden);
holder.bindingFetchMore.fetchMoreMin.setOnClickListener(v -> {
if (position + 1 < notificationList.size()) {
//We hide the button
notification.isFetchMoreHidden = true;
if (notification.isFetchMore && fetchMoreCallBack != null) {
holderFollow.binding.layoutFetchMore.fetchMoreContainer.setVisibility(View.VISIBLE);
holderFollow.binding.layoutFetchMore.fetchMoreMin.setOnClickListener(v -> {
notification.isFetchMore = false;
notifyItemChanged(position);
fetchMoreCallBack.onClickMin(notificationList.get(position + 1).id, notification.id);
}
});
holder.bindingFetchMore.fetchMoreMax.setOnClickListener(v -> {
if (position - 1 >= 0) {
fetchMoreCallBack.onClickMinId(notification.id);
});
holderFollow.binding.layoutFetchMore.fetchMoreMax.setOnClickListener(v -> {
//We hide the button
notification.isFetchMoreHidden = true;
notification.isFetchMore = false;
notifyItemChanged(position);
fetchMoreCallBack.onClickMax(notificationList.get(position - 1).id, notification.id);
}
});
fetchMoreCallBack.onClickMaxId(notification.id);
});
} else {
holderFollow.binding.layoutFetchMore.fetchMoreContainer.setVisibility(View.GONE);
}
} else {
StatusAdapter.StatusViewHolder holderStatus = (StatusAdapter.StatusViewHolder) viewHolder;
holderStatus.bindingNotification.status.typeOfNotification.setVisibility(View.VISIBLE);
@ -202,7 +191,7 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class);
SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class);
statusManagement(context, statusesVM, searchVM, holderStatus, this, null, notification.status, Timeline.TimeLineEnum.NOTIFICATION, false, true);
statusManagement(context, statusesVM, searchVM, holderStatus, this, null, notification.status, Timeline.TimeLineEnum.NOTIFICATION, false, true, fetchMoreCallBack);
holderStatus.bindingNotification.status.dateShort.setText(Helper.dateDiff(context, notification.created_at));
holderStatus.bindingNotification.containerTransparent.setAlpha(.3f);
if (getItemViewType(position) == TYPE_MENTION || getItemViewType(position) == TYPE_STATUS || getItemViewType(position) == TYPE_REACTION) {
@ -321,11 +310,6 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
return notificationList.size();
}
public interface FetchMoreCallBack {
void onClickMin(String min_id, String fetchmoreId);
void onClickMax(String max_id, String fetchmoreId);
}
static class ViewHolderFollow extends RecyclerView.ViewHolder {
DrawerFollowBinding binding;

View File

@ -143,7 +143,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
public static final int STATUS_HIDDEN = 0;
public static final int STATUS_VISIBLE = 1;
public static final int STATUS_ART = 2;
public static final int STATUS_FETCH_MORE = 3;
private final List<Status> statusList;
private final boolean minified;
private final Timeline.TimeLineEnum timelineType;
@ -322,7 +321,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
List<Status> statusList,
Status status,
Timeline.TimeLineEnum timelineType,
boolean minified, boolean canBeFederated) {
boolean minified, boolean canBeFederated,
FetchMoreCallBack fetchMoreCallBack) {
if (status == null) {
return;
}
@ -1868,6 +1868,51 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.bindingReport.checkbox.setOnClickListener(v -> status.isChecked = !status.isChecked);
}
if (status.isFetchMore && fetchMoreCallBack != null) {
holder.binding.layoutFetchMore.fetchMoreContainer.setVisibility(View.VISIBLE);
holder.binding.layoutFetchMore.fetchMoreMin.setOnClickListener(v -> {
status.isFetchMore = false;
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
fetchMoreCallBack.onClickMinId(status.id);
if (!remote) {
new Thread(() -> {
StatusCache statusCache = new StatusCache();
statusCache.instance = BaseMainActivity.currentInstance;
statusCache.user_id = BaseMainActivity.currentUserID;
statusCache.status = status;
statusCache.status_id = status.id;
try {
new StatusCache(context).updateIfExists(statusCache);
} catch (DBException e) {
e.printStackTrace();
}
}).start();
}
});
holder.binding.layoutFetchMore.fetchMoreMax.setOnClickListener(v -> {
//We hide the button
status.isFetchMore = false;
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
if (!remote) {
new Thread(() -> {
StatusCache statusCache = new StatusCache();
statusCache.instance = BaseMainActivity.currentInstance;
statusCache.user_id = BaseMainActivity.currentUserID;
statusCache.status = status;
statusCache.status_id = status.id;
try {
new StatusCache(context).updateIfExists(statusCache);
} catch (DBException e) {
e.printStackTrace();
}
}).start();
}
fetchMoreCallBack.onClickMaxId(status.id);
});
} else {
holder.binding.layoutFetchMore.fetchMoreContainer.setVisibility(View.GONE);
}
}
private static boolean mediaObfuscated(Status status) {
@ -1911,8 +1956,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
public int getItemViewType(int position) {
if (timelineType == Timeline.TimeLineEnum.ART) {
return STATUS_ART;
} else if (statusList.get(position).isFetchMore) {
return STATUS_FETCH_MORE;
} else {
return isVisible(timelineType, statusList.get(position)) ? STATUS_VISIBLE : STATUS_HIDDEN;
}
@ -1928,9 +1971,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
} 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_FETCH_MORE) { //Fetch more button
DrawerFetchMoreBinding itemBinding = DrawerFetchMoreBinding.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);
@ -1966,7 +2006,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
StatusViewHolder holder = (StatusViewHolder) viewHolder;
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);
statusManagement(context, statusesVM, searchVM, holder, this, statusList, status, timelineType, minified, canBeFederated, fetchMoreCallBack);
} else if (viewHolder.getItemViewType() == STATUS_ART) {
StatusViewHolder holder = (StatusViewHolder) viewHolder;
MastodonHelper.loadPPMastodon(holder.bindingArt.artPp, status.account);
@ -2007,25 +2047,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
intent.putExtra(Helper.ARG_STATUS, status);
context.startActivity(intent);
});
} else if (viewHolder.getItemViewType() == STATUS_FETCH_MORE) {
StatusViewHolder holder = (StatusViewHolder) viewHolder;
holder.bindingFetchMore.fetchMoreContainer.setEnabled(!status.isFetchMoreHidden);
holder.bindingFetchMore.fetchMoreMin.setOnClickListener(v -> {
if (position + 1 < statusList.size()) {
//We hide the button
status.isFetchMoreHidden = true;
notifyItemChanged(position);
fetchMoreCallBack.onClickMinId(statusList.get(position + 1).id, status.id);
}
});
holder.bindingFetchMore.fetchMoreMax.setOnClickListener(v -> {
if (position - 1 >= 0) {
//We hide the button
status.isFetchMoreHidden = true;
notifyItemChanged(position);
fetchMoreCallBack.onClickMaxId(statusList.get(position - 1).id, status.id);
}
});
}
}
@ -2040,9 +2061,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
public interface FetchMoreCallBack {
void onClickMinId(String min_id, String fetchmoreId);
void onClickMinId(String min_id);
void onClickMaxId(String max_id, String fetchmoreId);
void onClickMaxId(String max_id);
}
public static class StatusViewHolder extends RecyclerView.ViewHolder {
@ -2075,10 +2096,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
bindingHidden = itemView;
}
StatusViewHolder(DrawerFetchMoreBinding itemView) {
super(itemView.getRoot());
bindingFetchMore = itemView;
}
StatusViewHolder(DrawerStatusArtBinding itemView) {
super(itemView.getRoot());

View File

@ -48,10 +48,11 @@ import app.fedilab.android.helper.Helper;
import app.fedilab.android.helper.MastodonHelper;
import app.fedilab.android.helper.ThemeHelper;
import app.fedilab.android.ui.drawer.NotificationAdapter;
import app.fedilab.android.ui.drawer.StatusAdapter;
import app.fedilab.android.viewmodel.mastodon.NotificationsVM;
public class FragmentMastodonNotification extends Fragment implements NotificationAdapter.FetchMoreCallBack {
public class FragmentMastodonNotification extends Fragment implements StatusAdapter.FetchMoreCallBack {
private static final int NOTIFICATION_PRESENT = -1;
@ -86,7 +87,6 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
};
private String max_id, min_id, min_id_fetch_more, max_id_fetch_more;
private LinearLayoutManager mLayoutManager;
private String instance, user_id;
private ArrayList<String> idOfAddedNotifications;
private NotificationTypeEnum notificationType;
private List<String> excludeType;
@ -115,8 +115,6 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
ViewGroup container, Bundle savedInstanceState) {
flagLoading = false;
instance = BaseMainActivity.currentInstance;
user_id = BaseMainActivity.currentUserID;
idOfAddedNotifications = new ArrayList<>();
binding = FragmentPaginationBinding.inflate(inflater, container, false);
View root = binding.getRoot();
@ -456,43 +454,18 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
super.onPause();
}
@Override
public void onClickMin(String min_id, String id) {
public void onClickMinId(String min_id) {
//Fetch more has been pressed
min_id_fetch_more = min_id;
Notification notification = null;
int position = 0;
for (Notification currentNotification : this.notificationList) {
if (currentNotification.id.compareTo(id) == 0) {
notification = currentNotification;
break;
}
position++;
}
if (notification != null) {
this.notificationList.remove(position);
notificationAdapter.notifyItemRemoved(position);
}
route(FragmentMastodonTimeline.DIRECTION.TOP, true);
}
@Override
public void onClickMax(String max_id, String id) {
public void onClickMaxId(String max_id) {
//Fetch more has been pressed
max_id_fetch_more = max_id;
Notification notification = null;
int position = 0;
for (Notification currentNotification : this.notificationList) {
if (currentNotification.id.compareTo(id) == 0) {
notification = currentNotification;
break;
}
position++;
}
if (notification != null) {
this.notificationList.remove(position);
notificationAdapter.notifyItemRemoved(position);
}
route(FragmentMastodonTimeline.DIRECTION.BOTTOM, true);
}

View File

@ -829,41 +829,15 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
}
@Override
public void onClickMinId(String min_id, String id) {
public void onClickMinId(String min_id) {
//Fetch more has been pressed
min_id_fetch_more = min_id;
Status status = null;
int position = 0;
for (Status currentStatus : timelineStatuses) {
if (currentStatus.id.compareTo(id) == 0) {
status = currentStatus;
break;
}
position++;
}
if (status != null) {
timelineStatuses.remove(position);
statusAdapter.notifyItemRemoved(position);
}
route(DIRECTION.TOP, true);
}
@Override
public void onClickMaxId(String max_id, String id) {
public void onClickMaxId(String max_id) {
max_id_fetch_more = max_id;
Status status = null;
int position = 0;
for (Status currentStatus : timelineStatuses) {
if (currentStatus.id.compareTo(id) == 0) {
status = currentStatus;
break;
}
position++;
}
if (status != null) {
timelineStatuses.remove(position);
statusAdapter.notifyItemRemoved(position);
}
route(DIRECTION.BOTTOM, true);
}

View File

@ -346,24 +346,15 @@ public class TimelinesVM extends AndroidViewModel {
if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.REFRESH || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.SCROLL_TOP) {
//When refreshing/scrolling to TOP, if last statuses fetched has a greater id from newest in cache, there is potential hole
if (statusList.get(statusList.size() - 1).id.compareToIgnoreCase(timelineStatuses.get(0).id) > 0) {
Status statusFetchMore = new Status();
statusFetchMore.isFetchMore = true;
statusFetchMore.id = Helper.generateString();
statusList.add(statusFetchMore);
statusList.get(statusList.size() - 1).isFetchMore = true;
}
} else if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.TOP && timelineParams.fetchingMissing) {
if (!timelineStatuses.contains(statusList.get(0))) {
Status statusFetchMore = new Status();
statusFetchMore.isFetchMore = true;
statusFetchMore.id = Helper.generateString();
statusList.add(0, statusFetchMore);
statusList.get(0).isFetchMore = true;
}
} else if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.BOTTOM && timelineParams.fetchingMissing) {
if (!timelineStatuses.contains(statusList.get(statusList.size() - 1))) {
Status statusFetchMore = new Status();
statusFetchMore.isFetchMore = true;
statusFetchMore.id = Helper.generateString();
statusList.add(statusFetchMore);
statusList.get(statusList.size() - 1).isFetchMore = true;
}
}
}

View File

@ -117,6 +117,12 @@
</androidx.appcompat.widget.LinearLayoutCompat>
<include
android:id="@+id/layout_fetch_more"
layout="@layout/drawer_fetch_more"
android:visibility="gone"
tools:visibility="visible" />
</androidx.appcompat.widget.LinearLayoutCompat>
</com.google.android.material.card.MaterialCardView>

View File

@ -648,6 +648,11 @@
</androidx.appcompat.widget.LinearLayoutCompat>
<include
android:id="@+id/layout_fetch_more"
layout="@layout/drawer_fetch_more"
android:visibility="gone"
tools:visibility="visible" />
</androidx.appcompat.widget.LinearLayoutCompat>