Refreshing uses since_id wherever applicable. Also, reverted the notification icon.

This commit is contained in:
Vavassor 2017-03-10 15:12:40 -05:00
parent eed8168e8a
commit 851a92a271
17 changed files with 43 additions and 134 deletions

View File

@ -25,15 +25,12 @@ import java.util.List;
abstract class AccountAdapter extends RecyclerView.Adapter {
List<Account> accountList;
AccountActionListener accountActionListener;
FooterActionListener footerActionListener;
FooterViewHolder.State footerState;
AccountAdapter(AccountActionListener accountActionListener,
FooterActionListener footerActionListener) {
AccountAdapter(AccountActionListener accountActionListener) {
super();
accountList = new ArrayList<>();
this.accountActionListener = accountActionListener;
this.footerActionListener = footerActionListener;
footerState = FooterViewHolder.State.LOADING;
}

View File

@ -37,8 +37,7 @@ import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
public class AccountFragment extends Fragment implements AccountActionListener,
FooterActionListener {
public class AccountFragment extends Fragment implements AccountActionListener {
private static final String TAG = "Account"; // logging tag
public enum Type {
@ -106,7 +105,7 @@ public class AccountFragment extends Fragment implements AccountActionListener,
AccountAdapter adapter = (AccountAdapter) view.getAdapter();
Account account = adapter.getItem(adapter.getItemCount() - 2);
if (account != null) {
fetchAccounts(account.id);
fetchAccounts(account.id, null);
} else {
fetchAccounts();
}
@ -114,9 +113,9 @@ public class AccountFragment extends Fragment implements AccountActionListener,
};
recyclerView.addOnScrollListener(scrollListener);
if (type == Type.BLOCKS) {
adapter = new BlocksAdapter(this, this);
adapter = new BlocksAdapter(this);
} else {
adapter = new FollowAdapter(this, this);
adapter = new FollowAdapter(this);
}
recyclerView.setAdapter(adapter);
@ -151,7 +150,7 @@ public class AccountFragment extends Fragment implements AccountActionListener,
super.onDestroyView();
}
private void fetchAccounts(final String fromId) {
private void fetchAccounts(final String fromId, String uptoId) {
Callback<List<Account>> cb = new Callback<List<Account>>() {
@Override
public void onResponse(Call<List<Account>> call, retrofit2.Response<List<Account>> response) {
@ -167,22 +166,22 @@ public class AccountFragment extends Fragment implements AccountActionListener,
switch (type) {
default:
case FOLLOWS: {
api.accountFollowing(accountId, fromId, null, null).enqueue(cb);
api.accountFollowing(accountId, fromId, uptoId, null).enqueue(cb);
break;
}
case FOLLOWERS: {
api.accountFollowers(accountId, fromId, null, null).enqueue(cb);
api.accountFollowers(accountId, fromId, uptoId, null).enqueue(cb);
break;
}
case BLOCKS: {
api.blocks(fromId, null, null).enqueue(cb);
api.blocks(fromId, uptoId, null).enqueue(cb);
break;
}
}
}
private void fetchAccounts() {
fetchAccounts(null);
fetchAccounts(null, null);
}
private static boolean findAccount(List<Account> accounts, String id) {
@ -229,15 +228,6 @@ public class AccountFragment extends Fragment implements AccountActionListener,
}
}
public void onLoadMore() {
Account account = adapter.getItem(adapter.getItemCount() - 2);
if (account != null) {
fetchAccounts(account.id);
} else {
fetchAccounts();
}
}
public void onViewAccount(String id) {
Intent intent = new Intent(getContext(), AccountActivity.class);
intent.putExtra("id", id);

View File

@ -35,9 +35,8 @@ class BlocksAdapter extends AccountAdapter {
private Set<Integer> unblockedAccountPositions;
BlocksAdapter(AccountActionListener accountActionListener,
FooterActionListener footerActionListener) {
super(accountActionListener, footerActionListener);
BlocksAdapter(AccountActionListener accountActionListener) {
super(accountActionListener);
unblockedAccountPositions = new HashSet<>();
}

View File

@ -31,9 +31,8 @@ class FollowAdapter extends AccountAdapter {
private static final int VIEW_TYPE_ACCOUNT = 0;
private static final int VIEW_TYPE_FOOTER = 1;
FollowAdapter(AccountActionListener accountActionListener,
FooterActionListener footerActionListener) {
super(accountActionListener, footerActionListener);
FollowAdapter(AccountActionListener accountActionListener) {
super(accountActionListener);
}
@Override

View File

@ -1,20 +0,0 @@
/* Copyright 2017 Andrew Dawson
*
* This file is part of Tusky.
*
* Tusky is free software: you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky. If not, see
* <http://www.gnu.org/licenses/>. */
package com.keylesspalace.tusky;
public interface FooterActionListener {
void onLoadMore();
}

View File

@ -82,7 +82,7 @@ public class LoginActivity extends BaseActivity {
private void redirectUserToAuthorizeAndLogin() {
/* To authorize this app and log in it's necessary to redirect to the domain given,
* activity_login there, and the server will redirect back to the app with its response. */
String endpoint = getString(R.string.endpoint_authorize);
String endpoint = MastodonAPI.ENDPOINT_AUTHORIZE;
String redirectUri = getOauthRedirectUri();
Map<String, String> parameters = new HashMap<>();
parameters.put("client_id", clientId);

View File

@ -25,6 +25,8 @@ import retrofit2.http.Path;
import retrofit2.http.Query;
public interface MastodonAPI {
String ENDPOINT_AUTHORIZE = "/oauth/authorize";
@GET("api/v1/timelines/home")
Call<List<Status>> homeTimeline(
@Query("max_id") String maxId,

View File

@ -44,16 +44,13 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
private List<Notification> notifications;
private StatusActionListener statusListener;
private FollowListener followListener;
private FooterActionListener footerListener;
private FooterViewHolder.State footerState;
NotificationsAdapter(StatusActionListener statusListener, FollowListener followListener,
FooterActionListener footerListener) {
NotificationsAdapter(StatusActionListener statusListener, FollowListener followListener) {
super();
notifications = new ArrayList<>();
this.statusListener = statusListener;
this.followListener = followListener;
this.footerListener = footerListener;
footerState = FooterViewHolder.State.LOADING;
}
@ -187,7 +184,6 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
interface FollowListener {
void onViewAccount(String id);
void onFollow(String id);
}
private static class FollowViewHolder extends RecyclerView.ViewHolder {

View File

@ -38,7 +38,7 @@ import retrofit2.Call;
import retrofit2.Callback;
public class NotificationsFragment extends SFragment implements
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener,
SwipeRefreshLayout.OnRefreshListener, StatusActionListener,
NotificationsAdapter.FollowListener {
private static final String TAG = "Notifications"; // logging tag
@ -91,14 +91,14 @@ public class NotificationsFragment extends SFragment implements
NotificationsAdapter adapter = (NotificationsAdapter) view.getAdapter();
Notification notification = adapter.getItem(adapter.getItemCount() - 2);
if (notification != null) {
sendFetchNotificationsRequest(notification.id);
sendFetchNotificationsRequest(notification.id, null);
} else {
sendFetchNotificationsRequest();
}
}
};
recyclerView.addOnScrollListener(scrollListener);
adapter = new NotificationsAdapter(this, this, this);
adapter = new NotificationsAdapter(this, this);
recyclerView.setAdapter(adapter);
TabLayout layout = (TabLayout) getActivity().findViewById(R.id.tab_layout);
@ -116,8 +116,6 @@ public class NotificationsFragment extends SFragment implements
};
layout.addOnTabSelectedListener(onTabSelectedListener);
sendFetchNotificationsRequest();
return rootView;
}
@ -133,10 +131,10 @@ public class NotificationsFragment extends SFragment implements
scrollListener.reset();
}
private void sendFetchNotificationsRequest(final String fromId) {
private void sendFetchNotificationsRequest(final String fromId, String uptoId) {
MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
api.notifications(fromId, null, null).enqueue(new Callback<List<Notification>>() {
api.notifications(fromId, uptoId, null).enqueue(new Callback<List<Notification>>() {
@Override
public void onResponse(Call<List<Notification>> call, retrofit2.Response<List<Notification>> response) {
onFetchNotificationsSuccess(response.body(), fromId);
@ -150,7 +148,7 @@ public class NotificationsFragment extends SFragment implements
}
private void sendFetchNotificationsRequest() {
sendFetchNotificationsRequest(null);
sendFetchNotificationsRequest(null, null);
}
private static boolean findNotification(List<Notification> notifications, String id) {
@ -193,13 +191,9 @@ public class NotificationsFragment extends SFragment implements
}
public void onRefresh() {
sendFetchNotificationsRequest();
}
public void onLoadMore() {
Notification notification = adapter.getItem(adapter.getItemCount() - 2);
Notification notification = adapter.getItem(0);
if (notification != null) {
sendFetchNotificationsRequest(notification.id);
sendFetchNotificationsRequest(null, notification.id);
} else {
sendFetchNotificationsRequest();
}
@ -241,8 +235,4 @@ public class NotificationsFragment extends SFragment implements
public void onViewAccount(String id) {
super.viewAccount(id);
}
public void onFollow(String id) {
super.follow(id);
}
}

View File

@ -20,7 +20,6 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
public class PreferencesActivity extends BaseActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {

View File

@ -32,15 +32,12 @@ class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover
private List<Status> statuses;
private StatusActionListener statusListener;
private FooterActionListener footerListener;
private FooterViewHolder.State footerState;
TimelineAdapter(StatusActionListener statusListener,
FooterActionListener footerListener) {
TimelineAdapter(StatusActionListener statusListener) {
super();
statuses = new ArrayList<>();
this.statusListener = statusListener;
this.footerListener = footerListener;
footerState = FooterViewHolder.State.LOADING;
}

View File

@ -18,6 +18,7 @@ package com.keylesspalace.tusky;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DividerItemDecoration;
@ -35,12 +36,11 @@ import retrofit2.Call;
import retrofit2.Callback;
public class TimelineFragment extends SFragment implements
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
SwipeRefreshLayout.OnRefreshListener, StatusActionListener {
private static final String TAG = "Timeline"; // logging tag
public enum Kind {
enum Kind {
HOME,
MENTIONS,
PUBLIC,
TAG,
USER,
@ -106,14 +106,14 @@ public class TimelineFragment extends SFragment implements
TimelineAdapter adapter = (TimelineAdapter) view.getAdapter();
Status status = adapter.getItem(adapter.getItemCount() - 2);
if (status != null) {
sendFetchTimelineRequest(status.id);
sendFetchTimelineRequest(status.id, null);
} else {
sendFetchTimelineRequest();
}
}
};
recyclerView.addOnScrollListener(scrollListener);
adapter = new TimelineAdapter(this, this);
adapter = new TimelineAdapter(this);
recyclerView.setAdapter(adapter);
if (jumpToTopAllowed()) {
@ -156,7 +156,7 @@ public class TimelineFragment extends SFragment implements
scrollListener.reset();
}
private void sendFetchTimelineRequest(final String fromId) {
private void sendFetchTimelineRequest(@Nullable final String fromId, @Nullable String uptoId) {
MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
Callback<List<Status>> cb = new Callback<List<Status>>() {
@ -174,30 +174,30 @@ public class TimelineFragment extends SFragment implements
switch (kind) {
default:
case HOME: {
api.homeTimeline(fromId, null, null).enqueue(cb);
api.homeTimeline(fromId, uptoId, null).enqueue(cb);
break;
}
case PUBLIC: {
api.publicTimeline(null, fromId, null, null).enqueue(cb);
api.publicTimeline(null, fromId, uptoId, null).enqueue(cb);
break;
}
case TAG: {
api.hashtagTimeline(hashtagOrId, null, fromId, null, null).enqueue(cb);
api.hashtagTimeline(hashtagOrId, null, fromId, uptoId, null).enqueue(cb);
break;
}
case USER: {
api.accountStatuses(hashtagOrId, fromId, null, null).enqueue(cb);
api.accountStatuses(hashtagOrId, fromId, uptoId, null).enqueue(cb);
break;
}
case FAVOURITES: {
api.favourites(fromId, null, null).enqueue(cb);
api.favourites(fromId, uptoId, null).enqueue(cb);
break;
}
}
}
private void sendFetchTimelineRequest() {
sendFetchTimelineRequest(null);
sendFetchTimelineRequest(null, null);
}
private static boolean findStatus(List<Status> statuses, String id) {
@ -240,13 +240,9 @@ public class TimelineFragment extends SFragment implements
}
public void onRefresh() {
sendFetchTimelineRequest();
}
public void onLoadMore() {
Status status = adapter.getItem(adapter.getItemCount() - 2);
Status status = adapter.getItem(0);
if (status != null) {
sendFetchTimelineRequest(status.id);
sendFetchTimelineRequest(null, status.id);
} else {
sendFetchTimelineRequest();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 789 B

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -6,42 +6,6 @@
<string name="oauth_redirect_host">oauth2redirect</string>
<string name="preferences_file_key">com.keylesspalace.tusky.PREFERENCES</string>
<string name="endpoint_status">/api/v1/statuses</string>
<string name="endpoint_media">/api/v1/media</string>
<string name="endpoint_timelines_home">/api/v1/timelines/home</string>
<string name="endpoint_timelines_mentions">/api/v1/timelines/mentions</string>
<string name="endpoint_timelines_public">/api/v1/timelines/public</string>
<string name="endpoint_timelines_tag">/api/v1/timelines/tag/%s</string>
<string name="endpoint_notifications">/api/v1/notifications</string>
<string name="endpoint_follows">/api/v1/follows</string>
<string name="endpoint_get_status">/api/v1/statuses/%s</string>
<string name="endpoint_accounts">/api/v1/accounts/%s</string>
<string name="endpoint_verify_credentials">/api/v1/accounts/verify_credentials</string>
<string name="endpoint_statuses">/api/v1/accounts/%s/statuses</string>
<string name="endpoint_following">/api/v1/accounts/%s/following</string>
<string name="endpoint_followers">/api/v1/accounts/%s/followers</string>
<string name="endpoint_relationships">/api/v1/accounts/relationships</string>
<string name="endpoint_blocks">/api/v1/blocks</string>
<string name="endpoint_favourites">/api/v1/favourites</string>
<string name="endpoint_delete">/api/v1/statuses/%s</string>
<string name="endpoint_reblog">/api/v1/statuses/%s/reblog</string>
<string name="endpoint_unreblog">/api/v1/statuses/%s/unreblog</string>
<string name="endpoint_favourite">/api/v1/statuses/%s/favourite</string>
<string name="endpoint_unfavourite">/api/v1/statuses/%s/unfavourite</string>
<string name="endpoint_context">/api/v1/statuses/%s/context</string>
<string name="endpoint_reblogged_by">/api/v1/statuses/%s/reblogged_by</string>
<string name="endpoint_favourited_by">/api/v1/statuses/%s/favourited_by</string>
<string name="endpoint_follow">/api/v1/accounts/%s/follow</string>
<string name="endpoint_unfollow">/api/v1/accounts/%s/unfollow</string>
<string name="endpoint_block">/api/v1/accounts/%s/block</string>
<string name="endpoint_unblock">/api/v1/accounts/%s/unblock</string>
<string name="endpoint_reports">/api/v1/reports</string>
<string name="endpoint_apps">/api/v1/apps</string>
<string name="endpoint_authorize">/oauth/authorize</string>
<string name="endpoint_token">/oauth/token</string>
<string name="endpoint_devices_register">/api/v1/devices/register</string>
<string name="endpoint_devices_unregister">/api/v1/devices/unregister</string>
<string name="error_authorization_unknown">An unidentified authorization error occurred.</string>
<string name="error_fetching_notifications">Notifications could not be fetched.</string>
<string name="error_compose_character_limit">The status is too long!</string>
@ -157,12 +121,12 @@
<string name="action_compose_options">Privacy options</string>
<string name="login_success">Welcome back!</string>
<string name="action_share">Share</string>
<string name="send_status_to">Share toot URL to...</string>
<string name="send_status_to">Share toot URL to</string>
<string name="action_mute">Mute</string>
<string name="action_unmute">Unmute</string>
<string name="error_unmuting">That user wasn\'t unmuted.</string>
<string name="error_muting">That user wasn\'t muted.</string>
<string name="search">Search accounts...</string>
<string name="search">Search accounts</string>
<string name="toggle_nsfw">NSFW</string>
</resources>