QueueEvents, Queue shows undobar on removal of an item

This commit is contained in:
Martin Fietz 2015-04-05 20:49:11 +02:00
parent b2a50983ef
commit 8850c09920
16 changed files with 200 additions and 98 deletions

View File

@ -17,6 +17,7 @@ dependencies {
compile 'com.squareup.okhttp:okhttp:2.2.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'
compile 'com.squareup.okio:okio:1.2.0'
compile 'de.greenrobot:eventbus:2.4.0'
compile project(':core')
compile project(':library:drag-sort-listview')
}

View File

@ -97,7 +97,7 @@ public class PlaybackServiceTaskManagerTest extends InstrumentationTestCase {
};
EventDistributor.getInstance().register(queueListener);
List<FeedItem> queue = writeTestQueue("a");
EventDistributor.getInstance().sendQueueUpdateBroadcast();
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED_ITEMS, queue));
countDownLatch.await(5000, TimeUnit.MILLISECONDS);
assertNotNull(queue);

View File

@ -204,6 +204,6 @@ public class UITestUtils {
adapter.setQueue(queue);
adapter.close();
EventDistributor.getInstance().sendFeedUpdateBroadcast();
EventDistributor.getInstance().sendQueueUpdateBroadcast();
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED_ITEMS, queue));
}
}

View File

@ -52,8 +52,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED
| EventDistributor.DOWNLOAD_QUEUED
| EventDistributor.FEED_LIST_UPDATE
| EventDistributor.UNREAD_ITEMS_UPDATE
| EventDistributor.QUEUE_UPDATE;
| EventDistributor.UNREAD_ITEMS_UPDATE;
public static final String PREF_NAME = "MainActivityPrefs";
public static final String PREF_IS_FIRST_LAUNCH = "prefMainActivityIsFirstLaunch";
@ -324,6 +323,13 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
@Override
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
EventBus.getDefault().register(this);
}
@Override
protected void onPause() {
super.onPause();
@ -333,7 +339,6 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
protected void onResume() {
super.onResume();
StorageUtils.checkStorageAvailability(this);
EventDistributor.getInstance().register(contentUpdate);
Intent intent = getIntent();
if (navDrawerData != null && intent.hasExtra(EXTRA_NAV_INDEX) && intent.hasExtra(EXTRA_NAV_TYPE)) {
@ -348,6 +353,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
super.onStop();
cancelLoadTask();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
}
@Override
@ -436,6 +442,11 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
}
public void onEvent(QueueEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
loadData();
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override

View File

@ -67,7 +67,6 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOAD_QUEUED |
EventDistributor.QUEUE_UPDATE |
EventDistributor.UNREAD_ITEMS_UPDATE;
private static final String ARG_FEEDITEM = "feeditem";
@ -129,6 +128,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
EventBus.getDefault().register(this);
if (downloadObserver != null) {
downloadObserver.setActivity(getActivity());
downloadObserver.onResume();
@ -143,6 +143,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
}
private void resetViewState() {
@ -392,6 +393,10 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
}
}
public void onEvent(QueueEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
getLoaderManager().restartLoader(0, null, ItemFragment.this);
}
@Override
public Loader<Pair<FeedItem,LongList>> onCreateLoader(int id, Bundle args) {

View File

@ -67,7 +67,6 @@ public class ItemlistFragment extends ListFragment {
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED
| EventDistributor.DOWNLOAD_QUEUED
| EventDistributor.QUEUE_UPDATE
| EventDistributor.UNREAD_ITEMS_UPDATE
| EventDistributor.PLAYER_STATUS_UPDATE;
@ -120,6 +119,7 @@ public class ItemlistFragment extends ListFragment {
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
EventBus.getDefault().register(this);
if (downloadObserver != null) {
downloadObserver.setActivity(getActivity());
downloadObserver.onResume();
@ -133,6 +133,7 @@ public class ItemlistFragment extends ListFragment {
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
stopItemLoader();
}
@ -285,6 +286,11 @@ public class ItemlistFragment extends ListFragment {
}
}
public void onEvent(QueueEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
startItemLoader();
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override

View File

@ -7,7 +7,6 @@ import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.SearchView;
import android.util.Log;
@ -45,13 +44,9 @@ import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken;
import de.danoeh.antennapod.core.util.gui.UndoBarController;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.greenrobot.event.EventBus;
@ -112,6 +107,7 @@ public class NewEpisodesFragment extends Fragment {
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
EventBus.getDefault().register(this);
this.activity.set((MainActivity) getActivity());
if (downloadObserver != null) {
downloadObserver.setActivity(getActivity());
@ -126,6 +122,7 @@ public class NewEpisodesFragment extends Fragment {
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
stopItemLoader();
}
@ -269,17 +266,26 @@ public class NewEpisodesFragment extends Fragment {
}
});
undoBarController = new UndoBarController(root.findViewById(R.id.undobar), new UndoBarController.UndoListener() {
undoBarController = new UndoBarController<FeedItemUndoToken>(root.findViewById(R.id.undobar), new UndoBarController.UndoListener<FeedItemUndoToken>() {
@Override
public void onUndo(Parcelable token) {
// Perform the undo
FeedItemUndoToken undoToken = (FeedItemUndoToken) token;
public void onUndo(FeedItemUndoToken token) {
if (token != null) {
long itemId = undoToken.getFeedItemId();
int position = undoToken.getPosition();
long itemId = token.getFeedItemId();
int position = token.getPosition();
DBWriter.markItemRead(getActivity(), itemId, false);
}
}
@Override
public void onHide(FeedItemUndoToken token) {
if (token != null) {
long itemId = token.getFeedItemId();
FeedItem item = DBReader.getFeedItem(getActivity(), itemId);
FeedMedia media = item.getMedia();
if(media != null && media.hasAlmostEnded() && UserPreferences.isAutoDelete()) {
DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId());
}
}
}
});
final int secondColor = (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) ? R.color.swipe_refresh_secondary_color_dark : R.color.swipe_refresh_secondary_color_light;
@ -371,6 +377,11 @@ public class NewEpisodesFragment extends Fragment {
};
public void onEvent(QueueEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
startItemLoader();
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {

View File

@ -70,12 +70,14 @@ public class PlaybackHistoryFragment extends ListFragment {
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
stopItemLoader();
}
@ -169,6 +171,11 @@ public class PlaybackHistoryFragment extends ListFragment {
}
}
public void onEvent(QueueEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
startItemLoader();
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override

View File

@ -58,7 +58,6 @@ public class QueueFragment extends Fragment {
private static final String TAG = "QueueFragment";
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOAD_QUEUED |
EventDistributor.QUEUE_UPDATE |
EventDistributor.PLAYER_STATUS_UPDATE;
private DragSortListView listView;
@ -66,7 +65,7 @@ public class QueueFragment extends Fragment {
private TextView txtvEmpty;
private ProgressBar progLoading;
private UndoBarController undoBarController;
private UndoBarController<FeedItemUndoToken> undoBarController;
private List<FeedItem> queue;
private List<Downloader> downloaderList;
@ -106,6 +105,7 @@ public class QueueFragment extends Fragment {
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
EventBus.getDefault().register(this);
this.activity.set((MainActivity) getActivity());
if (downloadObserver != null) {
downloadObserver.setActivity(getActivity());
@ -126,6 +126,7 @@ public class QueueFragment extends Fragment {
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
stopItemLoader();
}
@ -135,6 +136,15 @@ public class QueueFragment extends Fragment {
this.activity.set((MainActivity) activity);
}
public void onEventMainThread(QueueEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
if(event.action == QueueEvent.Action.REMOVED) {
undoBarController.showUndoBar(false, getString(R.string.removed_from_queue),
new FeedItemUndoToken(event.item, event.position));
}
startItemLoader();
}
private void saveScrollPosition() {
SharedPreferences prefs = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
@ -345,29 +355,40 @@ public class QueueFragment extends Fragment {
@Override
public void remove(int which) {
Log.d(TAG, "remove("+which+")");
Log.d(TAG, "remove(" + which + ")");
stopItemLoader();
FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
DBWriter.removeQueueItem(getActivity(), item.getId(), true);
undoBarController.showUndoBar(false,
getString(R.string.removed_from_queue), new FeedItemUndoToken(item,
which)
);
DBWriter.markItemRead(getActivity(), item.getId(), true);
DBWriter.removeQueueItem(getActivity(), item, true);
}
});
undoBarController = new UndoBarController(root.findViewById(R.id.undobar), new UndoBarController.UndoListener() {
@Override
public void onUndo(Parcelable token) {
// Perform the undo
FeedItemUndoToken undoToken = (FeedItemUndoToken) token;
if (token != null) {
long itemId = undoToken.getFeedItemId();
int position = undoToken.getPosition();
DBWriter.addQueueItemAt(getActivity(), itemId, position, false);
}
}
});
undoBarController = new UndoBarController<FeedItemUndoToken>(root.findViewById(R.id.undobar),
new UndoBarController.UndoListener<FeedItemUndoToken>() {
@Override
public void onUndo(FeedItemUndoToken token) {
if (token != null) {
long itemId = token.getFeedItemId();
int position = token.getPosition();
DBWriter.markItemRead(getActivity(), itemId, false);
DBWriter.addQueueItemAt(getActivity(), itemId, position, false);
}
}
@Override
public void onHide(FeedItemUndoToken token) {
if (token != null) {
long itemId = token.getFeedItemId();
FeedItem item = DBReader.getFeedItem(getActivity(), itemId);
FeedMedia media = item.getMedia();
if(media != null && media.hasAlmostEnded() && UserPreferences.isAutoDelete()) {
DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId());
}
}
}
});
registerForContextMenu(listView);

View File

@ -17,7 +17,6 @@ import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.ShareUtils;
/**
@ -57,7 +56,7 @@ public class FeedItemMenuHandler {
* @return Returns true if selectedItem is not null.
*/
public static boolean onPrepareMenu(MenuInterface mi,
FeedItem selectedItem, boolean showExtendedMenu, QueueAccess queueAccess) {
FeedItem selectedItem, boolean showExtendedMenu, LongList queueAccess) {
if (selectedItem == null) {
return false;
}

View File

@ -45,4 +45,5 @@ dependencies {
compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'
compile 'com.squareup.okio:okio:1.2.0'
compile 'com.nineoldandroids:library:2.4.0'
compile 'de.greenrobot:eventbus:2.4.0'
}

View File

@ -24,7 +24,6 @@ public class EventDistributor extends Observable {
public static final int FEED_LIST_UPDATE = 1;
public static final int UNREAD_ITEMS_UPDATE = 2;
public static final int QUEUE_UPDATE = 4;
public static final int DOWNLOADLOG_UPDATE = 8;
public static final int PLAYBACK_HISTORY_UPDATE = 16;
public static final int DOWNLOAD_QUEUED = 32;
@ -97,10 +96,6 @@ public class EventDistributor extends Observable {
addEvent(UNREAD_ITEMS_UPDATE);
}
public void sendQueueUpdateBroadcast() {
addEvent(QUEUE_UPDATE);
}
public void sendFeedUpdateBroadcast() {
addEvent(FEED_LIST_UPDATE);
}

View File

@ -0,0 +1,51 @@
package de.danoeh.antennapod.core.feed;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.List;
public class QueueEvent {
public enum Action {
ADDED, ADDED_ITEMS, REMOVED, CLEARED, DELETED_MEDIA, SORTED
}
public final Action action;
public final FeedItem item;
public final int position;
public final List<FeedItem> items;
public QueueEvent(Action action) {
this(action, null, null, -1);
}
public QueueEvent(Action action, FeedItem item) {
this(action, item, null, -1);
}
public QueueEvent(Action action, FeedItem item, int position) {
this(action, item, null, position);
}
public QueueEvent(Action action, List<FeedItem> items) {
this(action, null, items, -1);
}
private QueueEvent(Action action, FeedItem item, List<FeedItem> items, int position) {
this.action = action;
this.item = item;
this.items = items;
this.position = position;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("action", action)
.append("item", item)
.append("items", items)
.append("position", position)
.toString();
}
}

View File

@ -76,18 +76,13 @@ public class PlaybackServiceTaskManager {
}
});
loadQueue();
EventDistributor.getInstance().register(eventDistributorListener);
EventBus.getDefault().register(this);
}
private final EventDistributor.EventListener eventDistributorListener = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((EventDistributor.QUEUE_UPDATE & arg) != 0) {
cancelQueueLoader();
loadQueue();
}
}
};
public void onEvent(QueueEvent event) {
cancelQueueLoader();
loadQueue();
}
private synchronized boolean isQueueLoaderActive() {
return queueFuture != null && !queueFuture.isDone();
@ -319,7 +314,7 @@ public class PlaybackServiceTaskManager {
* execution of this method.
*/
public synchronized void shutdown() {
EventDistributor.getInstance().unregister(eventDistributorListener);
EventBus.getDefault().unregister(this);
cancelAllTasks();
schedExecutor.shutdown();
}

View File

@ -41,7 +41,6 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import de.danoeh.antennapod.core.util.flattr.FlattrThing;
import de.danoeh.antennapod.core.util.flattr.SimpleFlattrThing;
@ -350,8 +349,7 @@ public class DBWriter {
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
final List<FeedItem> queue = DBReader
.getQueue(context, adapter);
final List<FeedItem> queue = DBReader.getQueue(context, adapter);
FeedItem item = null;
if (queue != null) {
@ -490,21 +488,14 @@ public class DBWriter {
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
final List<FeedItem> queue = DBReader
.getQueue(context, adapter);
FeedItem item = null;
final List<FeedItem> queue = DBReader.getQueue(context, adapter);
if (queue != null) {
boolean queueModified = false;
QueueAccess queueAccess = QueueAccess.ItemListAccess(queue);
if (queueAccess.contains(item.getId())) {
if (item != null) {
queueModified = queueAccess.remove(item.getId());
}
}
if (queueModified) {
int position = queue.indexOf(item);
if(position >= 0) {
queue.remove(position);
adapter.setQueue(queue);
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.REMOVED, item));
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.REMOVED, item, position));
} else {
Log.w(TAG, "Queue was not modified by call to removeQueueItem");
}
@ -628,6 +619,19 @@ public class DBWriter {
adapter.close();
}
/**
* Sets the 'read'-attribute of a FeedItem to the specified value.
*
* @param context A context that is used for opening a database connection.
* @param itemId ID of the FeedItem
* @param read New value of the 'read'-attribute
*/
public static Future<?> markItemRead(final Context context, final long itemId,
final boolean read) {
return markItemRead(context, itemId, read, 0, false);
}
/**
* Sets the 'read'-attribute of a FeedItem to the specified value.
*

View File

@ -1,9 +1,6 @@
package de.danoeh.antennapod.core.util.gui;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
@ -16,23 +13,36 @@ import de.danoeh.antennapod.core.R;
import static com.nineoldandroids.view.ViewPropertyAnimator.animate;
public class UndoBarController {
public class UndoBarController<T> {
private View mBarView;
private TextView mMessageView;
private ViewPropertyAnimator mBarAnimator;
private Handler mHideHandler = new Handler();
private UndoListener mUndoListener;
private UndoListener<T> mUndoListener;
// State objects
private Parcelable mUndoToken;
private T mUndoToken;
private CharSequence mUndoMessage;
public interface UndoListener {
void onUndo(Parcelable token);
public interface UndoListener<T> {
/**
* This callback function is called when the undo button is pressed
*
* @param token
*/
void onUndo(T token);
/**
*
* This callback function is called when the bar fades out without button press
*
* @param token
*/
void onHide(T token);
}
public UndoBarController(View undoBarView, UndoListener undoListener) {
public UndoBarController(View undoBarView, UndoListener<T> undoListener) {
mBarView = undoBarView;
mBarAnimator = animate(mBarView);
mUndoListener = undoListener;
@ -50,7 +60,7 @@ public class UndoBarController {
hideUndoBar(true);
}
public void showUndoBar(boolean immediate, CharSequence message, Parcelable undoToken) {
public void showUndoBar(boolean immediate, CharSequence message, T undoToken) {
mUndoToken = undoToken;
mUndoMessage = message;
mMessageView.setText(mUndoMessage);
@ -96,26 +106,11 @@ public class UndoBarController {
}
}
public void onSaveInstanceState(Bundle outState) {
outState.putCharSequence("undo_message", mUndoMessage);
outState.putParcelable("undo_token", mUndoToken);
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState != null) {
mUndoMessage = savedInstanceState.getCharSequence("undo_message");
mUndoToken = savedInstanceState.getParcelable("undo_token");
if (mUndoToken != null || !TextUtils.isEmpty(mUndoMessage)) {
showUndoBar(true, mUndoMessage, mUndoToken);
}
}
}
private Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
hideUndoBar(false);
mUndoListener.onHide(mUndoToken);
}
};
}