summaryrefslogtreecommitdiff
path: root/core/src/main/java/de
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2020-02-05 16:51:59 +0100
committerByteHamster <info@bytehamster.com>2020-02-05 16:51:59 +0100
commitd74b8d06b21448a1ac2441bbdd95ff8179b754e8 (patch)
treef5c9f571935c05a417ed312b3db256b51926af5a /core/src/main/java/de
parentc3e1f8afbbb798c2bc1fde2d835d19cce5ebfc31 (diff)
parentf790b78b1a6c2aaf0fb789be9542d09ed2da47d2 (diff)
downloadAntennaPod-d74b8d06b21448a1ac2441bbdd95ff8179b754e8.zip
Merge branch 'develop' into extract-queue-item-view
Diffstat (limited to 'core/src/main/java/de')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/SearchResult.java22
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java34
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java30
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java17
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java32
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java59
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java49
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/SearchLocation.java21
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/comparator/InReverseChronologicalOrder.java21
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java115
11 files changed, 140 insertions, 261 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/SearchResult.java b/core/src/main/java/de/danoeh/antennapod/core/feed/SearchResult.java
deleted file mode 100644
index 062a6abac..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/SearchResult.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package de.danoeh.antennapod.core.feed;
-
-import de.danoeh.antennapod.core.storage.SearchLocation;
-
-public class SearchResult {
- private final FeedComponent component;
- private SearchLocation location;
-
- public SearchResult(FeedComponent component, SearchLocation location) {
- super();
- this.component = component;
- this.location = location;
- }
-
- public FeedComponent getComponent() {
- return component;
- }
-
- public SearchLocation getLocation() {
- return location;
- }
-}
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 9db5eb212..383697fa2 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
@@ -389,7 +389,7 @@ public class UserPreferences {
return Float.parseFloat(prefs.getString(PREF_PLAYBACK_SPEED, "1.00"));
} catch (NumberFormatException e) {
Log.e(TAG, Log.getStackTraceString(e));
- UserPreferences.setPlaybackSpeed("1.00");
+ UserPreferences.setPlaybackSpeed(1.0f);
return 1.0f;
}
}
@@ -399,7 +399,7 @@ public class UserPreferences {
return Float.parseFloat(prefs.getString(PREF_VIDEO_PLAYBACK_SPEED, "1.00"));
} catch (NumberFormatException e) {
Log.e(TAG, Log.getStackTraceString(e));
- UserPreferences.setVideoPlaybackSpeed("1.00");
+ UserPreferences.setVideoPlaybackSpeed(1.0f);
return 1.0f;
}
}
@@ -408,7 +408,7 @@ public class UserPreferences {
return prefs.getBoolean(PREF_PLAYBACK_SKIP_SILENCE, false);
}
- public static String[] getPlaybackSpeedArray() {
+ public static float[] getPlaybackSpeedArray() {
return readPlaybackSpeedArray(prefs.getString(PREF_PLAYBACK_SPEED_ARRAY, null));
}
@@ -638,15 +638,15 @@ public class UserPreferences {
.apply();
}
- public static void setPlaybackSpeed(String speed) {
+ public static void setPlaybackSpeed(float speed) {
prefs.edit()
- .putString(PREF_PLAYBACK_SPEED, speed)
+ .putString(PREF_PLAYBACK_SPEED, String.valueOf(speed))
.apply();
}
- public static void setVideoPlaybackSpeed(String speed) {
+ public static void setVideoPlaybackSpeed(float speed) {
prefs.edit()
- .putString(PREF_VIDEO_PLAYBACK_SPEED, speed)
+ .putString(PREF_VIDEO_PLAYBACK_SPEED, String.valueOf(speed))
.apply();
}
@@ -769,24 +769,22 @@ public class UserPreferences {
}
}
- private static String[] readPlaybackSpeedArray(String valueFromPrefs) {
- String[] selectedSpeeds = null;
- // If this preference hasn't been set yet, return the default options
- if (valueFromPrefs == null) {
- selectedSpeeds = new String[] { "0.75", "1.00", "1.25", "1.50", "1.75", "2.00" };
- } else {
+ private static float[] readPlaybackSpeedArray(String valueFromPrefs) {
+ if (valueFromPrefs != null) {
try {
JSONArray jsonArray = new JSONArray(valueFromPrefs);
- selectedSpeeds = new String[jsonArray.length()];
+ float[] selectedSpeeds = new float[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
- selectedSpeeds[i] = jsonArray.getString(i);
+ selectedSpeeds[i] = (float) jsonArray.getDouble(i);
}
+ return selectedSpeeds;
} catch (JSONException e) {
Log.e(TAG, "Got JSON error when trying to get speeds from JSONArray");
e.printStackTrace();
}
}
- return selectedSpeeds;
+ // If this preference hasn't been set yet, return the default options
+ return new float[] { 0.75f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f };
}
public static String getMediaPlayer() {
@@ -816,11 +814,11 @@ public class UserPreferences {
}
public static VideoBackgroundBehavior getVideoBackgroundBehavior() {
- switch (prefs.getString(PREF_VIDEO_BEHAVIOR, "stop")) {
+ switch (prefs.getString(PREF_VIDEO_BEHAVIOR, "pip")) {
case "stop": return VideoBackgroundBehavior.STOP;
case "pip": return VideoBackgroundBehavior.PICTURE_IN_PICTURE;
case "continue": return VideoBackgroundBehavior.CONTINUE_PLAYING;
- default: return VideoBackgroundBehavior.STOP;
+ default: return VideoBackgroundBehavior.PICTURE_IN_PICTURE;
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
index 9c32e42e0..6f7401698 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
@@ -646,6 +646,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
float retVal = 1;
if ((playerStatus == PlayerStatus.PLAYING
|| playerStatus == PlayerStatus.PAUSED
+ || playerStatus == PlayerStatus.INITIALIZED
|| playerStatus == PlayerStatus.PREPARED) && mediaPlayer.canSetSpeed()) {
retVal = mediaPlayer.getCurrentSpeedMultiplier();
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
index 37deb6dc0..fbd8d65d8 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
@@ -54,10 +54,10 @@ import de.danoeh.antennapod.core.event.settings.SpeedPresetChangedEvent;
import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
-import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
@@ -574,6 +574,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
} else if (mediaPlayer.getPlayable() == null) {
startPlayingFromPreferences();
}
+ taskManager.restartSleepTimer();
return true;
case KeyEvent.KEYCODE_MEDIA_PLAY:
if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) {
@@ -584,6 +585,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
} else if (mediaPlayer.getPlayable() == null) {
startPlayingFromPreferences();
}
+ taskManager.restartSleepTimer();
return true;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
if (status == PlayerStatus.PLAYING) {
@@ -833,9 +835,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
@Override
public void onPlaybackStart(@NonNull Playable playable, int position) {
- if (taskManager.isSleepTimerActive()) {
- taskManager.restartSleepTimer();
- }
taskManager.startWidgetUpdater();
if (position != PlaybackServiceMediaPlayer.INVALID_TIME) {
playable.setPosition(position);
@@ -1468,10 +1467,12 @@ public class PlaybackService extends MediaBrowserServiceCompat {
public void resume() {
mediaPlayer.resume();
+ taskManager.restartSleepTimer();
}
public void prepare() {
mediaPlayer.prepare();
+ taskManager.restartSleepTimer();
}
public void pause(boolean abandonAudioFocus, boolean reinit) {
@@ -1634,16 +1635,17 @@ public class PlaybackService extends MediaBrowserServiceCompat {
public void onPlayFromSearch(String query, Bundle extras) {
Log.d(TAG, "onPlayFromSearch query=" + query + " extras=" + extras.toString());
- List<SearchResult> results = FeedSearcher.performSearch(getBaseContext(), query, 0);
- for (SearchResult result : results) {
- try {
- FeedMedia p = ((FeedItem) (result.getComponent())).getMedia();
- mediaPlayer.playMediaObject(p, !p.localFileAvailable(), true, true);
- return;
- } catch (Exception e) {
- Log.d(TAG, e.getMessage());
- e.printStackTrace();
- continue;
+ List<FeedComponent> results = FeedSearcher.performSearch(getBaseContext(), query, 0);
+ for (FeedComponent result : results) {
+ if (result instanceof FeedItem) {
+ try {
+ FeedMedia media = ((FeedItem) result).getMedia();
+ mediaPlayer.playMediaObject(media, !media.localFileAvailable(), true, true);
+ return;
+ } catch (Exception e) {
+ Log.d(TAG, e.getMessage());
+ e.printStackTrace();
+ }
}
}
onPlay();
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
index 91f656bf1..8ebe18dc0 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
@@ -553,6 +553,23 @@ public final class DBTasks {
});
}
+ public static FutureTask<List<Feed>> searchFeeds(final Context context, final String query) {
+ return new FutureTask<>(new QueryTask<List<Feed>>(context) {
+ @Override
+ public void execute(PodDBAdapter adapter) {
+ Cursor cursor = adapter.searchFeeds(query);
+ List<Feed> items = new ArrayList<>();
+ if (cursor.moveToFirst()) {
+ do {
+ items.add(Feed.fromCursor(cursor));
+ } while (cursor.moveToNext());
+ }
+ setResult(items);
+ cursor.close();
+ }
+ });
+ }
+
/**
* A runnable which should be used for database queries. The onCompletion
* method is executed on the database executor to handle Cursors correctly.
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java
index af3d1206c..234c01b20 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java
@@ -1,6 +1,8 @@
package de.danoeh.antennapod.core.storage;
import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -14,21 +16,10 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
-import java.util.Arrays;
public class DatabaseExporter {
private static final String TAG = "DatabaseExporter";
- private static final byte[] SQLITE3_MAGIC = "SQLite format 3\0".getBytes();
-
- public static boolean validateDB(Uri inputUri, Context context) throws IOException {
- try (InputStream inputStream = context.getContentResolver().openInputStream(inputUri)) {
- byte[] magicBuf = new byte[SQLITE3_MAGIC.length];
- if (inputStream.read(magicBuf) == magicBuf.length) {
- return Arrays.equals(SQLITE3_MAGIC, magicBuf);
- }
- }
- return false;
- }
+ private static final String TEMP_DB_NAME = PodDBAdapter.DATABASE_NAME + "_tmp";
public static void exportToDocument(Uri uri, Context context) throws IOException {
ParcelFileDescriptor pfd = null;
@@ -78,14 +69,21 @@ public class DatabaseExporter {
public static void importBackup(Uri inputUri, Context context) throws IOException {
InputStream inputStream = null;
try {
- if (!validateDB(inputUri, context)) {
- throw new IOException(context.getString(R.string.import_bad_file));
+ File tempDB = context.getDatabasePath(TEMP_DB_NAME);
+ inputStream = context.getContentResolver().openInputStream(inputUri);
+ FileUtils.copyInputStreamToFile(inputStream, tempDB);
+
+ SQLiteDatabase db = SQLiteDatabase.openDatabase(tempDB.getAbsolutePath(),
+ null, SQLiteDatabase.OPEN_READONLY);
+ if (db.getVersion() > PodDBAdapter.VERSION) {
+ throw new IOException(context.getString(R.string.import_no_downgrade));
}
+ db.close();
File currentDB = context.getDatabasePath(PodDBAdapter.DATABASE_NAME);
- inputStream = context.getContentResolver().openInputStream(inputUri);
- FileUtils.copyInputStreamToFile(inputStream, currentDB);
- } catch (IOException e) {
+ currentDB.delete();
+ FileUtils.moveFile(tempDB, currentDB);
+ } catch (IOException | SQLiteException e) {
Log.e(TAG, Log.getStackTraceString(e));
throw e;
} finally {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java b/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java
index 1d9e33d0e..bbe8b26f1 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java
@@ -2,21 +2,15 @@ package de.danoeh.antennapod.core.storage;
import android.content.Context;
import androidx.annotation.NonNull;
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.feed.FeedComponent;
+import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.Chapter;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
-import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.SearchResult;
-import de.danoeh.antennapod.core.util.comparator.InReverseChronologicalOrder;
-
/**
* Performs search on Feeds and FeedItems.
*/
@@ -37,48 +31,19 @@ public class FeedSearcher {
* @return list of episodes containing the query
*/
@NonNull
- public static List<SearchResult> performSearch(final Context context, final String query, final long selectedFeed) {
- final List<SearchResult> result = new ArrayList<>();
+ public static List<FeedComponent> performSearch(final Context context, final String query, final long selectedFeed) {
+ final List<FeedComponent> result = new ArrayList<>();
try {
- FutureTask<List<FeedItem>> searchTask = DBTasks.searchFeedItems(context, selectedFeed, query);
- searchTask.run();
- final List<FeedItem> items = searchTask.get();
- for (FeedItem item : items) {
- SearchLocation location;
- if (safeContains(item.getTitle(), query)) {
- location = SearchLocation.TITLE;
- } else if (safeContains(item.getContentEncoded(), query)) {
- location = SearchLocation.SHOWNOTES;
- } else if (safeContains(item.getDescription(), query)) {
- location = SearchLocation.SHOWNOTES;
- } else if (safeContains(item.getChapters(), query)) {
- location = SearchLocation.CHAPTERS;
- } else if (safeContains(item.getFeed().getAuthor(), query)) {
- location = SearchLocation.AUTHORS;
- } else {
- location = SearchLocation.FEED;
- }
- result.add(new SearchResult(item, location));
- }
+ FutureTask<List<FeedItem>> itemSearchTask = DBTasks.searchFeedItems(context, selectedFeed, query);
+ FutureTask<List<Feed>> feedSearchTask = DBTasks.searchFeeds(context, query);
+ itemSearchTask.run();
+ feedSearchTask.run();
+
+ result.addAll(feedSearchTask.get());
+ result.addAll(itemSearchTask.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return result;
}
-
- private static boolean safeContains(String haystack, String needle) {
- return haystack != null && haystack.contains(needle);
- }
-
- private static boolean safeContains(List<Chapter> haystack, String needle) {
- if (haystack == null) {
- return false;
- }
- for (Chapter chapter : haystack) {
- if (safeContains(chapter.getTitle(), needle)) {
- return true;
- }
- }
- return false;
- }
}
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 17b79a3da..4e2588f22 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
@@ -48,6 +48,7 @@ public class PodDBAdapter {
private static final String TAG = "PodDBAdapter";
public static final String DATABASE_NAME = "Antennapod.db";
+ public static final int VERSION = 1090000;
/**
* Maximum number of arguments for IN-operator.
@@ -284,10 +285,13 @@ public class PodDBAdapter {
* Contains FEEDITEM_SEL_FI_SMALL as comma-separated list. Useful for raw queries.
*/
private static final String SEL_FI_SMALL_STR;
+ private static final String FEED_SEL_STD_STR;
static {
String selFiSmall = Arrays.toString(FEEDITEM_SEL_FI_SMALL);
SEL_FI_SMALL_STR = selFiSmall.substring(1, selFiSmall.length() - 1);
+ String selFeedSmall = Arrays.toString(FEED_SEL_STD);
+ FEED_SEL_STD_STR = selFeedSmall.substring(1, selFeedSmall.length() - 1);
}
/**
@@ -1274,21 +1278,29 @@ public class PodDBAdapter {
}
String query = "SELECT " + SEL_FI_SMALL_STR + " FROM " + TABLE_NAME_FEED_ITEMS
- + " LEFT JOIN " + TABLE_NAME_SIMPLECHAPTERS
- + " ON " + TABLE_NAME_SIMPLECHAPTERS + "." + KEY_FEEDITEM
- + "=" + TABLE_NAME_FEED_ITEMS + "." + KEY_ID
- + " LEFT JOIN " + TABLE_NAME_FEEDS
- + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED
- + "=" + TABLE_NAME_FEEDS + "." + KEY_ID
+ " WHERE " + queryFeedId + " AND ("
- + TABLE_NAME_FEED_ITEMS + "." + KEY_DESCRIPTION + " LIKE '%" + preparedQuery + "%' OR "
- + TABLE_NAME_FEED_ITEMS + "." + KEY_CONTENT_ENCODED + " LIKE '%" + preparedQuery + "%' OR "
- + TABLE_NAME_FEED_ITEMS + "." + KEY_TITLE + " LIKE '%" + preparedQuery + "%' OR "
- + TABLE_NAME_SIMPLECHAPTERS + "." + KEY_TITLE + " LIKE '%" + preparedQuery + "%' OR "
- + TABLE_NAME_FEEDS + "." + KEY_AUTHOR + " LIKE '%" + preparedQuery + "%' OR "
- + TABLE_NAME_FEEDS + "." + KEY_FEED_IDENTIFIER + " LIKE '%" + preparedQuery + "%'"
+ + KEY_DESCRIPTION + " LIKE '%" + preparedQuery + "%' OR "
+ + KEY_CONTENT_ENCODED + " LIKE '%" + preparedQuery + "%' OR "
+ + KEY_TITLE + " LIKE '%" + preparedQuery + "%'"
+ ") ORDER BY " + KEY_PUBDATE + " DESC "
- + "LIMIT 500";
+ + "LIMIT 300";
+ return db.rawQuery(query, null);
+ }
+
+ /**
+ * Searches for the given query in various values of all feeds.
+ *
+ * @return A cursor with all search results in SEL_FI_EXTRA selection.
+ */
+ public Cursor searchFeeds(String searchQuery) {
+ String preparedQuery = prepareSearchQuery(searchQuery);
+ String query = "SELECT " + FEED_SEL_STD_STR + " FROM " + TABLE_NAME_FEEDS + " WHERE "
+ + KEY_TITLE + " LIKE '%" + preparedQuery + "%' OR "
+ + KEY_CUSTOM_TITLE + " LIKE '%" + preparedQuery + "%' OR "
+ + KEY_AUTHOR + " LIKE '%" + preparedQuery + "%' OR "
+ + KEY_DESCRIPTION + " LIKE '%" + preparedQuery + "%' "
+ + "ORDER BY " + KEY_TITLE + " ASC "
+ + "LIMIT 300";
return db.rawQuery(query, null);
}
@@ -1336,8 +1348,6 @@ public class PodDBAdapter {
* Helper class for opening the Antennapod database.
*/
private static class PodDBHelper extends SQLiteOpenHelper {
- private static final int VERSION = 1090000;
-
/**
* Constructor.
*
@@ -1345,8 +1355,7 @@ public class PodDBAdapter {
* @param name Name of the database
* @param factory to use for creating cursor objects
*/
- public PodDBHelper(final Context context, final String name,
- final CursorFactory factory) {
+ public PodDBHelper(final Context context, final String name, final CursorFactory factory) {
super(context, name, factory, VERSION, new PodDbErrorHandler());
}
@@ -1369,10 +1378,8 @@ public class PodDBAdapter {
}
@Override
- public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
- final int newVersion) {
- Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to "
- + newVersion + ".");
+ public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
+ Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion + ".");
DBUpgrader.upgrade(db, oldVersion, newVersion);
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/SearchLocation.java b/core/src/main/java/de/danoeh/antennapod/core/storage/SearchLocation.java
deleted file mode 100644
index fabe85b2c..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/SearchLocation.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package de.danoeh.antennapod.core.storage;
-
-import androidx.annotation.StringRes;
-import de.danoeh.antennapod.core.R;
-
-public enum SearchLocation {
- TITLE(R.string.found_in_title_label),
- CHAPTERS(R.string.found_in_chapters_label),
- SHOWNOTES(R.string.found_in_shownotes_label),
- AUTHORS(R.string.found_in_authors_label),
- FEED(R.string.found_in_feeds_label);
-
- private int description;
- SearchLocation(@StringRes int description) {
- this.description = description;
- }
-
- public @StringRes int getDescription() {
- return description;
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/comparator/InReverseChronologicalOrder.java b/core/src/main/java/de/danoeh/antennapod/core/util/comparator/InReverseChronologicalOrder.java
deleted file mode 100644
index 80246af8f..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/comparator/InReverseChronologicalOrder.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package de.danoeh.antennapod.core.util.comparator;
-
-import java.util.Comparator;
-
-import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.SearchResult;
-
-public class InReverseChronologicalOrder implements Comparator<SearchResult> {
- /**
- * Compare items and sort it on chronological order.
- */
- @Override
- public int compare(SearchResult o1, SearchResult o2) {
- if ((o1.getComponent() instanceof FeedItem) && (o2.getComponent() instanceof FeedItem)) {
- FeedItem item1 = (FeedItem) o1.getComponent();
- FeedItem item2 = (FeedItem) o2.getComponent();
- return item2.getPubDate().compareTo(item1.getPubDate());
- }
- return 0;
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java
index 8624ec7e5..0fd658853 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java
@@ -9,11 +9,15 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import org.apache.commons.io.IOUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -27,48 +31,20 @@ import de.danoeh.antennapod.core.util.ShownotesProvider;
* shownotes to navigate to another position in the podcast or by highlighting certain parts of the shownotesProvider's
* shownotes.
* <p/>
- * A timeline object needs a shownotesProvider from which the chapter information is retrieved and shownotes are generated.
+ * A timeline object needs a shownotesProvider from which the chapter information
+ * is retrieved and shownotes are generated.
*/
public class Timeline {
private static final String TAG = "Timeline";
- private static final String WEBVIEW_STYLE =
- "@font-face {"
- + "font-family: 'Roboto-Light';"
- + "src: url('file:///android_asset/Roboto-Light.ttf');"
- + "}"
- + "* {"
- + "color: %s;"
- + "font-family: roboto-Light;"
- + "font-size: 13pt;"
- + "overflow-wrap: break-word;"
- + "}"
- + "a {"
- + "font-style: normal;"
- + "text-decoration: none;"
- + "font-weight: normal;"
- + "color: #00A8DF;"
- + "}"
- + "a.timecode {"
- + "color: #669900;"
- + "}"
- + "img, iframe {"
- + "display: block;"
- + "margin: 10 auto;"
- + "max-width: %s;"
- + "height: auto;"
- + "}"
- + "body {"
- + "margin: %dpx %dpx %dpx %dpx;"
- + "}";
-
-
- private ShownotesProvider shownotesProvider;
+ private static final Pattern TIMECODE_LINK_REGEX = Pattern.compile("antennapod://timecode/((\\d+))");
+ private static final String TIMECODE_LINK = "<a class=\"timecode\" href=\"antennapod://timecode/%d\">%s</a>";
+ private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b((\\d+):)?(\\d+):(\\d{2})\\b");
+ private static final Pattern LINE_BREAK_REGEX = Pattern.compile("<br */?>");
+ private final ShownotesProvider shownotesProvider;
private final String noShownotesLabel;
- private final String colorPrimaryString;
- private final String colorSecondaryString;
- private final int pageMargin;
+ private final String webviewStyle;
public Timeline(Context context, ShownotesProvider shownotesProvider) {
if (shownotesProvider == null) {
@@ -80,26 +56,21 @@ public class Timeline {
TypedArray res = context.getTheme().obtainStyledAttributes(new int[]{android.R.attr.textColorPrimary});
@ColorInt int col = res.getColor(0, 0);
- colorPrimaryString = "rgba(" + Color.red(col) + "," + Color.green(col) + "," +
- Color.blue(col) + "," + (Color.alpha(col) / 255.0) + ")";
- res.recycle();
- res = context.getTheme().obtainStyledAttributes(new int[]{android.R.attr.textColorSecondary});
- col = res.getColor(0, 0);
- colorSecondaryString = "rgba(" + Color.red(col) + "," + Color.green(col) + "," +
- Color.blue(col) + "," + (Color.alpha(col) / 255.0) + ")";
+ final String colorPrimary = "rgba(" + Color.red(col) + "," + Color.green(col) + ","
+ + Color.blue(col) + "," + (Color.alpha(col) / 255.0) + ")";
res.recycle();
-
- pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
- context.getResources().getDisplayMetrics()
- );
+ final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
+ context.getResources().getDisplayMetrics());
+ String styleString = "";
+ try {
+ InputStream templateStream = context.getAssets().open("shownotes-style.css");
+ styleString = IOUtils.toString(templateStream, "UTF-8");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ webviewStyle = String.format(Locale.getDefault(), styleString, colorPrimary, margin, margin, margin, margin);
}
- private static final Pattern TIMECODE_LINK_REGEX = Pattern.compile("antennapod://timecode/((\\d+))");
- private static final String TIMECODE_LINK = "<a class=\"timecode\" href=\"antennapod://timecode/%d\">%s</a>";
- private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b((\\d+):)?(\\d+):(\\d{2})\\b");
- private static final Pattern LINE_BREAK_REGEX = Pattern.compile("<br */?>");
-
-
/**
* Applies an app-specific CSS stylesheet and adds timecode links (optional).
* <p/>
@@ -110,10 +81,6 @@ public class Timeline {
*/
@NonNull
public String processShownotes() {
- final Playable playable = (shownotesProvider instanceof Playable) ? (Playable) shownotesProvider : null;
-
- // load shownotes
-
String shownotes;
try {
shownotes = shownotesProvider.loadShownotes().call();
@@ -124,21 +91,7 @@ public class Timeline {
if (TextUtils.isEmpty(shownotes)) {
Log.d(TAG, "shownotesProvider contained no shownotes. Returning 'no shownotes' message");
- shownotes = "<html>" +
- "<head>" +
- "<style type='text/css'>" +
- "html, body { margin: 0; padding: 0; width: 100%; height: 100%; } " +
- "html { display: table; }" +
- "body { display: table-cell; vertical-align: middle; text-align:center;" +
- "-webkit-text-size-adjust: none; font-size: 87%; color: " + colorSecondaryString + ";} " +
- "</style>" +
- "</head>" +
- "<body>" +
- "<p>" + noShownotesLabel + "</p>" +
- "</body>" +
- "</html>";
- Log.d(TAG, "shownotes: " + shownotes);
- return shownotes;
+ shownotes = "<html><head></head><body><p id='apNoShownotes'>" + noShownotesLabel + "</p></body></html>";
}
// replace ASCII line breaks with HTML ones if shownotes don't contain HTML line breaks already
@@ -147,14 +100,10 @@ public class Timeline {
}
Document document = Jsoup.parse(shownotes);
-
- // apply style
- String styleStr = String.format(Locale.getDefault(), WEBVIEW_STYLE, colorPrimaryString, "100%",
- pageMargin, pageMargin, pageMargin, pageMargin);
- document.head().appendElement("style").attr("type", "text/css").text(styleStr);
+ document.head().appendElement("style").attr("type", "text/css").text(webviewStyle);
// apply timecode links
- addTimecodes(document, playable);
+ addTimecodes(document);
return document.toString();
}
@@ -184,7 +133,7 @@ public class Timeline {
return -1;
}
- private void addTimecodes(Document document, final Playable playable) {
+ private void addTimecodes(Document document) {
Elements elementsWithTimeCodes = document.body().getElementsMatchingOwnText(TIMECODE_REGEX);
Log.d(TAG, "Recognized " + elementsWithTimeCodes.size() + " timecodes");
@@ -193,7 +142,13 @@ public class Timeline {
return;
}
- int playableDuration = playable == null ? Integer.MAX_VALUE : playable.getDuration();
+ int playableDuration = Integer.MAX_VALUE;
+ if (shownotesProvider instanceof Playable) {
+ playableDuration = ((Playable) shownotesProvider).getDuration();
+ } else if (shownotesProvider instanceof FeedItem && ((FeedItem) shownotesProvider).getMedia() != null) {
+ playableDuration = ((FeedItem) shownotesProvider).getMedia().getDuration();
+ }
+
boolean useHourFormat = true;
if (playableDuration != Integer.MAX_VALUE) {