Fix issue #163 - Fetch more has now two buttons (down or up)

This commit is contained in:
Thomas 2022-07-08 19:02:18 +02:00
parent 4467853b71
commit 91501ab46a
7 changed files with 153 additions and 43 deletions

View File

@ -143,13 +143,21 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
});
} else if (viewHolder.getItemViewType() == NOTIFICATION_FETCH_MORE) {
StatusAdapter.StatusViewHolder holder = (StatusAdapter.StatusViewHolder) viewHolder;
holder.bindingFetchMore.fetchMore.setEnabled(!notification.isFetchMoreHidden);
holder.bindingFetchMore.fetchMore.setOnClickListener(v -> {
holder.bindingFetchMore.fetchMoreContainer.setEnabled(!notification.isFetchMoreHidden);
holder.bindingFetchMore.fetchMoreMin.setOnClickListener(v -> {
if (position + 1 < notificationList.size()) {
//We hide the button
notification.isFetchMoreHidden = true;
notifyItemChanged(position);
fetchMoreCallBack.onClick(notificationList.get(position + 1).id, notification.id);
fetchMoreCallBack.onClickMin(notificationList.get(position + 1).id, notification.id);
}
});
holder.bindingFetchMore.fetchMoreMax.setOnClickListener(v -> {
if (position - 1 >= 0) {
//We hide the button
notification.isFetchMoreHidden = true;
notifyItemChanged(position);
fetchMoreCallBack.onClickMax(notificationList.get(position - 1).id, notification.id);
}
});
} else {
@ -264,7 +272,9 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
public interface FetchMoreCallBack {
void onClick(String min_id, String fetchmoreId);
void onClickMin(String min_id, String fetchmoreId);
void onClickMax(String max_id, String fetchmoreId);
}
static class ViewHolderFollow extends RecyclerView.ViewHolder {

View File

@ -1847,13 +1847,21 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
});
} else if (viewHolder.getItemViewType() == STATUS_FETCH_MORE) {
StatusViewHolder holder = (StatusViewHolder) viewHolder;
holder.bindingFetchMore.fetchMore.setEnabled(!status.isFetchMoreHidden);
holder.bindingFetchMore.fetchMore.setOnClickListener(v -> {
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.onClick(statusList.get(position + 1).id, status.id);
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);
}
});
}
@ -1876,7 +1884,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
public interface FetchMoreCallBack {
void onClick(String min_id, String fetchmoreId);
void onClickMinId(String min_id, String fetchmoreId);
void onClickMaxId(String max_id, String fetchmoreId);
}
public static class StatusViewHolder extends RecyclerView.ViewHolder {

View File

@ -88,7 +88,7 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
}
}
};
private String max_id, min_id, min_id_fetch_more;
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;
@ -316,8 +316,8 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
notificationsVM.getNotifications(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, null, null, null, MastodonHelper.statusesPerCall(requireActivity()), excludeType, null)
.observe(getViewLifecycleOwner(), this::initializeNotificationView);
} else if (direction == FragmentMastodonTimeline.DIRECTION.BOTTOM) {
notificationsVM.getNotifications(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()), excludeType, null)
.observe(getViewLifecycleOwner(), notificationsBottom -> dealWithPagination(notificationsBottom, FragmentMastodonTimeline.DIRECTION.BOTTOM, false));
notificationsVM.getNotifications(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, fetchingMissing ? max_id_fetch_more : max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()), excludeType, null)
.observe(getViewLifecycleOwner(), notificationsBottom -> dealWithPagination(notificationsBottom, FragmentMastodonTimeline.DIRECTION.BOTTOM, fetchingMissing));
} else if (direction == FragmentMastodonTimeline.DIRECTION.TOP) {
notificationsVM.getNotifications(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, null, null, fetchingMissing ? min_id_fetch_more : min_id, MastodonHelper.statusesPerCall(requireActivity()), excludeType, null)
.observe(getViewLifecycleOwner(), notificationsTop -> dealWithPagination(notificationsTop, FragmentMastodonTimeline.DIRECTION.TOP, fetchingMissing));
@ -510,7 +510,7 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
}
@Override
public void onClick(String min_id, String id) {
public void onClickMin(String min_id, String id) {
//Fetch more has been pressed
min_id_fetch_more = min_id;
Notification notification = null;
@ -529,6 +529,25 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
route(FragmentMastodonTimeline.DIRECTION.TOP, true);
}
@Override
public void onClickMax(String max_id, String 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);
}
public enum NotificationTypeEnum {
@SerializedName("ALL")

View File

@ -77,7 +77,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
private List<Status> statuses;
private String search, searchCache;
private Status statusReport;
private String max_id, min_id, min_id_fetch_more;
private String max_id, min_id, min_id_fetch_more, max_id_fetch_more;
private StatusAdapter statusAdapter;
private Timeline.TimeLineEnum timelineType;
//Handle actions that can be done in other fragments
@ -471,7 +471,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
statusFetchMore.isFetchMore = true;
statusFetchMore.id = Helper.generateString();
int insertAt;
if (direction == DIRECTION.REFRESH) {
if (direction == DIRECTION.REFRESH || direction == DIRECTION.BOTTOM) {
insertAt = lastInsertedPosition;
} else {
insertAt = initialInsertedPosition;
@ -620,8 +620,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
timelinesVM.getPublic(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, true, false, false, null, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
} else if (direction == DIRECTION.BOTTOM) {
timelinesVM.getPublic(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, true, false, false, max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
timelinesVM.getPublic(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, true, false, false, fetchingMissing ? max_id_fetch_more : max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, fetchingMissing));
} else if (direction == DIRECTION.TOP) {
timelinesVM.getPublic(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, true, false, false, null, null, fetchingMissing ? min_id_fetch_more : min_id, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.TOP, fetchingMissing));
@ -640,8 +640,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
timelinesVM.getPublic(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, false, true, false, null, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
} else if (direction == DIRECTION.BOTTOM) {
timelinesVM.getPublic(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, false, true, false, max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
timelinesVM.getPublic(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, false, true, false, fetchingMissing ? max_id_fetch_more : max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, fetchingMissing));
} else if (direction == DIRECTION.TOP) {
timelinesVM.getPublic(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, false, true, false, null, null, fetchingMissing ? min_id_fetch_more : min_id, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.TOP, fetchingMissing));
@ -726,8 +726,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
timelinesVM.getPublic(null, remoteInstance, true, false, false, null, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
} else if (direction == DIRECTION.BOTTOM) {
timelinesVM.getPublic(null, remoteInstance, true, false, false, max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
timelinesVM.getPublic(null, remoteInstance, true, false, false, fetchingMissing ? max_id_fetch_more : max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, fetchingMissing));
} else if (direction == DIRECTION.TOP) {
timelinesVM.getPublic(null, remoteInstance, true, false, false, null, null, fetchingMissing ? min_id_fetch_more : min_id, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.TOP, fetchingMissing));
@ -747,8 +747,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
timelinesVM.getList(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, list_id, null, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
} else if (direction == DIRECTION.BOTTOM) {
timelinesVM.getList(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, list_id, max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
timelinesVM.getList(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, list_id, fetchingMissing ? max_id_fetch_more : max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, fetchingMissing));
} else if (direction == DIRECTION.TOP) {
timelinesVM.getList(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, list_id, null, null, fetchingMissing ? min_id_fetch_more : min_id, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.TOP, fetchingMissing));
@ -771,8 +771,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
timelinesVM.getHashTag(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, tagTimeline.name, false, tagTimeline.isART, tagTimeline.all, tagTimeline.any, tagTimeline.none, null, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
} else if (direction == DIRECTION.BOTTOM) {
timelinesVM.getHashTag(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, tagTimeline.name, false, tagTimeline.isART, tagTimeline.all, tagTimeline.any, tagTimeline.none, max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
timelinesVM.getHashTag(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, tagTimeline.name, false, tagTimeline.isART, tagTimeline.all, tagTimeline.any, tagTimeline.none, fetchingMissing ? max_id_fetch_more : max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, fetchingMissing));
} else if (direction == DIRECTION.TOP) {
timelinesVM.getHashTag(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, tagTimeline.name, false, tagTimeline.isART, tagTimeline.all, tagTimeline.any, tagTimeline.none, null, null, fetchingMissing ? min_id_fetch_more : min_id, MastodonHelper.statusesPerCall(requireActivity()))
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.TOP, fetchingMissing));
@ -907,21 +907,26 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
}
} else if (direction == DIRECTION.BOTTOM) {
if (networkAvailable == BaseMainActivity.status.CONNECTED) {
//We first if we get results from cache
timelinesVM.getHomeCache(BaseMainActivity.currentInstance, BaseMainActivity.currentUserID, max_id, null, null)
.observe(getViewLifecycleOwner(), statusesBottomCache -> {
if (statusesBottomCache != null && statusesBottomCache.statuses != null && statusesBottomCache.statuses.size() > 0) {
dealWithPagination(statusesBottomCache, DIRECTION.BOTTOM, false);
} else { // If not, we fetch remotely
timelinesVM.getHome(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, false, max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()), false)
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
}
});
if (!fetchingMissing) {
if (networkAvailable == BaseMainActivity.status.CONNECTED) {
//We first if we get results from cache
timelinesVM.getHomeCache(BaseMainActivity.currentInstance, BaseMainActivity.currentUserID, max_id, null, null)
.observe(getViewLifecycleOwner(), statusesBottomCache -> {
if (statusesBottomCache != null && statusesBottomCache.statuses != null && statusesBottomCache.statuses.size() > 0) {
dealWithPagination(statusesBottomCache, DIRECTION.BOTTOM, false);
} else { // If not, we fetch remotely
timelinesVM.getHome(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, false, max_id, null, null, MastodonHelper.statusesPerCall(requireActivity()), false)
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
}
});
} else {
timelinesVM.getHomeCache(BaseMainActivity.currentInstance, BaseMainActivity.currentUserID, max_id, null, null)
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
}
} else {
timelinesVM.getHomeCache(BaseMainActivity.currentInstance, BaseMainActivity.currentUserID, max_id, null, null)
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
timelinesVM.getHomeCache(BaseMainActivity.currentInstance, BaseMainActivity.currentUserID, max_id_fetch_more, null, null)
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, true));
}
} else if (direction == DIRECTION.TOP) {
if (!fetchingMissing) {
@ -968,7 +973,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
}
@Override
public void onClick(String min_id, String id) {
public void onClickMinId(String min_id, String id) {
//Fetch more has been pressed
min_id_fetch_more = min_id;
Status status = null;
@ -987,6 +992,25 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
route(DIRECTION.TOP, true);
}
@Override
public void onClickMaxId(String max_id, String id) {
max_id_fetch_more = max_id;
Status status = null;
int position = 0;
for (Status currentStatus : this.statuses) {
if (currentStatus.id.compareTo(id) == 0) {
status = currentStatus;
break;
}
position++;
}
if (status != null) {
this.statuses.remove(position);
statusAdapter.notifyItemRemoved(position);
}
route(DIRECTION.BOTTOM, true);
}
public enum DIRECTION {
TOP,
BOTTOM,

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,4c4.41,0 8,3.59 8,8s-3.59,8 -8,8s-8,-3.59 -8,-8S7.59,4 12,4M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2L12,2zM13,12l0,-4h-2l0,4H8l4,4l4,-4H13z" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20M12,22c5.52,0 10,-4.48 10,-10c0,-5.52 -4.48,-10 -10,-10C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22L12,22zM11,12l0,4h2l0,-4h3l-4,-4l-4,4H11z" />
</vector>

View File

@ -1,9 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.button.MaterialButton xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fetch_more"
style="@style/MyOutlinedButton"
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fetch_more_container"
android:layout_gravity="center"
android:layout_margin="6dp"
android:text="@string/fetch_more_messages" />
android:orientation="horizontal"
android:padding="6dp">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/fetch_more_min"
style="@style/MyOutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_arrow_circle_up_24"
android:text="@string/fetch_more_messages"
android:tint="?colorAccent" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:text="@string/fetch_more_messages"
android:textColor="?colorAccent"
android:textSize="18sp" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/fetch_more_max"
style="@style/MyOutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_arrow_circle_down_24"
android:text="@string/fetch_more_messages"
android:tint="?colorAccent" />
</androidx.appcompat.widget.LinearLayoutCompat>