keep track of watched content for subsequent shuffle sessions

This commit is contained in:
Akinwale Ariwodola 2020-09-23 15:31:34 +01:00
parent 6c171560fd
commit eeca602f7a
2 changed files with 107 additions and 6 deletions

View file

@ -21,7 +21,7 @@ import io.lbry.browser.utils.Helper;
import io.lbry.browser.utils.LbryUri; import io.lbry.browser.utils.LbryUri;
public class DatabaseHelper extends SQLiteOpenHelper { public class DatabaseHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 6; public static final int DATABASE_VERSION = 7;
public static final String DATABASE_NAME = "LbryApp.db"; public static final String DATABASE_NAME = "LbryApp.db";
private static DatabaseHelper instance; private static DatabaseHelper instance;
@ -60,6 +60,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
", is_read INTEGER DEFAULT 0 NOT NULL" + ", is_read INTEGER DEFAULT 0 NOT NULL" +
", is_seen INTEGER DEFAULT 0 NOT NULL " + ", is_seen INTEGER DEFAULT 0 NOT NULL " +
", timestamp TEXT NOT NULL)", ", timestamp TEXT NOT NULL)",
"CREATE TABLE shuffle_watched (id INTEGER PRIMARY KEY NOT NULL, claim_id TEXT NOT NULL)"
}; };
private static final String[] SQL_CREATE_INDEXES = { private static final String[] SQL_CREATE_INDEXES = {
"CREATE UNIQUE INDEX idx_subscription_url ON subscriptions (url)", "CREATE UNIQUE INDEX idx_subscription_url ON subscriptions (url)",
@ -69,7 +70,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
"CREATE UNIQUE INDEX idx_view_history_url_device ON view_history (url, device)", "CREATE UNIQUE INDEX idx_view_history_url_device ON view_history (url, device)",
"CREATE INDEX idx_view_history_device ON view_history (device)", "CREATE INDEX idx_view_history_device ON view_history (device)",
"CREATE UNIQUE INDEX idx_notification_remote_id ON notifications (remote_id)", "CREATE UNIQUE INDEX idx_notification_remote_id ON notifications (remote_id)",
"CREATE INDEX idx_notification_timestamp ON notifications (timestamp)" "CREATE INDEX idx_notification_timestamp ON notifications (timestamp)",
"CREATE UNIQUE INDEX idx_shuffle_watched_claim ON shuffle_watched (claim_id)",
}; };
private static final String[] SQL_V1_V2_UPGRADE = { private static final String[] SQL_V1_V2_UPGRADE = {
@ -99,6 +101,10 @@ public class DatabaseHelper extends SQLiteOpenHelper {
private static final String[] SQL_V5_V6_UPGRADE = { private static final String[] SQL_V5_V6_UPGRADE = {
"ALTER TABLE notifications ADD COLUMN author_url TEXT" "ALTER TABLE notifications ADD COLUMN author_url TEXT"
}; };
private static final String[] SQL_V6_V7_UPGRADE = {
"CREATE TABLE shuffle_watched (id INTEGER PRIMARY KEY NOT NULL, claim_id TEXT NOT NULL)",
"CREATE UNIQUE INDEX idx_shuffle_watched_claim ON shuffle_watched (claim_id)"
};
private static final String SQL_INSERT_SUBSCRIPTION = "REPLACE INTO subscriptions (channel_name, url) VALUES (?, ?)"; private static final String SQL_INSERT_SUBSCRIPTION = "REPLACE INTO subscriptions (channel_name, url) VALUES (?, ?)";
private static final String SQL_CLEAR_SUBSCRIPTIONS = "DELETE FROM subscriptions"; private static final String SQL_CLEAR_SUBSCRIPTIONS = "DELETE FROM subscriptions";
@ -116,6 +122,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
private static final String SQL_MARK_NOTIFICATIONS_READ = "UPDATE notifications SET is_read = 1 WHERE is_read = 0"; private static final String SQL_MARK_NOTIFICATIONS_READ = "UPDATE notifications SET is_read = 1 WHERE is_read = 0";
private static final String SQL_MARK_NOTIFICATION_READ_AND_SEEN = "UPDATE notifications SET is_read = 1, is_seen = 1 WHERE id = ?"; private static final String SQL_MARK_NOTIFICATION_READ_AND_SEEN = "UPDATE notifications SET is_read = 1, is_seen = 1 WHERE id = ?";
private static final String SQL_INSERT_SHUFFLE_WATCHED = "REPLACE INTO shuffle_watched (claim_id) VALUES (?)";
private static final String SQL_GET_SHUFFLE_WATCHED_CLAIMS = "SELECT claim_id FROM shuffle_watched";
private static final String SQL_INSERT_VIEW_HISTORY = private static final String SQL_INSERT_VIEW_HISTORY =
"REPLACE INTO view_history (url, claim_id, claim_name, cost, currency, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; "REPLACE INTO view_history (url, claim_id, claim_name, cost, currency, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String SQL_GET_VIEW_HISTORY = private static final String SQL_GET_VIEW_HISTORY =
@ -174,6 +183,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
db.execSQL(sql); db.execSQL(sql);
} }
} }
if (oldVersion < 7) {
for (String sql : SQL_V6_V7_UPGRADE) {
db.execSQL(sql);
}
}
} }
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
@ -190,6 +204,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
public static void clearUrlHistoryBefore(Date date, SQLiteDatabase db) { public static void clearUrlHistoryBefore(Date date, SQLiteDatabase db) {
db.execSQL(SQL_CLEAR_URL_HISTORY_BEFORE_TIME, new Object[] { new SimpleDateFormat(Helper.ISO_DATE_FORMAT_PATTERN).format(new Date()) }); db.execSQL(SQL_CLEAR_URL_HISTORY_BEFORE_TIME, new Object[] { new SimpleDateFormat(Helper.ISO_DATE_FORMAT_PATTERN).format(new Date()) });
} }
// History items are essentially url suggestions // History items are essentially url suggestions
public static List<UrlSuggestion> getRecentHistory(SQLiteDatabase db) { public static List<UrlSuggestion> getRecentHistory(SQLiteDatabase db) {
List<UrlSuggestion> suggestions = new ArrayList<>(); List<UrlSuggestion> suggestions = new ArrayList<>();
@ -376,4 +391,20 @@ public class DatabaseHelper extends SQLiteOpenHelper {
public static void markNotificationReadAndSeen(long notificationId, SQLiteDatabase db) { public static void markNotificationReadAndSeen(long notificationId, SQLiteDatabase db) {
db.execSQL(SQL_MARK_NOTIFICATION_READ_AND_SEEN, new Object[] { notificationId }); db.execSQL(SQL_MARK_NOTIFICATION_READ_AND_SEEN, new Object[] { notificationId });
} }
public static void createOrUpdateShuffleWatched(String claimId, SQLiteDatabase db) {
db.execSQL(SQL_INSERT_SHUFFLE_WATCHED, new Object[] { claimId });
}
public static List<String> getShuffleWatchedClaims(SQLiteDatabase db) {
List<String> claimIds = new ArrayList<>();
Cursor cursor = null;
try {
cursor = db.rawQuery(SQL_GET_SHUFFLE_WATCHED_CLAIMS, null);
while (cursor.moveToNext()) {
claimIds.add(cursor.getString(0));
}
} finally {
Helper.closeCursor(cursor);
}
return claimIds;
}
} }

View file

@ -3,6 +3,7 @@ package io.lbry.browser.ui.findcontent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color; import android.graphics.Color;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -45,6 +46,7 @@ import java.util.concurrent.TimeUnit;
import io.lbry.browser.MainActivity; import io.lbry.browser.MainActivity;
import io.lbry.browser.R; import io.lbry.browser.R;
import io.lbry.browser.data.DatabaseHelper;
import io.lbry.browser.exceptions.LbryUriException; import io.lbry.browser.exceptions.LbryUriException;
import io.lbry.browser.model.Claim; import io.lbry.browser.model.Claim;
import io.lbry.browser.model.lbryinc.Reward; import io.lbry.browser.model.lbryinc.Reward;
@ -70,6 +72,7 @@ public class ShuffleFragment extends BaseFragment {
private int playlistIndex; private int playlistIndex;
private Claim current; private Claim current;
private List<Claim> playlist; private List<Claim> playlist;
private List<String> watchedContentClaimIds;
private long sessionStart; private long sessionStart;
private ProgressBar surfModeLoading; private ProgressBar surfModeLoading;
@ -104,6 +107,10 @@ public class ShuffleFragment extends BaseFragment {
logPlay(currentUrl, startTimeMillis); logPlay(currentUrl, startTimeMillis);
playbackStarted = true; playbackStarted = true;
isPlaying = true; isPlaying = true;
if (current != null) {
saveWatchedContent(current.getClaimId());
}
} }
renderTotalDuration(); renderTotalDuration();
@ -227,13 +234,14 @@ public class ShuffleFragment extends BaseFragment {
} }
if (playlist == null) { if (playlist == null) {
loadContent(); loadWatchedContentList();
} else { } else {
if (current != null) { if (current != null) {
playbackCurrentClaim(); playbackCurrentClaim();
} else { } else {
startPlaylist(); startPlaylist();
} }
loadAndScheduleDurations();
} }
} }
@ -264,6 +272,46 @@ public class ShuffleFragment extends BaseFragment {
} }
private void loadWatchedContentList() {
(new AsyncTask<Void, Void, List<String>>() {
protected List<String> doInBackground(Void... params) {
MainActivity activity = (MainActivity) getContext();
if (activity != null) {
try {
SQLiteDatabase db = activity.getDbHelper().getReadableDatabase();
return DatabaseHelper.getShuffleWatchedClaims(db);
} catch (Exception ex) {
// pass
}
}
return null;
}
protected void onPostExecute(List<String> claimIds) {
watchedContentClaimIds = new ArrayList<>(claimIds);
if (playlist == null) {
loadContent();
}
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private void saveWatchedContent(final String claimId) {
(new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void... params) {
MainActivity activity = (MainActivity) getContext();
if (activity != null) {
try {
SQLiteDatabase db = activity.getDbHelper().getWritableDatabase();
DatabaseHelper.createOrUpdateShuffleWatched(claimId, db);
} catch (Exception ex) {
// pass
}
}
return null;
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private void loadContent() { private void loadContent() {
if (playlist == null || playlist.size() == 0) { if (playlist == null || playlist.size() == 0) {
Helper.setViewVisibility(surfModeLoading, View.VISIBLE); Helper.setViewVisibility(surfModeLoading, View.VISIBLE);
@ -301,6 +349,7 @@ public class ShuffleFragment extends BaseFragment {
playlistIndex = 0; playlistIndex = 0;
current = playlist.get(playlistIndex); current = playlist.get(playlistIndex);
checkCurrentClaimIsVideo(false); checkCurrentClaimIsVideo(false);
checkCurrentClaimWatched(false);
playbackCurrentClaim(); playbackCurrentClaim();
} }
@ -311,11 +360,26 @@ public class ShuffleFragment extends BaseFragment {
playlistIndex--; playlistIndex--;
} else { } else {
playlistIndex++; playlistIndex++;
checkPlaylistSize();
} }
current = playlist.get(playlistIndex); current = playlist.get(playlistIndex);
} }
} }
private void checkCurrentClaimWatched(boolean previous) {
if (current != null && watchedContentClaimIds != null) {
while (watchedContentClaimIds.contains(current.getClaimId())) {
if (previous) {
playlistIndex--;
} else {
playlistIndex++;
checkPlaylistSize();
}
current = playlist.get(playlistIndex);
}
}
}
private void playPreviousClaim() { private void playPreviousClaim() {
if (playlist == null || playlist.size() == 0) { if (playlist == null || playlist.size() == 0) {
return; return;
@ -325,6 +389,7 @@ public class ShuffleFragment extends BaseFragment {
} }
current = playlist.get(playlistIndex); current = playlist.get(playlistIndex);
checkCurrentClaimIsVideo(true); checkCurrentClaimIsVideo(true);
checkCurrentClaimWatched(true);
playbackCurrentClaim(); playbackCurrentClaim();
} }
private void playNextClaim() { private void playNextClaim() {
@ -334,13 +399,18 @@ public class ShuffleFragment extends BaseFragment {
if (playlistIndex < playlist.size() - 1) { if (playlistIndex < playlist.size() - 1) {
playlistIndex++; playlistIndex++;
} }
checkPlaylistSize();
current = playlist.get(playlistIndex);
checkCurrentClaimIsVideo(false);
checkCurrentClaimWatched(false);
playbackCurrentClaim();
}
private void checkPlaylistSize() {
if (playlist.size() - playlistIndex < 10) { if (playlist.size() - playlistIndex < 10) {
currentClaimSearchPage++; currentClaimSearchPage++;
loadContent(); loadContent();
} }
current = playlist.get(playlistIndex);
checkCurrentClaimIsVideo(false);
playbackCurrentClaim();
} }
private void playbackCurrentClaim() { private void playbackCurrentClaim() {