diff --git a/app/src/main/java/com/keylesspalace/tusky/Account.java b/app/src/main/java/com/keylesspalace/tusky/Account.java
index 8cb45b37..c22eab6f 100644
--- a/app/src/main/java/com/keylesspalace/tusky/Account.java
+++ b/app/src/main/java/com/keylesspalace/tusky/Account.java
@@ -73,4 +73,20 @@ public class Account {
}
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);
+ }
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/AccountAdapter.java b/app/src/main/java/com/keylesspalace/tusky/AccountAdapter.java
index efc0a02b..35c2cf87 100644
--- a/app/src/main/java/com/keylesspalace/tusky/AccountAdapter.java
+++ b/app/src/main/java/com/keylesspalace/tusky/AccountAdapter.java
@@ -71,6 +71,7 @@ public class AccountAdapter extends RecyclerView.Adapter {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setupButton(footerActionListener);
holder.setRetryMessage(R.string.footer_retry_accounts);
+ holder.setEndOfTimelineMessage(R.string.footer_end_of_accounts);
}
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/AccountFragment.java b/app/src/main/java/com/keylesspalace/tusky/AccountFragment.java
index af619231..3eb3868b 100644
--- a/app/src/main/java/com/keylesspalace/tusky/AccountFragment.java
+++ b/app/src/main/java/com/keylesspalace/tusky/AccountFragment.java
@@ -46,6 +46,7 @@ import java.util.Map;
public class AccountFragment extends Fragment implements AccountActionListener,
FooterActionListener {
private static final String TAG = "Account";
+ private static int EXPECTED_ACCOUNTS_FETCHED = 20;
public enum Type {
FOLLOWS,
@@ -200,20 +201,24 @@ public class AccountFragment extends Fragment implements AccountActionListener,
} else {
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) {
- showFetchAccountsRetry(true);
+ setFetchTimelineState(FooterViewHolder.State.RETRY);
Log.e(TAG, "Fetch failure: " + exception.getMessage());
}
- private void showFetchAccountsRetry(boolean show) {
+ private void setFetchTimelineState(FooterViewHolder.State state) {
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
if (viewHolder != null) {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
- holder.showRetry(show);
+ holder.setState(state);
}
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/FooterViewHolder.java b/app/src/main/java/com/keylesspalace/tusky/FooterViewHolder.java
index cb68cb95..247e4e5a 100644
--- a/app/src/main/java/com/keylesspalace/tusky/FooterViewHolder.java
+++ b/app/src/main/java/com/keylesspalace/tusky/FooterViewHolder.java
@@ -27,6 +27,13 @@ public class FooterViewHolder extends RecyclerView.ViewHolder {
private TextView retryMessage;
private Button retry;
private ProgressBar progressBar;
+ private TextView endOfTimelineMessage;
+
+ enum State {
+ LOADING,
+ RETRY,
+ END_OF_TIMELINE,
+ }
public FooterViewHolder(View itemView) {
super(itemView);
@@ -35,6 +42,7 @@ public class FooterViewHolder extends RecyclerView.ViewHolder {
retry = (Button) itemView.findViewById(R.id.footer_retry_button);
progressBar = (ProgressBar) itemView.findViewById(R.id.footer_progress_bar);
progressBar.setIndeterminate(true);
+ endOfTimelineMessage = (TextView) itemView.findViewById(R.id.footer_end_of_timeline_text);
}
public void setupButton(final FooterActionListener listener) {
@@ -50,13 +58,30 @@ public class FooterViewHolder extends RecyclerView.ViewHolder {
retryMessage.setText(messageId);
}
- public void showRetry(boolean show) {
- if (!show) {
- retryBar.setVisibility(View.GONE);
- progressBar.setVisibility(View.VISIBLE);
- } else {
- retryBar.setVisibility(View.VISIBLE);
- progressBar.setVisibility(View.GONE);
+ public void setEndOfTimelineMessage(int messageId) {
+ endOfTimelineMessage.setText(messageId);
+ }
+
+ public void setState(State state) {
+ switch (state) {
+ 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;
+ }
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/keylesspalace/tusky/Notification.java b/app/src/main/java/com/keylesspalace/tusky/Notification.java
index d5fbacf3..6dce737c 100644
--- a/app/src/main/java/com/keylesspalace/tusky/Notification.java
+++ b/app/src/main/java/com/keylesspalace/tusky/Notification.java
@@ -91,4 +91,20 @@ public class Notification {
}
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);
+ }
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java b/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java
index 13b3bd42..f8dcfa3d 100644
--- a/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java
+++ b/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java
@@ -102,6 +102,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter implements Adapte
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setupButton(footerListener);
holder.setRetryMessage(R.string.footer_retry_notifications);
+ holder.setEndOfTimelineMessage(R.string.footer_end_of_notifications);
}
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java b/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java
index 9209b1eb..b815a7cd 100644
--- a/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java
+++ b/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java
@@ -43,6 +43,7 @@ import java.util.Map;
public class NotificationsFragment extends SFragment implements
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
private static final String TAG = "Notifications"; // logging tag
+ private static final int EXPECTED_NOTIFICATIONS_FETCHED = 10;
private SwipeRefreshLayout swipeRefreshLayout;
private RecyclerView recyclerView;
@@ -139,22 +140,26 @@ public class NotificationsFragment extends SFragment implements
} else {
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);
}
private void onFetchNotificationsFailure(Exception exception) {
- showFetchTimelineRetry(true);
+ setFetchTimelineState(FooterViewHolder.State.RETRY);
swipeRefreshLayout.setRefreshing(false);
Log.e(TAG, "Fetch failure: " + exception.getMessage());
}
- private void showFetchTimelineRetry(boolean show) {
+ private void setFetchTimelineState(FooterViewHolder.State state) {
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
if (viewHolder != null) {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
- holder.showRetry(show);
+ holder.setState(state);
}
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/TimelineAdapter.java b/app/src/main/java/com/keylesspalace/tusky/TimelineAdapter.java
index 96295db0..d14e9ec6 100644
--- a/app/src/main/java/com/keylesspalace/tusky/TimelineAdapter.java
+++ b/app/src/main/java/com/keylesspalace/tusky/TimelineAdapter.java
@@ -67,6 +67,7 @@ public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItem
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setupButton(footerListener);
holder.setRetryMessage(R.string.footer_retry_statuses);
+ holder.setEndOfTimelineMessage(R.string.footer_end_of_statuses);
}
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java b/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java
index 5cebce5e..dcef6553 100644
--- a/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java
+++ b/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java
@@ -43,6 +43,7 @@ import java.util.Map;
public class TimelineFragment extends SFragment implements
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
private static final String TAG = "Timeline"; // logging tag
+ private static final int EXPECTED_STATUSES_FETCHED = 20;
public enum Kind {
HOME,
@@ -229,22 +230,26 @@ public class TimelineFragment extends SFragment implements
} else {
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);
}
public void onFetchTimelineFailure(Exception exception) {
- showFetchTimelineRetry(true);
+ setFetchTimelineState(FooterViewHolder.State.RETRY);
swipeRefreshLayout.setRefreshing(false);
Log.e(TAG, exception.getMessage());
}
- private void showFetchTimelineRetry(boolean show) {
+ private void setFetchTimelineState(FooterViewHolder.State state) {
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
if (viewHolder != null) {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
- holder.showRetry(show);
+ holder.setState(state);
}
}
diff --git a/app/src/main/res/layout/item_footer.xml b/app/src/main/res/layout/item_footer.xml
index c07c8e96..44e8d6f6 100644
--- a/app/src/main/res/layout/item_footer.xml
+++ b/app/src/main/res/layout/item_footer.xml
@@ -36,6 +36,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 31f4c4b3..83220dc6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -74,6 +74,9 @@
Could not load the rest of the statuses.
Could not load the rest of the statuses.
Could not load the rest of the accounts.
+ end of the statuses
+ end of the notifications
+ end of the accounts
%s boosted your status
%s favourited your status