Merge branch 'master' of https://github.com/lbryio/lbry-android
This commit is contained in:
commit
b4626b2d6a
5 changed files with 152 additions and 12 deletions
|
@ -14,8 +14,8 @@ android {
|
||||||
applicationId "io.lbry.browser"
|
applicationId "io.lbry.browser"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 1604
|
versionCode 1606
|
||||||
versionName "0.16.4"
|
versionName "0.16.6"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import io.lbry.browser.ui.BaseFragment;
|
||||||
import io.lbry.browser.utils.Helper;
|
import io.lbry.browser.utils.Helper;
|
||||||
import io.lbry.browser.utils.Lbry;
|
import io.lbry.browser.utils.Lbry;
|
||||||
import io.lbry.browser.utils.LbryAnalytics;
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
|
import io.lbry.browser.utils.Predefined;
|
||||||
|
|
||||||
public class EditorsChoiceFragment extends BaseFragment {
|
public class EditorsChoiceFragment extends BaseFragment {
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ public class EditorsChoiceFragment extends BaseFragment {
|
||||||
return Lbry.buildClaimSearchOptions(
|
return Lbry.buildClaimSearchOptions(
|
||||||
Claim.TYPE_REPOST,
|
Claim.TYPE_REPOST,
|
||||||
null,
|
null,
|
||||||
null, /*canShowMatureContent ? null : new ArrayList<>(Predefined.MATURE_TAGS),*/
|
canShowMatureContent ? null : new ArrayList<>(Predefined.MATURE_TAGS),
|
||||||
new ArrayList<>(titleChannelIdsMap.values()),
|
new ArrayList<>(titleChannelIdsMap.values()),
|
||||||
null,
|
null,
|
||||||
Arrays.asList(Claim.ORDER_BY_RELEASE_TIME),
|
Arrays.asList(Claim.ORDER_BY_RELEASE_TIME),
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -20,6 +21,7 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||||
|
@ -45,6 +47,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 +73,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 +108,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 +235,31 @@ 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MainActivity.appPlayer != null) {
|
||||||
|
if (MainActivity.playerReassigned) {
|
||||||
|
setPlayerForPlayerView();
|
||||||
|
MainActivity.playerReassigned = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPlayerForPlayerView() {
|
||||||
|
View root = getView();
|
||||||
|
if (root != null) {
|
||||||
|
PlayerView view = root.findViewById(R.id.shuffle_exoplayer_view);
|
||||||
|
view.setVisibility(View.VISIBLE);
|
||||||
|
view.setPlayer(null);
|
||||||
|
view.setPlayer(MainActivity.appPlayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,6 +290,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 +367,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 +378,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 +407,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 +417,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() {
|
||||||
|
@ -432,8 +520,7 @@ public class ShuffleFragment extends BaseFragment {
|
||||||
playbackStarted = false;
|
playbackStarted = false;
|
||||||
startTimeMillis = 0;
|
startTimeMillis = 0;
|
||||||
|
|
||||||
/*
|
/*if (MainActivity.appPlayer != null) {
|
||||||
if (MainActivity.appPlayer != null) {
|
|
||||||
MainActivity.appPlayer.stop(true);
|
MainActivity.appPlayer.stop(true);
|
||||||
MainActivity.appPlayer.removeListener(fileViewPlayerListener);
|
MainActivity.appPlayer.removeListener(fileViewPlayerListener);
|
||||||
PlaybackParameters params = new PlaybackParameters(1.0f);
|
PlaybackParameters params = new PlaybackParameters(1.0f);
|
||||||
|
|
|
@ -493,7 +493,28 @@ public final class Predefined {
|
||||||
"covidcuts",
|
"covidcuts",
|
||||||
"covid-19"
|
"covid-19"
|
||||||
);
|
);
|
||||||
public static final List<String> MATURE_TAGS = Arrays.asList("mature", "nsfw", "porn", "xxx");
|
public static final List<String> MATURE_TAGS = Arrays.asList(
|
||||||
|
"porn",
|
||||||
|
"porno",
|
||||||
|
"nsfw",
|
||||||
|
"mature",
|
||||||
|
"xxx",
|
||||||
|
"sex",
|
||||||
|
"creampie",
|
||||||
|
"blowjob",
|
||||||
|
"handjob",
|
||||||
|
"vagina",
|
||||||
|
"boobs",
|
||||||
|
"big boobs",
|
||||||
|
"big dick",
|
||||||
|
"pussy",
|
||||||
|
"cumshot",
|
||||||
|
"anal",
|
||||||
|
"hard fucking",
|
||||||
|
"ass",
|
||||||
|
"fuck",
|
||||||
|
"hentai"
|
||||||
|
);
|
||||||
public static final List<String> ADJECTIVES = Arrays.asList(
|
public static final List<String> ADJECTIVES = Arrays.asList(
|
||||||
"aback",
|
"aback",
|
||||||
"abaft",
|
"abaft",
|
||||||
|
|
Loading…
Reference in a new issue