diff options
Diffstat (limited to 'core')
9 files changed, 244 insertions, 8 deletions
diff --git a/core/build.gradle b/core/build.gradle index dfe0fb133..710378a18 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -44,4 +44,5 @@ 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' -}
\ No newline at end of file + compile 'com.nineoldandroids:library:2.4.0' +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java index a3b9f6049..7cbb69a7f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java @@ -60,6 +60,7 @@ public class UserPreferences implements private static final String PREF_SEEK_DELTA_SECS = "prefSeekDeltaSecs"; private static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify"; private static final String PREF_PERSISTENT_NOTIFICATION = "prefPersistNotify"; + public static final String PREF_QUEUE_ADD_TO_FRONT = "prefQueueAddToFront"; // TODO: Make this value configurable private static final float PREF_AUTO_FLATTR_PLAYED_DURATION_THRESHOLD_DEFAULT = 0.8f; diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java index 87bbdf455..c5bf89533 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java @@ -7,7 +7,6 @@ import android.content.SharedPreferences; import android.database.Cursor; import android.preference.PreferenceManager; import android.util.Log; - import org.shredzone.flattr4j.model.Flattr; import java.io.File; @@ -35,6 +34,7 @@ import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; +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.QueueAccess; @@ -239,6 +239,26 @@ public class DBWriter { } /** + * Deletes the entire download log. + * + * @param context A context that is used for opening a database connection. + */ + public static Future<?> clearDownloadLog(final Context context) { + return dbExec.submit(new Runnable() { + @Override + public void run() { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.clearDownloadLog(); + adapter.close(); + EventDistributor.getInstance() + .sendDownloadLogUpdateBroadcast(); + } + }); + } + + + /** * Adds a FeedMedia object to the playback history. A FeedMedia object is in the playback history if * its playback completion date is set to a non-null value. This method will set the playback completion date to the * current date regardless of the current value. @@ -386,7 +406,16 @@ public class DBWriter { context, itemIds[i]); if (item != null) { - queue.add(item); + // add item to either front ot back of queue + boolean addToFront = PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(UserPreferences.PREF_QUEUE_ADD_TO_FRONT, false); + + if(addToFront){ + queue.add(0, item); + }else{ + queue.add(item); + } + queueModified = true; if (!item.isRead()) { item.setRead(true); diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index ce41147e1..f72858adc 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -889,6 +889,10 @@ public class PodDBAdapter { db.update(TABLE_NAME_FEED_MEDIA, values, null, null); } + public void clearDownloadLog() { + db.delete(TABLE_NAME_DOWNLOAD_LOG, null, null); + } + /** * Get all Feeds from the Feed Table. * diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java index 1dda24944..47503dee4 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java @@ -1,14 +1,23 @@ package de.danoeh.antennapod.core.syndication.handler; import android.util.Log; -import de.danoeh.antennapod.core.BuildConfig; -import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.syndication.namespace.*; -import de.danoeh.antennapod.core.syndication.namespace.atom.NSAtom; + import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; +import de.danoeh.antennapod.core.BuildConfig; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.syndication.namespace.NSContent; +import de.danoeh.antennapod.core.syndication.namespace.NSDublinCore; +import de.danoeh.antennapod.core.syndication.namespace.NSITunes; +import de.danoeh.antennapod.core.syndication.namespace.NSMedia; +import de.danoeh.antennapod.core.syndication.namespace.NSRSS20; +import de.danoeh.antennapod.core.syndication.namespace.NSSimpleChapters; +import de.danoeh.antennapod.core.syndication.namespace.Namespace; +import de.danoeh.antennapod.core.syndication.namespace.SyndElement; +import de.danoeh.antennapod.core.syndication.namespace.atom.NSAtom; + /** Superclass for all SAX Handlers which process Syndication formats */ public class SyndHandler extends DefaultHandler { private static final String TAG = "SyndHandler"; @@ -100,7 +109,12 @@ public class SyndHandler extends DefaultHandler { state.namespaces.put(uri, new NSMedia()); if (BuildConfig.DEBUG) Log.d(TAG, "Recognized media namespace"); - } + } else if (uri.equals(NSDublinCore.NSURI) + && prefix.equals(NSDublinCore.NSTAG)) { + state.namespaces.put(uri, new NSDublinCore()); + if (BuildConfig.DEBUG) + Log.d(TAG, "Recognized DublinCore namespace"); + } } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSDublinCore.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSDublinCore.java new file mode 100644 index 000000000..099593eed --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSDublinCore.java @@ -0,0 +1,37 @@ +package de.danoeh.antennapod.core.syndication.namespace; + +import org.xml.sax.Attributes; + +import de.danoeh.antennapod.core.syndication.handler.HandlerState; +import de.danoeh.antennapod.core.syndication.util.SyndDateUtils; + +public class NSDublinCore extends Namespace { + private static final String TAG = "NSDublinCore"; + public static final String NSTAG = "dc"; + public static final String NSURI = "http://purl.org/dc/elements/1.1/"; + + private static final String ITEM = "item"; + private static final String DATE = "date"; + + @Override + public SyndElement handleElementStart(String localName, HandlerState state, + Attributes attributes) { + return new SyndElement(localName, this); + } + + @Override + public void handleElementEnd(String localName, HandlerState state) { + if(state.getTagstack().size() >= 2 + && state.getContentBuf() != null) { + String content = state.getContentBuf().toString(); + SyndElement topElement = state.getTagstack().peek(); + String top = topElement.getName(); + SyndElement secondElement = state.getSecondTag(); + String second = secondElement.getName(); + if (top.equals(DATE) && second.equals(ITEM)) { + state.getCurrentItem().setPubDate( + SyndDateUtils.parseISO8601Date(content)); + } + } + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndDateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndDateUtils.java index 1ac389f08..a9929d7b1 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndDateUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndDateUtils.java @@ -28,6 +28,8 @@ public class SyndDateUtils { */ public static final String RFC3339LOCAL = "yyyy-MM-dd'T'HH:mm:ssZ"; + public static final String ISO8601_SHORT = "yyyy-MM-dd"; + private static ThreadLocal<SimpleDateFormat> RFC822Formatter = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { @@ -44,6 +46,14 @@ public class SyndDateUtils { }; + private static ThreadLocal<SimpleDateFormat> ISO8601ShortFormatter = new ThreadLocal<SimpleDateFormat>() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat(ISO8601_SHORT, Locale.US); + } + + }; + public static Date parseRFC822Date(String date) { Date result = null; if (date.contains("PDT")) { @@ -123,6 +133,23 @@ public class SyndDateUtils { } + public static Date parseISO8601Date(String date) { + if(date.length() > ISO8601_SHORT.length()) { + return parseRFC3339Date(date); + } + Date result = null; + if(date.length() == "YYYYMMDD".length()) { + date = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6,8); + } + SimpleDateFormat format = ISO8601ShortFormatter.get(); + try { + result = format.parse(date); + } catch (ParseException e) { + e.printStackTrace(); + } + return result; + } + /** * Takes a string of the form [HH:]MM:SS[.mmm] and converts it to * milliseconds. diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/gui/UndoBarController.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/UndoBarController.java new file mode 100644 index 000000000..0e03bc8b4 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/gui/UndoBarController.java @@ -0,0 +1,121 @@ +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; + +import com.nineoldandroids.animation.Animator; +import com.nineoldandroids.animation.AnimatorListenerAdapter; +import com.nineoldandroids.view.ViewHelper; +import com.nineoldandroids.view.ViewPropertyAnimator; + +import de.danoeh.antennapod.core.R; + +import static com.nineoldandroids.view.ViewPropertyAnimator.animate; + +public class UndoBarController { + private View mBarView; + private TextView mMessageView; + private ViewPropertyAnimator mBarAnimator; + private Handler mHideHandler = new Handler(); + + private UndoListener mUndoListener; + + // State objects + private Parcelable mUndoToken; + private CharSequence mUndoMessage; + + public interface UndoListener { + void onUndo(Parcelable token); + } + + public UndoBarController(View undoBarView, UndoListener undoListener) { + mBarView = undoBarView; + mBarAnimator = animate(mBarView); + mUndoListener = undoListener; + + mMessageView = (TextView) mBarView.findViewById(R.id.undobar_message); + mBarView.findViewById(R.id.undobar_button) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + hideUndoBar(false); + mUndoListener.onUndo(mUndoToken); + } + }); + + hideUndoBar(true); + } + + public void showUndoBar(boolean immediate, CharSequence message, Parcelable undoToken) { + mUndoToken = undoToken; + mUndoMessage = message; + mMessageView.setText(mUndoMessage); + + mHideHandler.removeCallbacks(mHideRunnable); + mHideHandler.postDelayed(mHideRunnable, + mBarView.getResources().getInteger(R.integer.undobar_hide_delay)); + + mBarView.setVisibility(View.VISIBLE); + if (immediate) { + ViewHelper.setAlpha(mBarView, 1); + } else { + mBarAnimator.cancel(); + mBarAnimator + .alpha(1) + .setDuration( + mBarView.getResources() + .getInteger(android.R.integer.config_shortAnimTime)) + .setListener(null); + } + } + + public void hideUndoBar(boolean immediate) { + mHideHandler.removeCallbacks(mHideRunnable); + if (immediate) { + mBarView.setVisibility(View.GONE); + ViewHelper.setAlpha(mBarView, 0); + mUndoMessage = null; + } else { + mBarAnimator.cancel(); + mBarAnimator + .alpha(0) + .setDuration(mBarView.getResources() + .getInteger(android.R.integer.config_shortAnimTime)) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mBarView.setVisibility(View.GONE); + mUndoMessage = null; + mUndoToken = null; + } + }); + } + } + + 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); + } + }; +} diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 9b7cb3585..e8c3408b2 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -272,6 +272,8 @@ <string name="pref_persistNotify_title">Persistent playback controls</string> <string name="pref_persistNotify_sum">Keep notification and lockscreen controls when playback is paused.</string> <string name="pref_expand_notify_unsupport_toast">Android versions before 4.1 do not support expanded notifications.</string> + <string name="pref_queueAddToFront_sum">Add new episodes to the front of the queue.</string> + <string name="pref_queueAddToFront_title">Enqueue at front.</string> <!-- Auto-Flattr dialog --> <string name="auto_flattr_enable">Enable automatic flattring</string> |