Refreshing uses since_id wherever applicable. Also, reverted the notification icon.
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<>();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 789 B After Width: | Height: | Size: 675 B |
Before Width: | Height: | Size: 531 B After Width: | Height: | Size: 453 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 888 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.3 KiB |
|
@ -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>
|
||||
|
|