End of timelines are now detected correctly. Also, duplicate notifications/accounts are prevented.
This commit is contained in:
parent
5f39da27b3
commit
33883aca3d
11 changed files with 103 additions and 19 deletions
|
@ -73,4 +73,20 @@ public class Account {
|
||||||
}
|
}
|
||||||
return accounts;
|
return accounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return id.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (this.id == null) {
|
||||||
|
return this == other;
|
||||||
|
} else if (!(other instanceof Account)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Account account = (Account) other;
|
||||||
|
return account.id.equals(this.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ public class AccountAdapter extends RecyclerView.Adapter {
|
||||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||||
holder.setupButton(footerActionListener);
|
holder.setupButton(footerActionListener);
|
||||||
holder.setRetryMessage(R.string.footer_retry_accounts);
|
holder.setRetryMessage(R.string.footer_retry_accounts);
|
||||||
|
holder.setEndOfTimelineMessage(R.string.footer_end_of_accounts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ import java.util.Map;
|
||||||
public class AccountFragment extends Fragment implements AccountActionListener,
|
public class AccountFragment extends Fragment implements AccountActionListener,
|
||||||
FooterActionListener {
|
FooterActionListener {
|
||||||
private static final String TAG = "Account";
|
private static final String TAG = "Account";
|
||||||
|
private static int EXPECTED_ACCOUNTS_FETCHED = 20;
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
FOLLOWS,
|
FOLLOWS,
|
||||||
|
@ -200,20 +201,24 @@ public class AccountFragment extends Fragment implements AccountActionListener,
|
||||||
} else {
|
} else {
|
||||||
adapter.update(accounts);
|
adapter.update(accounts);
|
||||||
}
|
}
|
||||||
showFetchAccountsRetry(false);
|
if (accounts.size() >= EXPECTED_ACCOUNTS_FETCHED) {
|
||||||
|
setFetchTimelineState(FooterViewHolder.State.LOADING);
|
||||||
|
} else {
|
||||||
|
setFetchTimelineState(FooterViewHolder.State.END_OF_TIMELINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFetchAccountsFailure(Exception exception) {
|
private void onFetchAccountsFailure(Exception exception) {
|
||||||
showFetchAccountsRetry(true);
|
setFetchTimelineState(FooterViewHolder.State.RETRY);
|
||||||
Log.e(TAG, "Fetch failure: " + exception.getMessage());
|
Log.e(TAG, "Fetch failure: " + exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showFetchAccountsRetry(boolean show) {
|
private void setFetchTimelineState(FooterViewHolder.State state) {
|
||||||
RecyclerView.ViewHolder viewHolder =
|
RecyclerView.ViewHolder viewHolder =
|
||||||
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
|
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
|
||||||
if (viewHolder != null) {
|
if (viewHolder != null) {
|
||||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||||
holder.showRetry(show);
|
holder.setState(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,13 @@ public class FooterViewHolder extends RecyclerView.ViewHolder {
|
||||||
private TextView retryMessage;
|
private TextView retryMessage;
|
||||||
private Button retry;
|
private Button retry;
|
||||||
private ProgressBar progressBar;
|
private ProgressBar progressBar;
|
||||||
|
private TextView endOfTimelineMessage;
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
LOADING,
|
||||||
|
RETRY,
|
||||||
|
END_OF_TIMELINE,
|
||||||
|
}
|
||||||
|
|
||||||
public FooterViewHolder(View itemView) {
|
public FooterViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
@ -35,6 +42,7 @@ public class FooterViewHolder extends RecyclerView.ViewHolder {
|
||||||
retry = (Button) itemView.findViewById(R.id.footer_retry_button);
|
retry = (Button) itemView.findViewById(R.id.footer_retry_button);
|
||||||
progressBar = (ProgressBar) itemView.findViewById(R.id.footer_progress_bar);
|
progressBar = (ProgressBar) itemView.findViewById(R.id.footer_progress_bar);
|
||||||
progressBar.setIndeterminate(true);
|
progressBar.setIndeterminate(true);
|
||||||
|
endOfTimelineMessage = (TextView) itemView.findViewById(R.id.footer_end_of_timeline_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupButton(final FooterActionListener listener) {
|
public void setupButton(final FooterActionListener listener) {
|
||||||
|
@ -50,13 +58,30 @@ public class FooterViewHolder extends RecyclerView.ViewHolder {
|
||||||
retryMessage.setText(messageId);
|
retryMessage.setText(messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showRetry(boolean show) {
|
public void setEndOfTimelineMessage(int messageId) {
|
||||||
if (!show) {
|
endOfTimelineMessage.setText(messageId);
|
||||||
retryBar.setVisibility(View.GONE);
|
}
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
public void setState(State state) {
|
||||||
retryBar.setVisibility(View.VISIBLE);
|
switch (state) {
|
||||||
progressBar.setVisibility(View.GONE);
|
case LOADING: {
|
||||||
|
retryBar.setVisibility(View.GONE);
|
||||||
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
|
endOfTimelineMessage.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RETRY: {
|
||||||
|
retryBar.setVisibility(View.VISIBLE);
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
endOfTimelineMessage.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case END_OF_TIMELINE: {
|
||||||
|
retryBar.setVisibility(View.GONE);
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
endOfTimelineMessage.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -91,4 +91,20 @@ public class Notification {
|
||||||
}
|
}
|
||||||
return notifications;
|
return notifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return id.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (this.id == null) {
|
||||||
|
return this == other;
|
||||||
|
} else if (!(other instanceof Notification)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Notification notification = (Notification) other;
|
||||||
|
return notification.getId().equals(this.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter implements Adapte
|
||||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||||
holder.setupButton(footerListener);
|
holder.setupButton(footerListener);
|
||||||
holder.setRetryMessage(R.string.footer_retry_notifications);
|
holder.setRetryMessage(R.string.footer_retry_notifications);
|
||||||
|
holder.setEndOfTimelineMessage(R.string.footer_end_of_notifications);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ import java.util.Map;
|
||||||
public class NotificationsFragment extends SFragment implements
|
public class NotificationsFragment extends SFragment implements
|
||||||
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
|
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
|
||||||
private static final String TAG = "Notifications"; // logging tag
|
private static final String TAG = "Notifications"; // logging tag
|
||||||
|
private static final int EXPECTED_NOTIFICATIONS_FETCHED = 10;
|
||||||
|
|
||||||
private SwipeRefreshLayout swipeRefreshLayout;
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
private RecyclerView recyclerView;
|
private RecyclerView recyclerView;
|
||||||
|
@ -139,22 +140,26 @@ public class NotificationsFragment extends SFragment implements
|
||||||
} else {
|
} else {
|
||||||
adapter.update(notifications);
|
adapter.update(notifications);
|
||||||
}
|
}
|
||||||
showFetchTimelineRetry(false);
|
if (notifications.size() >= EXPECTED_NOTIFICATIONS_FETCHED) {
|
||||||
|
setFetchTimelineState(FooterViewHolder.State.LOADING);
|
||||||
|
} else {
|
||||||
|
setFetchTimelineState(FooterViewHolder.State.END_OF_TIMELINE);
|
||||||
|
}
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFetchNotificationsFailure(Exception exception) {
|
private void onFetchNotificationsFailure(Exception exception) {
|
||||||
showFetchTimelineRetry(true);
|
setFetchTimelineState(FooterViewHolder.State.RETRY);
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
Log.e(TAG, "Fetch failure: " + exception.getMessage());
|
Log.e(TAG, "Fetch failure: " + exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showFetchTimelineRetry(boolean show) {
|
private void setFetchTimelineState(FooterViewHolder.State state) {
|
||||||
RecyclerView.ViewHolder viewHolder =
|
RecyclerView.ViewHolder viewHolder =
|
||||||
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
|
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
|
||||||
if (viewHolder != null) {
|
if (viewHolder != null) {
|
||||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||||
holder.showRetry(show);
|
holder.setState(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItem
|
||||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||||
holder.setupButton(footerListener);
|
holder.setupButton(footerListener);
|
||||||
holder.setRetryMessage(R.string.footer_retry_statuses);
|
holder.setRetryMessage(R.string.footer_retry_statuses);
|
||||||
|
holder.setEndOfTimelineMessage(R.string.footer_end_of_statuses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ import java.util.Map;
|
||||||
public class TimelineFragment extends SFragment implements
|
public class TimelineFragment extends SFragment implements
|
||||||
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
|
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
|
||||||
private static final String TAG = "Timeline"; // logging tag
|
private static final String TAG = "Timeline"; // logging tag
|
||||||
|
private static final int EXPECTED_STATUSES_FETCHED = 20;
|
||||||
|
|
||||||
public enum Kind {
|
public enum Kind {
|
||||||
HOME,
|
HOME,
|
||||||
|
@ -229,22 +230,26 @@ public class TimelineFragment extends SFragment implements
|
||||||
} else {
|
} else {
|
||||||
adapter.update(statuses);
|
adapter.update(statuses);
|
||||||
}
|
}
|
||||||
showFetchTimelineRetry(false);
|
if (statuses.size() >= EXPECTED_STATUSES_FETCHED) {
|
||||||
|
setFetchTimelineState(FooterViewHolder.State.LOADING);
|
||||||
|
} else {
|
||||||
|
setFetchTimelineState(FooterViewHolder.State.END_OF_TIMELINE);
|
||||||
|
}
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFetchTimelineFailure(Exception exception) {
|
public void onFetchTimelineFailure(Exception exception) {
|
||||||
showFetchTimelineRetry(true);
|
setFetchTimelineState(FooterViewHolder.State.RETRY);
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
Log.e(TAG, exception.getMessage());
|
Log.e(TAG, exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showFetchTimelineRetry(boolean show) {
|
private void setFetchTimelineState(FooterViewHolder.State state) {
|
||||||
RecyclerView.ViewHolder viewHolder =
|
RecyclerView.ViewHolder viewHolder =
|
||||||
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
|
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
|
||||||
if (viewHolder != null) {
|
if (viewHolder != null) {
|
||||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||||
holder.showRetry(show);
|
holder.setState(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,12 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/footer_end_of_timeline_text"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -74,6 +74,9 @@
|
||||||
<string name="footer_retry_statuses">Could not load the rest of the statuses.</string>
|
<string name="footer_retry_statuses">Could not load the rest of the statuses.</string>
|
||||||
<string name="footer_retry_notifications">Could not load the rest of the statuses.</string>
|
<string name="footer_retry_notifications">Could not load the rest of the statuses.</string>
|
||||||
<string name="footer_retry_accounts">Could not load the rest of the accounts.</string>
|
<string name="footer_retry_accounts">Could not load the rest of the accounts.</string>
|
||||||
|
<string name="footer_end_of_statuses">end of the statuses</string>
|
||||||
|
<string name="footer_end_of_notifications">end of the notifications</string>
|
||||||
|
<string name="footer_end_of_accounts">end of the accounts</string>
|
||||||
|
|
||||||
<string name="notification_reblog_format">%s boosted your status</string>
|
<string name="notification_reblog_format">%s boosted your status</string>
|
||||||
<string name="notification_favourite_format">%s favourited your status</string>
|
<string name="notification_favourite_format">%s favourited your status</string>
|
||||||
|
|
Loading…
Reference in a new issue