Fixed some odd refresh behaviour and possibly the duplicate 20 statuses issue?

This commit is contained in:
Vavassor 2017-03-20 03:03:03 -04:00
parent 7f4637c04c
commit 70536ed001
11 changed files with 47 additions and 158 deletions

View file

@ -25,13 +25,11 @@ import java.util.List;
abstract class AccountAdapter extends RecyclerView.Adapter {
List<Account> accountList;
AccountActionListener accountActionListener;
FooterViewHolder.State footerState;
AccountAdapter(AccountActionListener accountActionListener) {
super();
accountList = new ArrayList<>();
this.accountActionListener = accountActionListener;
footerState = FooterViewHolder.State.LOADING;
}
@Override
@ -40,14 +38,21 @@ abstract class AccountAdapter extends RecyclerView.Adapter {
}
void update(List<Account> newAccounts) {
if (accountList == null || accountList.isEmpty()) {
if (newAccounts == null || newAccounts.isEmpty()) {
return;
}
if (accountList.isEmpty()) {
accountList = newAccounts;
} else {
int index = newAccounts.indexOf(accountList.get(0));
if (index == -1) {
int index = accountList.indexOf(newAccounts.get(newAccounts.size() - 1));
for (int i = 0; i < index; i++) {
accountList.remove(0);
}
int newIndex = newAccounts.indexOf(accountList.get(0));
if (newIndex == -1) {
accountList.addAll(0, newAccounts);
} else {
accountList.addAll(0, newAccounts.subList(0, index));
accountList.addAll(0, newAccounts.subList(0, newIndex));
}
}
notifyDataSetChanged();
@ -65,8 +70,4 @@ abstract class AccountAdapter extends RecyclerView.Adapter {
}
return null;
}
void setFooterState(FooterViewHolder.State state) {
this.footerState = state;
}
}

View file

@ -50,7 +50,6 @@ public class AccountFragment extends BaseFragment implements AccountActionListen
private Type type;
private String accountId;
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private EndlessOnScrollListener scrollListener;
private AccountAdapter adapter;
@ -91,7 +90,7 @@ public class AccountFragment extends BaseFragment implements AccountActionListen
View rootView = inflater.inflate(R.layout.fragment_account, container, false);
Context context = getContext();
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
@ -210,38 +209,17 @@ public class AccountFragment extends BaseFragment implements AccountActionListen
private void onFetchAccountsSuccess(List<Account> accounts, String fromId) {
if (fromId != null) {
if (accounts.size() > 0 && !findAccount(accounts, fromId)) {
setFetchTimelineState(FooterViewHolder.State.LOADING);
adapter.addItems(accounts);
} else {
setFetchTimelineState(FooterViewHolder.State.END_OF_TIMELINE);
}
} else {
if (accounts.size() > 0) {
setFetchTimelineState(FooterViewHolder.State.LOADING);
adapter.update(accounts);
} else {
setFetchTimelineState(FooterViewHolder.State.END_OF_TIMELINE);
}
adapter.update(accounts);
}
}
private void onFetchAccountsFailure(Exception exception) {
setFetchTimelineState(FooterViewHolder.State.RETRY);
Log.e(TAG, "Fetch failure: " + exception.getMessage());
}
private void setFetchTimelineState(FooterViewHolder.State state) {
// Set the adapter to set its state when it's bound, if the current Footer is offscreen.
adapter.setFooterState(state);
// Check if it's onscreen, and update it directly if it is.
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
if (viewHolder != null) {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setState(state);
}
}
public void onViewAccount(String id) {
Intent intent = new Intent(getContext(), AccountActivity.class);
intent.putExtra("id", id);

View file

@ -19,9 +19,7 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.keylesspalace.tusky.entity.Account;
@ -69,9 +67,6 @@ class BlocksAdapter extends AccountAdapter {
holder.setupWithAccount(accountList.get(position));
boolean blocked = !unblockedAccountPositions.contains(position);
holder.setupActionListener(accountActionListener, blocked, position);
} else {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setState(footerState);
}
}

View file

@ -20,15 +20,12 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.keylesspalace.tusky.entity.Account;
import com.pkmmte.view.CircularImageView;
import com.squareup.picasso.Picasso;
import butterknife.ButterKnife;
/** Both for follows and following lists. */
class FollowAdapter extends AccountAdapter {
private static final int VIEW_TYPE_ACCOUNT = 0;
@ -61,9 +58,6 @@ class FollowAdapter extends AccountAdapter {
AccountViewHolder holder = (AccountViewHolder) viewHolder;
holder.setupWithAccount(accountList.get(position));
holder.setupActionListener(accountActionListener);
} else {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setState(footerState);
}
}

View file

@ -17,39 +17,12 @@ package com.keylesspalace.tusky;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
class FooterViewHolder extends RecyclerView.ViewHolder {
private ProgressBar progressBar;
enum State {
LOADING,
RETRY,
END_OF_TIMELINE,
}
FooterViewHolder(View itemView) {
super(itemView);
progressBar = (ProgressBar) itemView.findViewById(R.id.footer_progress_bar);
ProgressBar progressBar = (ProgressBar) itemView.findViewById(R.id.footer_progress_bar);
progressBar.setIndeterminate(true);
}
void setState(State state) {
switch (state) {
case LOADING: {
progressBar.setVisibility(View.VISIBLE);
break;
}
case RETRY: {
progressBar.setVisibility(View.GONE);
break;
}
case END_OF_TIMELINE: {
progressBar.setVisibility(View.GONE);
break;
}
}
}
}

View file

@ -44,14 +44,12 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
private List<Notification> notifications;
private StatusActionListener statusListener;
private FollowListener followListener;
private FooterViewHolder.State footerState;
NotificationsAdapter(StatusActionListener statusListener, FollowListener followListener) {
super();
notifications = new ArrayList<>();
this.statusListener = statusListener;
this.followListener = followListener;
footerState = FooterViewHolder.State.LOADING;
}
@Override
@ -108,9 +106,6 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
break;
}
}
} else {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setState(footerState);
}
}
@ -148,23 +143,25 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
return null;
}
int update(List<Notification> new_notifications) {
int scrollToPosition;
if (notifications == null || notifications.isEmpty()) {
notifications = new_notifications;
scrollToPosition = 0;
void update(List<Notification> newNotifications) {
if (newNotifications == null || newNotifications.isEmpty()) {
return;
}
if (notifications.isEmpty()) {
notifications = newNotifications;
} else {
int index = new_notifications.indexOf(notifications.get(0));
if (index == -1) {
notifications.addAll(0, new_notifications);
scrollToPosition = 0;
int index = notifications.indexOf(newNotifications.get(newNotifications.size() - 1));
for (int i = 0; i < index; i++) {
notifications.remove(0);
}
int newIndex = newNotifications.indexOf(notifications.get(0));
if (newIndex == -1) {
notifications.addAll(0, newNotifications);
} else {
notifications.addAll(0, new_notifications.subList(0, index));
scrollToPosition = index;
notifications.addAll(0, newNotifications.subList(0, newIndex));
}
}
notifyDataSetChanged();
return scrollToPosition;
}
void addItems(List<Notification> new_notifications) {
@ -178,10 +175,6 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
notifyItemChanged(position);
}
void setFooterState(FooterViewHolder.State state) {
footerState = state;
}
interface FollowListener {
void onViewAccount(String id);
}

View file

@ -36,6 +36,7 @@ import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class NotificationsFragment extends SFragment implements
SwipeRefreshLayout.OnRefreshListener, StatusActionListener,
@ -43,7 +44,6 @@ public class NotificationsFragment extends SFragment implements
private static final String TAG = "Notifications"; // logging tag
private SwipeRefreshLayout swipeRefreshLayout;
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private EndlessOnScrollListener scrollListener;
private NotificationsAdapter adapter;
@ -73,7 +73,7 @@ public class NotificationsFragment extends SFragment implements
swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
// Setup the RecyclerView.
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
@ -148,7 +148,7 @@ public class NotificationsFragment extends SFragment implements
listCall.enqueue(new Callback<List<Notification>>() {
@Override
public void onResponse(Call<List<Notification>> call, retrofit2.Response<List<Notification>> response) {
public void onResponse(Call<List<Notification>> call, Response<List<Notification>> response) {
if (response.isSuccessful()) {
onFetchNotificationsSuccess(response.body(), fromId);
} else {
@ -180,7 +180,6 @@ public class NotificationsFragment extends SFragment implements
private void onFetchNotificationsSuccess(List<Notification> notifications, String fromId) {
if (fromId != null) {
if (notifications.size() > 0 && !findNotification(notifications, fromId)) {
setFetchTimelineState(FooterViewHolder.State.LOADING);
adapter.addItems(notifications);
// Set last update id for pull notifications so that we don't get notified
@ -189,8 +188,6 @@ public class NotificationsFragment extends SFragment implements
SharedPreferences.Editor editor = preferences.edit();
editor.putString("lastUpdateId", notifications.get(0).id);
editor.apply();
} else {
setFetchTimelineState(FooterViewHolder.State.END_OF_TIMELINE);
}
} else {
adapter.update(notifications);
@ -199,21 +196,10 @@ public class NotificationsFragment extends SFragment implements
}
private void onFetchNotificationsFailure(Exception exception) {
setFetchTimelineState(FooterViewHolder.State.RETRY);
swipeRefreshLayout.setRefreshing(false);
Log.e(TAG, "Fetch failure: " + exception.getMessage());
}
private void setFetchTimelineState(FooterViewHolder.State state) {
adapter.setFooterState(state);
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
if (viewHolder != null) {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setState(state);
}
}
public void onRefresh() {
Notification notification = adapter.getItem(0);
if (notification != null) {

View file

@ -32,13 +32,11 @@ class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover
private List<Status> statuses;
private StatusActionListener statusListener;
private FooterViewHolder.State footerState;
TimelineAdapter(StatusActionListener statusListener) {
super();
statuses = new ArrayList<>();
this.statusListener = statusListener;
footerState = FooterViewHolder.State.LOADING;
}
@Override
@ -64,9 +62,6 @@ class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover
StatusViewHolder holder = (StatusViewHolder) viewHolder;
Status status = statuses.get(position);
holder.setupWithStatus(status, statusListener);
} else {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setState(footerState);
}
}
@ -84,25 +79,25 @@ class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover
}
}
int update(List<Status> newStatuses) {
int scrollToPosition;
void update(List<Status> newStatuses) {
if (newStatuses == null || newStatuses.isEmpty()) {
return;
}
if (statuses.isEmpty()) {
if (newStatuses != null) {
statuses = newStatuses;
}
scrollToPosition = 0;
statuses = newStatuses;
} else {
int index = newStatuses.indexOf(statuses.get(0));
if (index == -1) {
int index = statuses.indexOf(newStatuses.get(newStatuses.size() - 1));
for (int i = 0; i < index; i++) {
statuses.remove(0);
}
int newIndex = newStatuses.indexOf(statuses.get(0));
if (newIndex == -1) {
statuses.addAll(0, newStatuses);
scrollToPosition = 0;
} else {
statuses.addAll(0, newStatuses.subList(0, index));
scrollToPosition = index;
statuses.addAll(0, newStatuses.subList(0, newIndex));
}
}
notifyDataSetChanged();
return scrollToPosition;
}
void addItems(List<Status> newStatuses) {
@ -123,8 +118,4 @@ class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover
}
return null;
}
void setFooterState(FooterViewHolder.State state) {
footerState = state;
}
}

View file

@ -50,7 +50,6 @@ public class TimelineFragment extends SFragment implements
}
private SwipeRefreshLayout swipeRefreshLayout;
private RecyclerView recyclerView;
private TimelineAdapter adapter;
private Kind kind;
private String hashtagOrId;
@ -92,7 +91,7 @@ public class TimelineFragment extends SFragment implements
swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
// Setup the RecyclerView.
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
@ -135,17 +134,9 @@ public class TimelineFragment extends SFragment implements
layout.addOnTabSelectedListener(onTabSelectedListener);
}
sendFetchTimelineRequest();
return rootView;
}
@Override
public void onResume() {
super.onResume();
sendFetchTimelineRequest();
}
@Override
public void onDestroy() {
super.onDestroy();
@ -232,10 +223,7 @@ public class TimelineFragment extends SFragment implements
public void onFetchTimelineSuccess(List<Status> statuses, String fromId) {
if (fromId != null) {
if (statuses.size() > 0 && !findStatus(statuses, fromId)) {
setFetchTimelineState(FooterViewHolder.State.LOADING);
adapter.addItems(statuses);
} else {
setFetchTimelineState(FooterViewHolder.State.END_OF_TIMELINE);
}
} else {
adapter.update(statuses);
@ -244,21 +232,10 @@ public class TimelineFragment extends SFragment implements
}
public void onFetchTimelineFailure(Exception exception) {
setFetchTimelineState(FooterViewHolder.State.RETRY);
swipeRefreshLayout.setRefreshing(false);
Log.e(TAG, "Fetch Failure: " + exception.getMessage());
}
private void setFetchTimelineState(FooterViewHolder.State state) {
adapter.setFooterState(state);
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
if (viewHolder != null) {
FooterViewHolder holder = (FooterViewHolder) viewHolder;
holder.setState(state);
}
}
public void onRefresh() {
Status status = adapter.getItem(0);
if (status != null) {

View file

@ -17,7 +17,6 @@ package com.keylesspalace.tusky;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.widget.MediaController;
@ -50,8 +49,9 @@ public class ViewVideoActivity extends BaseActivity {
videoView.setVideoPath(url);
MediaController controller = new MediaController(this);
controller.setMediaPlayer(videoView);
videoView.setMediaController(controller);
controller.show();
videoView.requestFocus();
videoView.start();
}

View file

@ -6,6 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/view_video_background"
android:id="@+id/view_video_container"
tools:context=".ViewVideoActivity">
<VideoView
android:id="@+id/video_player"