mirror of
https://codeberg.org/tom79/Fedilab.git
synced 2024-12-23 09:10:04 +02:00
some fixes with fetch more
This commit is contained in:
parent
d349062fea
commit
a8f0125a8f
3 changed files with 88 additions and 189 deletions
|
@ -298,57 +298,7 @@ public class StatusCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get newest status for a timeline
|
|
||||||
*
|
|
||||||
* @param slug String - slug for the timeline (it's a unique string value for a timeline)
|
|
||||||
* @param instance String - instance
|
|
||||||
* @param user_id String - us
|
|
||||||
* @return Statuses
|
|
||||||
* @throws DBException - throws a db exception
|
|
||||||
*/
|
|
||||||
public Status getNewestStatus(String slug, String instance, String user_id) throws DBException {
|
|
||||||
if (db == null) {
|
|
||||||
throw new DBException("db is null. Wrong initialization.");
|
|
||||||
}
|
|
||||||
String selection = Sqlite.COL_INSTANCE + "='" + instance + "' AND " + Sqlite.COL_USER_ID + "= '" + user_id + "' AND " + Sqlite.COL_SLUG + "= '" + slug + "'";
|
|
||||||
try {
|
|
||||||
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, null, null, Sqlite.COL_STATUS_ID + " DESC", "1");
|
|
||||||
Statuses statuses = createStatusReply(cursorToListOfStatuses(c));
|
|
||||||
if (statuses.statuses != null && statuses.statuses.size() > 0) {
|
|
||||||
return statuses.statuses.get(0);
|
|
||||||
} else return null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get oldest status for a timeline
|
|
||||||
*
|
|
||||||
* @param slug String - slug for the timeline (it's a unique string value for a timeline)
|
|
||||||
* @param instance String - instance
|
|
||||||
* @param user_id String - us
|
|
||||||
* @return Statuses
|
|
||||||
* @throws DBException - throws a db exception
|
|
||||||
*/
|
|
||||||
public Status getOldestStatus(String slug, String instance, String user_id) throws DBException {
|
|
||||||
if (db == null) {
|
|
||||||
throw new DBException("db is null. Wrong initialization.");
|
|
||||||
}
|
|
||||||
String selection = Sqlite.COL_INSTANCE + "='" + instance + "' AND " + Sqlite.COL_USER_ID + "= '" + user_id + "' AND " + Sqlite.COL_SLUG + "= '" + slug + "'";
|
|
||||||
try {
|
|
||||||
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, null, null, Sqlite.COL_STATUS_ID + " ASC", "1");
|
|
||||||
Statuses statuses = createStatusReply(cursorToListOfStatuses(c));
|
|
||||||
if (statuses.statuses != null && statuses.statuses.size() > 0) {
|
|
||||||
return statuses.statuses.get(0);
|
|
||||||
} else return null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get paginated statuses from db
|
* Get paginated statuses from db
|
||||||
|
@ -366,15 +316,15 @@ public class StatusCache {
|
||||||
throw new DBException("db is null. Wrong initialization.");
|
throw new DBException("db is null. Wrong initialization.");
|
||||||
}
|
}
|
||||||
String order = " DESC";
|
String order = " DESC";
|
||||||
String selection = Sqlite.COL_INSTANCE + "='" + instance + "' AND " + Sqlite.COL_USER_ID + "= '" + user_id + "' AND " + Sqlite.COL_SLUG + "= '" + slug + "'";
|
String selection = Sqlite.COL_INSTANCE + "='" + instance + "' AND " + Sqlite.COL_USER_ID + "= '" + user_id + "' AND " + Sqlite.COL_SLUG + "= '" + slug + "' ";
|
||||||
String limit = String.valueOf(MastodonHelper.statusesPerCall(context));
|
String limit = String.valueOf(MastodonHelper.statusesPerCall(context));
|
||||||
if (min_id != null) {
|
if (min_id != null) {
|
||||||
selection += "AND " + Sqlite.COL_STATUS_ID + " > '" + min_id + "'";
|
selection += "AND " + Sqlite.COL_STATUS_ID + " > '" + min_id + "' ";
|
||||||
order = " ASC";
|
order = " ASC";
|
||||||
} else if (max_id != null) {
|
} else if (max_id != null) {
|
||||||
selection += "AND " + Sqlite.COL_STATUS_ID + " < '" + max_id + "'";
|
selection += "AND " + Sqlite.COL_STATUS_ID + " < '" + max_id + "' ";
|
||||||
} else if (since_id != null) {
|
} else if (since_id != null) {
|
||||||
selection += "AND " + Sqlite.COL_STATUS_ID + " > '" + since_id + "'";
|
selection += "AND " + Sqlite.COL_STATUS_ID + " > '" + since_id + "' ";
|
||||||
limit = null;
|
limit = null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -386,59 +336,6 @@ public class StatusCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get statuses from db
|
|
||||||
*
|
|
||||||
* @return Statuses
|
|
||||||
* @throws DBException - throws a db exception
|
|
||||||
*/
|
|
||||||
public Status getTopFetchMore(String slug, String instance, String user_id, String status_id) throws DBException {
|
|
||||||
if (db == null) {
|
|
||||||
throw new DBException("db is null. Wrong initialization.");
|
|
||||||
}
|
|
||||||
String selection = Sqlite.COL_INSTANCE + "='" + instance + "' AND "
|
|
||||||
+ Sqlite.COL_USER_ID + "= '" + user_id + "' AND "
|
|
||||||
+ Sqlite.COL_SLUG + "= '" + slug + "' AND "
|
|
||||||
+ Sqlite.COL_STATUS_ID + " > '" + status_id + "'";
|
|
||||||
try {
|
|
||||||
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, null, null, Sqlite.COL_STATUS_ID + " ASC", "1");
|
|
||||||
if (c != null && c.getCount() > 0) {
|
|
||||||
return convertCursorToStatus(c);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get statuses from db
|
|
||||||
*
|
|
||||||
* @return Statuses
|
|
||||||
* @throws DBException - throws a db exception
|
|
||||||
*/
|
|
||||||
public Status getBottomFetchMore(String slug, String instance, String user_id, String status_id) throws DBException {
|
|
||||||
if (db == null) {
|
|
||||||
throw new DBException("db is null. Wrong initialization.");
|
|
||||||
}
|
|
||||||
String selection = Sqlite.COL_INSTANCE + "='" + instance + "' AND "
|
|
||||||
+ Sqlite.COL_USER_ID + "= '" + user_id + "' AND "
|
|
||||||
+ Sqlite.COL_SLUG + "= '" + slug + "' AND "
|
|
||||||
+ Sqlite.COL_STATUS_ID + " < '" + status_id + "'";
|
|
||||||
try {
|
|
||||||
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, null, null, Sqlite.COL_STATUS_ID + " DESC", "1");
|
|
||||||
if (c != null && c.getCount() > 0) {
|
|
||||||
return convertCursorToStatus(c);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param instance String - instance
|
* @param instance String - instance
|
||||||
|
|
|
@ -69,12 +69,12 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
private TimelinesVM timelinesVM;
|
private TimelinesVM timelinesVM;
|
||||||
private AccountsVM accountsVM;
|
private AccountsVM accountsVM;
|
||||||
private boolean flagLoading;
|
private boolean flagLoading;
|
||||||
private List<Status> statuses;
|
|
||||||
private String search, searchCache;
|
private String search, searchCache;
|
||||||
private Status statusReport;
|
private Status statusReport;
|
||||||
private String max_id, min_id, min_id_fetch_more, max_id_fetch_more;
|
private String max_id, min_id, min_id_fetch_more, max_id_fetch_more;
|
||||||
private StatusAdapter statusAdapter;
|
private StatusAdapter statusAdapter;
|
||||||
private Timeline.TimeLineEnum timelineType;
|
private Timeline.TimeLineEnum timelineType;
|
||||||
|
private List<Status> timelineStatuses;
|
||||||
//Handle actions that can be done in other fragments
|
//Handle actions that can be done in other fragments
|
||||||
private final BroadcastReceiver receive_action = new BroadcastReceiver() {
|
private final BroadcastReceiver receive_action = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -88,17 +88,17 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
if (receivedStatus != null && statusAdapter != null) {
|
if (receivedStatus != null && statusAdapter != null) {
|
||||||
int position = getPosition(receivedStatus);
|
int position = getPosition(receivedStatus);
|
||||||
if (position >= 0) {
|
if (position >= 0) {
|
||||||
statuses.get(position).reblog = receivedStatus.reblog;
|
timelineStatuses.get(position).reblog = receivedStatus.reblog;
|
||||||
statuses.get(position).reblogged = receivedStatus.reblogged;
|
timelineStatuses.get(position).reblogged = receivedStatus.reblogged;
|
||||||
statuses.get(position).favourited = receivedStatus.favourited;
|
timelineStatuses.get(position).favourited = receivedStatus.favourited;
|
||||||
statuses.get(position).bookmarked = receivedStatus.bookmarked;
|
timelineStatuses.get(position).bookmarked = receivedStatus.bookmarked;
|
||||||
statuses.get(position).reblogs_count = receivedStatus.reblogs_count;
|
timelineStatuses.get(position).reblogs_count = receivedStatus.reblogs_count;
|
||||||
statuses.get(position).favourites_count = receivedStatus.favourites_count;
|
timelineStatuses.get(position).favourites_count = receivedStatus.favourites_count;
|
||||||
statusAdapter.notifyItemChanged(position);
|
statusAdapter.notifyItemChanged(position);
|
||||||
}
|
}
|
||||||
} else if (delete_statuses_for_user != null && statusAdapter != null) {
|
} else if (delete_statuses_for_user != null && statusAdapter != null) {
|
||||||
List<Status> statusesToRemove = new ArrayList<>();
|
List<Status> statusesToRemove = new ArrayList<>();
|
||||||
for (Status status : statuses) {
|
for (Status status : timelineStatuses) {
|
||||||
if (status != null && status.account != null && status.account.id != null && status.account.id.equals(delete_statuses_for_user)) {
|
if (status != null && status.account != null && status.account.id != null && status.account.id.equals(delete_statuses_for_user)) {
|
||||||
statusesToRemove.add(status);
|
statusesToRemove.add(status);
|
||||||
}
|
}
|
||||||
|
@ -106,18 +106,18 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
for (Status statusToRemove : statusesToRemove) {
|
for (Status statusToRemove : statusesToRemove) {
|
||||||
int position = getPosition(statusToRemove);
|
int position = getPosition(statusToRemove);
|
||||||
if (position >= 0) {
|
if (position >= 0) {
|
||||||
statuses.remove(position);
|
timelineStatuses.remove(position);
|
||||||
statusAdapter.notifyItemRemoved(position);
|
statusAdapter.notifyItemRemoved(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (status_to_delete != null && statusAdapter != null) {
|
} else if (status_to_delete != null && statusAdapter != null) {
|
||||||
int position = getPosition(status_to_delete);
|
int position = getPosition(status_to_delete);
|
||||||
if (position >= 0) {
|
if (position >= 0) {
|
||||||
statuses.remove(position);
|
timelineStatuses.remove(position);
|
||||||
statusAdapter.notifyItemRemoved(position);
|
statusAdapter.notifyItemRemoved(position);
|
||||||
}
|
}
|
||||||
} else if (statusPosted != null && statusAdapter != null && timelineType == Timeline.TimeLineEnum.HOME) {
|
} else if (statusPosted != null && statusAdapter != null && timelineType == Timeline.TimeLineEnum.HOME) {
|
||||||
statuses.add(0, statusPosted);
|
timelineStatuses.add(0, statusPosted);
|
||||||
statusAdapter.notifyItemInserted(0);
|
statusAdapter.notifyItemInserted(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
private PinnedTimeline pinnedTimeline;
|
private PinnedTimeline pinnedTimeline;
|
||||||
private String ident;
|
private String ident;
|
||||||
private String slug;
|
private String slug;
|
||||||
|
private TimelinesVM.TimelineParams timelineParams;
|
||||||
private boolean canBeFederated;
|
private boolean canBeFederated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -147,7 +147,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
if (status.id == null) {
|
if (status.id == null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (Status _status : statuses) {
|
for (Status _status : timelineStatuses) {
|
||||||
if (_status.id != null && _status.id.compareTo(status.id) == 0) {
|
if (_status.id != null && _status.id.compareTo(status.id) == 0) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -164,7 +164,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
*/
|
*/
|
||||||
public List<String> getCheckedStatusesId() {
|
public List<String> getCheckedStatusesId() {
|
||||||
List<String> stringList = new ArrayList<>();
|
List<String> stringList = new ArrayList<>();
|
||||||
for (Status status : statuses) {
|
for (Status status : timelineStatuses) {
|
||||||
if (status.isChecked) {
|
if (status.isChecked) {
|
||||||
stringList.add(status.id);
|
stringList.add(status.id);
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,6 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
route(DIRECTION.REFRESH, true);
|
route(DIRECTION.REFRESH, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statuses == null || statuses.statuses == null || statuses.statuses.size() == 0) {
|
if (statuses == null || statuses.statuses == null || statuses.statuses.size() == 0) {
|
||||||
binding.noAction.setVisibility(View.VISIBLE);
|
binding.noAction.setVisibility(View.VISIBLE);
|
||||||
return;
|
return;
|
||||||
|
@ -308,27 +307,26 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
}
|
}
|
||||||
flagLoading = statuses.pagination.max_id == null;
|
flagLoading = statuses.pagination.max_id == null;
|
||||||
binding.recyclerView.setVisibility(View.VISIBLE);
|
binding.recyclerView.setVisibility(View.VISIBLE);
|
||||||
if (statusAdapter != null && this.statuses != null) {
|
if (statusAdapter != null && timelineStatuses != null) {
|
||||||
int size = this.statuses.size();
|
int size = timelineStatuses.size();
|
||||||
this.statuses.clear();
|
timelineStatuses.clear();
|
||||||
this.statuses = new ArrayList<>();
|
timelineStatuses = new ArrayList<>();
|
||||||
statusAdapter.notifyItemRangeRemoved(0, size);
|
statusAdapter.notifyItemRangeRemoved(0, size);
|
||||||
}
|
}
|
||||||
if (this.statuses == null) {
|
if (timelineStatuses == null) {
|
||||||
this.statuses = new ArrayList<>();
|
timelineStatuses = new ArrayList<>();
|
||||||
}
|
}
|
||||||
if (statusReport != null) {
|
if (statusReport != null) {
|
||||||
this.statuses.add(statusReport);
|
timelineStatuses.add(statusReport);
|
||||||
}
|
}
|
||||||
this.statuses.addAll(statuses.statuses);
|
timelineStatuses.addAll(statuses.statuses);
|
||||||
|
|
||||||
if (max_id == null || (statuses.pagination.max_id != null && statuses.pagination.max_id.compareTo(max_id) < 0)) {
|
if (max_id == null || (statuses.pagination.max_id != null && statuses.pagination.max_id.compareTo(max_id) < 0)) {
|
||||||
max_id = statuses.pagination.max_id;
|
max_id = statuses.pagination.max_id;
|
||||||
}
|
}
|
||||||
if (min_id == null || (statuses.pagination.min_id != null && statuses.pagination.min_id.compareTo(min_id) > 0)) {
|
if (min_id == null || (statuses.pagination.min_id != null && statuses.pagination.min_id.compareTo(min_id) > 0)) {
|
||||||
min_id = statuses.pagination.min_id;
|
min_id = statuses.pagination.min_id;
|
||||||
}
|
}
|
||||||
statusAdapter = new StatusAdapter(this.statuses, timelineType, minified, canBeFederated);
|
statusAdapter = new StatusAdapter(timelineStatuses, timelineType, minified, canBeFederated);
|
||||||
statusAdapter.fetchMoreCallBack = this;
|
statusAdapter.fetchMoreCallBack = this;
|
||||||
if (statusReport != null) {
|
if (statusReport != null) {
|
||||||
scrollToTop();
|
scrollToTop();
|
||||||
|
@ -343,6 +341,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
binding.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
binding.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||||
|
|
||||||
if (requireActivity() instanceof BaseMainActivity) {
|
if (requireActivity() instanceof BaseMainActivity) {
|
||||||
if (dy < 0 && !((BaseMainActivity) requireActivity()).getFloatingVisibility())
|
if (dy < 0 && !((BaseMainActivity) requireActivity()).getFloatingVisibility())
|
||||||
((BaseMainActivity) requireActivity()).manageFloatingButton(true);
|
((BaseMainActivity) requireActivity()).manageFloatingButton(true);
|
||||||
|
@ -386,7 +385,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
binding.swipeContainer.setRefreshing(false);
|
binding.swipeContainer.setRefreshing(false);
|
||||||
binding.loadingNextElements.setVisibility(View.GONE);
|
binding.loadingNextElements.setVisibility(View.GONE);
|
||||||
flagLoading = false;
|
flagLoading = false;
|
||||||
if (statuses != null && fetched_statuses != null && fetched_statuses.statuses != null && fetched_statuses.statuses.size() > 0) {
|
if (timelineStatuses != null && fetched_statuses != null && fetched_statuses.statuses != null && fetched_statuses.statuses.size() > 0) {
|
||||||
flagLoading = fetched_statuses.pagination.max_id == null;
|
flagLoading = fetched_statuses.pagination.max_id == null;
|
||||||
binding.noAction.setVisibility(View.GONE);
|
binding.noAction.setVisibility(View.GONE);
|
||||||
if (timelineType == Timeline.TimeLineEnum.ART) {
|
if (timelineType == Timeline.TimeLineEnum.ART) {
|
||||||
|
@ -432,17 +431,17 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
if (statusListReceived != null && statusListReceived.size() > 0) {
|
if (statusListReceived != null && statusListReceived.size() > 0) {
|
||||||
for (Status statusReceived : statusListReceived) {
|
for (Status statusReceived : statusListReceived) {
|
||||||
int position = 0;
|
int position = 0;
|
||||||
if (this.statuses != null) {
|
if (timelineStatuses != null) {
|
||||||
//First we refresh statuses
|
//First we refresh statuses
|
||||||
statusAdapter.notifyItemRangeChanged(0, this.statuses.size());
|
statusAdapter.notifyItemRangeChanged(0, timelineStatuses.size());
|
||||||
//We loop through messages already in the timeline
|
//We loop through messages already in the timeline
|
||||||
for (Status statusAlreadyPresent : this.statuses) {
|
for (Status statusAlreadyPresent : timelineStatuses) {
|
||||||
//We compare the id of each status and we only add status having an id greater than the another, it is inserted at this position
|
//We compare the id of each status and we only add status having an id greater than the another, it is inserted at this position
|
||||||
//Pinned messages are ignored because their date can be older
|
//Pinned messages are ignored because their date can be older
|
||||||
if (statusReceived.id.compareTo(statusAlreadyPresent.id) > 0) {
|
if (statusReceived.id.compareTo(statusAlreadyPresent.id) > 0) {
|
||||||
//We add the status to a list of id - thus we know it is already in the timeline
|
//We add the status to a list of id - thus we know it is already in the timeline
|
||||||
if (!this.statuses.contains(statusReceived) && !statusReceived.pinned && timelineType != Timeline.TimeLineEnum.ACCOUNT_TIMELINE) {
|
if (!timelineStatuses.contains(statusReceived) && !statusReceived.pinned && timelineType != Timeline.TimeLineEnum.ACCOUNT_TIMELINE) {
|
||||||
this.statuses.add(position, statusReceived);
|
timelineStatuses.add(position, statusReceived);
|
||||||
statusAdapter.notifyItemInserted(position);
|
statusAdapter.notifyItemInserted(position);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -450,9 +449,9 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
//Statuses added at the bottom
|
//Statuses added at the bottom
|
||||||
if (position == this.statuses.size() && !this.statuses.contains(statusReceived)) {
|
if (position == timelineStatuses.size() && !timelineStatuses.contains(statusReceived)) {
|
||||||
//We add the status to a list of id - thus we know it is already in the timeline
|
//We add the status to a list of id - thus we know it is already in the timeline
|
||||||
this.statuses.add(position, statusReceived);
|
timelineStatuses.add(position, statusReceived);
|
||||||
statusAdapter.notifyItemInserted(position);
|
statusAdapter.notifyItemInserted(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,9 +479,9 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
private void storeMarker() {
|
private void storeMarker() {
|
||||||
if (timelineType == Timeline.TimeLineEnum.HOME && mLayoutManager != null) {
|
if (timelineType == Timeline.TimeLineEnum.HOME && mLayoutManager != null) {
|
||||||
int position = mLayoutManager.findFirstVisibleItemPosition();
|
int position = mLayoutManager.findFirstVisibleItemPosition();
|
||||||
if (statuses != null && statuses.size() > position) {
|
if (timelineStatuses != null && timelineStatuses.size() > position) {
|
||||||
try {
|
try {
|
||||||
Status status = statuses.get(position);
|
Status status = timelineStatuses.get(position);
|
||||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
|
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
|
||||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
editor.putString(getString(R.string.SET_INNER_MARKER) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance + slug, status.id);
|
editor.putString(getString(R.string.SET_INNER_MARKER) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance + slug, status.id);
|
||||||
|
@ -521,9 +520,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Initialize with default params
|
//Initialize with default params
|
||||||
TimelinesVM.TimelineParams timelineParams = new TimelinesVM.TimelineParams(timelineType, direction, ident);
|
timelineParams = new TimelinesVM.TimelineParams(timelineType, direction, ident);
|
||||||
timelineParams.limit = MastodonHelper.statusesPerCall(requireActivity());
|
timelineParams.limit = MastodonHelper.statusesPerCall(requireActivity());
|
||||||
|
|
||||||
if (direction == DIRECTION.REFRESH || direction == DIRECTION.SCROLL_TOP) {
|
if (direction == DIRECTION.REFRESH || direction == DIRECTION.SCROLL_TOP) {
|
||||||
timelineParams.maxId = null;
|
timelineParams.maxId = null;
|
||||||
timelineParams.minId = null;
|
timelineParams.minId = null;
|
||||||
|
@ -578,7 +576,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
|
|
||||||
private void getCachedStatus(DIRECTION direction, boolean fetchingMissing, TimelinesVM.TimelineParams timelineParams) {
|
private void getCachedStatus(DIRECTION direction, boolean fetchingMissing, TimelinesVM.TimelineParams timelineParams) {
|
||||||
if (direction == null) {
|
if (direction == null) {
|
||||||
timelinesVM.getTimelineCache(timelineParams)
|
timelinesVM.getTimelineCache(timelineStatuses, timelineParams)
|
||||||
.observe(getViewLifecycleOwner(), statusesCached -> {
|
.observe(getViewLifecycleOwner(), statusesCached -> {
|
||||||
if (statusesCached == null || statusesCached.statuses == null || statusesCached.statuses.size() == 0) {
|
if (statusesCached == null || statusesCached.statuses == null || statusesCached.statuses.size() == 0) {
|
||||||
getLiveStatus(null, fetchingMissing, timelineParams);
|
getLiveStatus(null, fetchingMissing, timelineParams);
|
||||||
|
@ -587,7 +585,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (direction == DIRECTION.BOTTOM) {
|
} else if (direction == DIRECTION.BOTTOM) {
|
||||||
timelinesVM.getTimelineCache(timelineParams)
|
timelinesVM.getTimelineCache(timelineStatuses, timelineParams)
|
||||||
.observe(getViewLifecycleOwner(), statusesCachedBottom -> {
|
.observe(getViewLifecycleOwner(), statusesCachedBottom -> {
|
||||||
if (statusesCachedBottom == null || statusesCachedBottom.statuses == null || statusesCachedBottom.statuses.size() == 0) {
|
if (statusesCachedBottom == null || statusesCachedBottom.statuses == null || statusesCachedBottom.statuses.size() == 0) {
|
||||||
getLiveStatus(DIRECTION.BOTTOM, fetchingMissing, timelineParams);
|
getLiveStatus(DIRECTION.BOTTOM, fetchingMissing, timelineParams);
|
||||||
|
@ -596,9 +594,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (direction == DIRECTION.TOP) {
|
} else if (direction == DIRECTION.TOP) {
|
||||||
timelinesVM.getTimelineCache(timelineParams)
|
timelinesVM.getTimelineCache(timelineStatuses, timelineParams)
|
||||||
.observe(getViewLifecycleOwner(), statusesCachedTop -> {
|
.observe(getViewLifecycleOwner(), statusesCachedTop -> {
|
||||||
|
|
||||||
if (statusesCachedTop == null || statusesCachedTop.statuses == null || statusesCachedTop.statuses.size() == 0) {
|
if (statusesCachedTop == null || statusesCachedTop.statuses == null || statusesCachedTop.statuses.size() == 0) {
|
||||||
getLiveStatus(DIRECTION.TOP, fetchingMissing, timelineParams);
|
getLiveStatus(DIRECTION.TOP, fetchingMissing, timelineParams);
|
||||||
} else {
|
} else {
|
||||||
|
@ -607,7 +604,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
|
|
||||||
});
|
});
|
||||||
} else if (direction == DIRECTION.REFRESH || direction == DIRECTION.SCROLL_TOP) {
|
} else if (direction == DIRECTION.REFRESH || direction == DIRECTION.SCROLL_TOP) {
|
||||||
timelinesVM.getTimelineCache(timelineParams)
|
timelinesVM.getTimelineCache(timelineStatuses, timelineParams)
|
||||||
.observe(getViewLifecycleOwner(), statusesRefresh -> {
|
.observe(getViewLifecycleOwner(), statusesRefresh -> {
|
||||||
if (statusesRefresh == null || statusesRefresh.statuses == null || statusesRefresh.statuses.size() == 0) {
|
if (statusesRefresh == null || statusesRefresh.statuses == null || statusesRefresh.statuses.size() == 0) {
|
||||||
getLiveStatus(direction, fetchingMissing, timelineParams);
|
getLiveStatus(direction, fetchingMissing, timelineParams);
|
||||||
|
@ -624,16 +621,16 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
|
|
||||||
private void getLiveStatus(DIRECTION direction, boolean fetchingMissing, TimelinesVM.TimelineParams timelineParams) {
|
private void getLiveStatus(DIRECTION direction, boolean fetchingMissing, TimelinesVM.TimelineParams timelineParams) {
|
||||||
if (direction == null) {
|
if (direction == null) {
|
||||||
timelinesVM.getTimeline(timelineParams)
|
timelinesVM.getTimeline(timelineStatuses, timelineParams)
|
||||||
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
|
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
|
||||||
} else if (direction == DIRECTION.BOTTOM) {
|
} else if (direction == DIRECTION.BOTTOM) {
|
||||||
timelinesVM.getTimeline(timelineParams)
|
timelinesVM.getTimeline(timelineStatuses, timelineParams)
|
||||||
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, fetchingMissing));
|
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, fetchingMissing));
|
||||||
} else if (direction == DIRECTION.TOP) {
|
} else if (direction == DIRECTION.TOP) {
|
||||||
timelinesVM.getTimeline(timelineParams)
|
timelinesVM.getTimeline(timelineStatuses, timelineParams)
|
||||||
.observe(getViewLifecycleOwner(), statusesTop -> dealWithPagination(statusesTop, DIRECTION.TOP, fetchingMissing));
|
.observe(getViewLifecycleOwner(), statusesTop -> dealWithPagination(statusesTop, DIRECTION.TOP, fetchingMissing));
|
||||||
} else if (direction == DIRECTION.REFRESH || direction == DIRECTION.SCROLL_TOP) {
|
} else if (direction == DIRECTION.REFRESH || direction == DIRECTION.SCROLL_TOP) {
|
||||||
timelinesVM.getTimeline(timelineParams)
|
timelinesVM.getTimeline(timelineStatuses, timelineParams)
|
||||||
.observe(getViewLifecycleOwner(), statusesRefresh -> {
|
.observe(getViewLifecycleOwner(), statusesRefresh -> {
|
||||||
if (statusAdapter != null) {
|
if (statusAdapter != null) {
|
||||||
dealWithPagination(statusesRefresh, direction, true);
|
dealWithPagination(statusesRefresh, direction, true);
|
||||||
|
@ -711,7 +708,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
timelinesVM.getPeertube(remoteInstance, null, MastodonHelper.statusesPerCall(requireActivity()))
|
timelinesVM.getPeertube(remoteInstance, null, MastodonHelper.statusesPerCall(requireActivity()))
|
||||||
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
|
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
|
||||||
} else if (direction == DIRECTION.BOTTOM) {
|
} else if (direction == DIRECTION.BOTTOM) {
|
||||||
timelinesVM.getPeertube(remoteInstance, String.valueOf(statuses.size()), MastodonHelper.statusesPerCall(requireActivity()))
|
timelinesVM.getPeertube(remoteInstance, String.valueOf(timelineStatuses.size()), MastodonHelper.statusesPerCall(requireActivity()))
|
||||||
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
|
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
|
||||||
} else if (direction == DIRECTION.TOP) {
|
} else if (direction == DIRECTION.TOP) {
|
||||||
flagLoading = false;
|
flagLoading = false;
|
||||||
|
@ -826,8 +823,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
* Refresh status in list
|
* Refresh status in list
|
||||||
*/
|
*/
|
||||||
public void refreshAllAdapters() {
|
public void refreshAllAdapters() {
|
||||||
if (statusAdapter != null && statuses != null) {
|
if (statusAdapter != null && timelineStatuses != null) {
|
||||||
statusAdapter.notifyItemRangeChanged(0, statuses.size());
|
statusAdapter.notifyItemRangeChanged(0, timelineStatuses.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +834,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
min_id_fetch_more = min_id;
|
min_id_fetch_more = min_id;
|
||||||
Status status = null;
|
Status status = null;
|
||||||
int position = 0;
|
int position = 0;
|
||||||
for (Status currentStatus : this.statuses) {
|
for (Status currentStatus : timelineStatuses) {
|
||||||
if (currentStatus.id.compareTo(id) == 0) {
|
if (currentStatus.id.compareTo(id) == 0) {
|
||||||
status = currentStatus;
|
status = currentStatus;
|
||||||
break;
|
break;
|
||||||
|
@ -845,7 +842,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
this.statuses.remove(position);
|
timelineStatuses.remove(position);
|
||||||
statusAdapter.notifyItemRemoved(position);
|
statusAdapter.notifyItemRemoved(position);
|
||||||
}
|
}
|
||||||
route(DIRECTION.TOP, true);
|
route(DIRECTION.TOP, true);
|
||||||
|
@ -856,7 +853,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
max_id_fetch_more = max_id;
|
max_id_fetch_more = max_id;
|
||||||
Status status = null;
|
Status status = null;
|
||||||
int position = 0;
|
int position = 0;
|
||||||
for (Status currentStatus : this.statuses) {
|
for (Status currentStatus : timelineStatuses) {
|
||||||
if (currentStatus.id.compareTo(id) == 0) {
|
if (currentStatus.id.compareTo(id) == 0) {
|
||||||
status = currentStatus;
|
status = currentStatus;
|
||||||
break;
|
break;
|
||||||
|
@ -864,7 +861,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
this.statuses.remove(position);
|
timelineStatuses.remove(position);
|
||||||
statusAdapter.notifyItemRemoved(position);
|
statusAdapter.notifyItemRemoved(position);
|
||||||
}
|
}
|
||||||
route(DIRECTION.BOTTOM, true);
|
route(DIRECTION.BOTTOM, true);
|
||||||
|
|
|
@ -341,7 +341,35 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public LiveData<Statuses> getTimeline(TimelineParams timelineParams) {
|
private static void addFetchMore(List<Status> statusList, List<Status> timelineStatuses, TimelineParams timelineParams) throws DBException {
|
||||||
|
if (statusList != null && statusList.size() > 0 && timelineStatuses != null && timelineStatuses.size() > 0) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Statuses> getTimeline(List<Status> timelineStatuses, TimelineParams timelineParams) {
|
||||||
|
|
||||||
statusesMutableLiveData = new MutableLiveData<>();
|
statusesMutableLiveData = new MutableLiveData<>();
|
||||||
MastodonTimelinesService mastodonTimelinesService = init(timelineParams.instance);
|
MastodonTimelinesService mastodonTimelinesService = init(timelineParams.instance);
|
||||||
|
@ -375,32 +403,6 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
statuses.pagination = MastodonHelper.getPagination(timelineResponse.headers());
|
statuses.pagination = MastodonHelper.getPagination(timelineResponse.headers());
|
||||||
|
|
||||||
if (statusList != null && statusList.size() > 0) {
|
if (statusList != null && statusList.size() > 0) {
|
||||||
if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.REFRESH || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.SCROLL_TOP) {
|
|
||||||
Status newestStatus = new StatusCache(getApplication().getApplicationContext()).getNewestStatus(timelineParams.slug, timelineParams.instance, timelineParams.userId);
|
|
||||||
//When refreshing/scrolling to TOP, if last statuses fetched has a greater id from newest in cache, there is potential hole
|
|
||||||
if (newestStatus != null && statusList.get(statusList.size() - 1).id.compareToIgnoreCase(newestStatus.id) > 0) {
|
|
||||||
Status statusFetchMore = new Status();
|
|
||||||
statusFetchMore.isFetchMore = true;
|
|
||||||
statusFetchMore.id = Helper.generateString();
|
|
||||||
statusList.add(statusFetchMore);
|
|
||||||
}
|
|
||||||
} else if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.TOP && timelineParams.fetchingMissing) {
|
|
||||||
Status topStatus = new StatusCache(getApplication().getApplicationContext()).getTopFetchMore(timelineParams.slug, timelineParams.instance, timelineParams.slug, statusList.get(0).id);
|
|
||||||
if (topStatus != null && statusList.get(0).id.compareToIgnoreCase(topStatus.id) < 0) {
|
|
||||||
Status statusFetchMore = new Status();
|
|
||||||
statusFetchMore.isFetchMore = true;
|
|
||||||
statusFetchMore.id = Helper.generateString();
|
|
||||||
statusList.add(0, statusFetchMore);
|
|
||||||
}
|
|
||||||
} else if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.BOTTOM && timelineParams.fetchingMissing) {
|
|
||||||
Status bottomStatus = new StatusCache(getApplication().getApplicationContext()).getBottomFetchMore(timelineParams.slug, timelineParams.instance, timelineParams.slug, statusList.get(0).id);
|
|
||||||
if (bottomStatus != null && statusList.get(statusList.size() - 1).id.compareToIgnoreCase(bottomStatus.id) > 0) {
|
|
||||||
Status statusFetchMore = new Status();
|
|
||||||
statusFetchMore.isFetchMore = true;
|
|
||||||
statusFetchMore.id = Helper.generateString();
|
|
||||||
statusList.add(statusFetchMore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Status status : statuses.statuses) {
|
for (Status status : statuses.statuses) {
|
||||||
StatusCache statusCacheDAO = new StatusCache(getApplication().getApplicationContext());
|
StatusCache statusCacheDAO = new StatusCache(getApplication().getApplicationContext());
|
||||||
StatusCache statusCache = new StatusCache();
|
StatusCache statusCache = new StatusCache();
|
||||||
|
@ -415,6 +417,7 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addFetchMore(statusList, timelineStatuses, timelineParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -428,7 +431,7 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
return statusesMutableLiveData;
|
return statusesMutableLiveData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<Statuses> getTimelineCache(TimelineParams timelineParams) {
|
public LiveData<Statuses> getTimelineCache(List<Status> timelineStatuses, TimelineParams timelineParams) {
|
||||||
statusesMutableLiveData = new MutableLiveData<>();
|
statusesMutableLiveData = new MutableLiveData<>();
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
StatusCache statusCacheDAO = new StatusCache(getApplication().getApplicationContext());
|
StatusCache statusCacheDAO = new StatusCache(getApplication().getApplicationContext());
|
||||||
|
@ -438,6 +441,7 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
if (statuses != null) {
|
if (statuses != null) {
|
||||||
TimelineHelper.filterStatus(getApplication().getApplicationContext(), statuses.statuses, timelineParams.type, true);
|
TimelineHelper.filterStatus(getApplication().getApplicationContext(), statuses.statuses, timelineParams.type, true);
|
||||||
if (statuses.statuses != null && statuses.statuses.size() > 0) {
|
if (statuses.statuses != null && statuses.statuses.size() > 0) {
|
||||||
|
addFetchMore(statuses.statuses, timelineStatuses, timelineParams);
|
||||||
statuses.pagination = new Pagination();
|
statuses.pagination = new Pagination();
|
||||||
statuses.pagination.min_id = statuses.statuses.get(0).id;
|
statuses.pagination.min_id = statuses.statuses.get(0).id;
|
||||||
statuses.pagination.max_id = statuses.statuses.get(statuses.statuses.size() - 1).id;
|
statuses.pagination.max_id = statuses.statuses.get(statuses.statuses.size() - 1).id;
|
||||||
|
@ -876,7 +880,8 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
"local: " + local + "\n" +
|
"local: " + local + "\n" +
|
||||||
"maxId: " + maxId + "\n" +
|
"maxId: " + maxId + "\n" +
|
||||||
"sinceId: " + sinceId + "\n" +
|
"sinceId: " + sinceId + "\n" +
|
||||||
"minId: " + minId + "\n";
|
"minId: " + minId + "\n" +
|
||||||
|
"fetchingMissing: " + fetchingMissing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue