mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2026-05-16 04:52:39 +02:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 150a7d5006 | |||
| a0a73a8e5c | |||
| 4723a0b29a | |||
| adbe0357ba | |||
| b0a35bcf3f | |||
| 0e7482321c | |||
| e50d195b85 | |||
| 33780f1046 |
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 3,
|
||||
"identityHash": "ffba56c2f572c25080ce8596e8bb8945",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "history",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `url` TEXT NOT NULL, `position` INTEGER NOT NULL, `datetime` INTEGER NOT NULL, `name` TEXT NOT NULL, `serialized` BLOB)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "position",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "datetime",
|
||||
"columnName": "datetime",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "serialized",
|
||||
"columnName": "serialized",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_history_url",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"url"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_history_url` ON `${TABLE_NAME}` (`url`)"
|
||||
},
|
||||
{
|
||||
"name": "index_history_name",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"name"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_history_name` ON `${TABLE_NAME}` (`name`)"
|
||||
},
|
||||
{
|
||||
"name": "index_history_datetime",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"datetime"
|
||||
],
|
||||
"orders": [
|
||||
"DESC"
|
||||
],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_history_datetime` ON `${TABLE_NAME}` (`datetime` DESC)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ffba56c2f572c25080ce8596e8bb8945')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 5,
|
||||
"identityHash": "eb813d54b9c44d29f1d7bb198a16d4d1",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "subscription_cache",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `url` TEXT, `channelUrl` TEXT, `datetime` INTEGER, `serialized` BLOB)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "channelUrl",
|
||||
"columnName": "channelUrl",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "datetime",
|
||||
"columnName": "datetime",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "serialized",
|
||||
"columnName": "serialized",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_subscription_cache_url",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"url"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_subscription_cache_url` ON `${TABLE_NAME}` (`url`)"
|
||||
},
|
||||
{
|
||||
"name": "index_subscription_cache_channelUrl",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"channelUrl"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_subscription_cache_channelUrl` ON `${TABLE_NAME}` (`channelUrl`)"
|
||||
},
|
||||
{
|
||||
"name": "index_subscription_cache_datetime",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"datetime"
|
||||
],
|
||||
"orders": [
|
||||
"DESC"
|
||||
],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_subscription_cache_datetime` ON `${TABLE_NAME}` (`datetime` DESC)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'eb813d54b9c44d29f1d7bb198a16d4d1')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 3,
|
||||
"identityHash": "6e3b2d286325c4ea8a7a4c94c290daec",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "testing",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`someString` TEXT NOT NULL, `someNum` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `serialized` BLOB)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "someString",
|
||||
"columnName": "someString",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "someNum",
|
||||
"columnName": "someNum",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "serialized",
|
||||
"columnName": "serialized",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6e3b2d286325c4ea8a7a4c94c290daec')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@@ -35,9 +37,11 @@
|
||||
android:enabled="true"
|
||||
android:foregroundServiceType="mediaPlayback" />
|
||||
<service android:name=".services.DownloadService"
|
||||
android:enabled="true" />
|
||||
android:enabled="true"
|
||||
android:foregroundServiceType="dataSync" />
|
||||
<service android:name=".services.ExportingService"
|
||||
android:enabled="true" />
|
||||
android:enabled="true"
|
||||
android:foregroundServiceType="dataSync" />
|
||||
|
||||
<receiver android:name=".receivers.MediaControlReceiver" />
|
||||
<receiver android:name=".receivers.AudioNoisyReceiver" />
|
||||
|
||||
@@ -555,7 +555,7 @@ class Settings : FragmentedStorageFileJson() {
|
||||
val cookieManager: CookieManager = CookieManager.getInstance();
|
||||
cookieManager.removeAllCookies(null);
|
||||
}
|
||||
@FormField(R.string.reinstall_embedded_plugins, FieldForm.BUTTON, R.string.also_removes_any_data_related_plugin_like_login_or_settings, 1)
|
||||
/*@FormField(R.string.reinstall_embedded_plugins, FieldForm.BUTTON, R.string.also_removes_any_data_related_plugin_like_login_or_settings, 1)
|
||||
fun reinstallEmbedded() {
|
||||
StateApp.instance.scopeOrNull!!.launch(Dispatchers.IO) {
|
||||
try {
|
||||
@@ -574,7 +574,7 @@ class Settings : FragmentedStorageFileJson() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.futo.platformplayer.api.media.structures
|
||||
|
||||
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
||||
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
|
||||
import com.futo.platformplayer.assume
|
||||
import kotlin.streams.asSequence
|
||||
import kotlin.streams.toList
|
||||
|
||||
/**
|
||||
@@ -28,6 +30,7 @@ class PlatformContentPager : IPager<IPlatformContent> {
|
||||
_page++;
|
||||
_currentItems = _items.stream()
|
||||
.skip((_page * _pageSize).toLong())
|
||||
.asSequence()
|
||||
.toList()
|
||||
.take(_pageSize)
|
||||
.toList();
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.view.LayoutInflater
|
||||
import android.widget.Button
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.activities.MainActivity
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.SourcesFragment
|
||||
import com.futo.platformplayer.readBytes
|
||||
import com.futo.platformplayer.states.StateApp
|
||||
import com.futo.platformplayer.states.StateBackup
|
||||
@@ -19,6 +20,7 @@ class ImportOptionsDialog: AlertDialog {
|
||||
private lateinit var _button_import_ezip: BigButton;
|
||||
private lateinit var _button_import_txt: BigButton;
|
||||
private lateinit var _button_import_newpipe_subs: BigButton;
|
||||
private lateinit var _button_import_platform: BigButton;
|
||||
private lateinit var _button_close: Button;
|
||||
|
||||
|
||||
@@ -33,6 +35,7 @@ class ImportOptionsDialog: AlertDialog {
|
||||
_button_import_ezip = findViewById(R.id.button_import_ezip);
|
||||
_button_import_txt = findViewById(R.id.button_import_txt);
|
||||
_button_import_newpipe_subs = findViewById(R.id.button_import_newpipe_subs);
|
||||
_button_import_platform = findViewById(R.id.button_import_platform);
|
||||
_button_close = findViewById(R.id.button_cancel);
|
||||
|
||||
_button_import_zip.onClick.subscribe {
|
||||
@@ -61,6 +64,10 @@ class ImportOptionsDialog: AlertDialog {
|
||||
StateBackup.importNewPipeSubs(_context, json);
|
||||
};
|
||||
};
|
||||
_button_import_platform.onClick.subscribe {
|
||||
dismiss();
|
||||
_context.navigate(_context.getFragment<SourcesFragment>());
|
||||
};
|
||||
_button_close.setOnClickListener {
|
||||
dismiss();
|
||||
}
|
||||
|
||||
+25
@@ -264,6 +264,31 @@ class SourceDetailFragment : MainFragment() {
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
val migrationButtons = mutableListOf<BigButton>();
|
||||
if (isEnabled && source.capabilities.hasGetUserSubscriptions) {
|
||||
migrationButtons.add(
|
||||
BigButton(c, context.getString(R.string.import_subscriptions), context.getString(R.string.login_required), R.drawable.ic_subscriptions) {
|
||||
|
||||
}.apply { this.alpha = 0.5f }
|
||||
);
|
||||
}
|
||||
|
||||
if (isEnabled && source.capabilities.hasGetUserPlaylists && source.capabilities.hasGetPlaylist) {
|
||||
val bigButton = BigButton(c, context.getString(R.string.import_playlists), context.getString(R.string.login_required), R.drawable.ic_playlist) {
|
||||
|
||||
}.apply { this.alpha = 0.5f };
|
||||
|
||||
bigButton.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
|
||||
setMargins(0, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5f, resources.displayMetrics).toInt(), 0, 0);
|
||||
};
|
||||
|
||||
migrationButtons.add(bigButton);
|
||||
}
|
||||
|
||||
if (migrationButtons.size > 0) {
|
||||
groups.add(BigButtonGroup(c, context.getString(R.string.migration), *migrationButtons.toTypedArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -538,6 +538,7 @@ class VideoDetailView : ConstraintLayout {
|
||||
if(!_destroyed) {
|
||||
updateQueueState();
|
||||
StatePlayer.instance.updateMediaSession(null);
|
||||
_cast.setLoopVisible(!StatePlayer.instance.hasQueue);
|
||||
}
|
||||
};
|
||||
StatePlayer.instance.onVideoChanging.subscribe(this) {
|
||||
@@ -565,9 +566,7 @@ class VideoDetailView : ConstraintLayout {
|
||||
};
|
||||
|
||||
_upNext.onNextItem.subscribe {
|
||||
val item = StatePlayer.instance.nextQueueItem();
|
||||
if(item != null)
|
||||
setVideoOverview(item, true);
|
||||
nextVideo(true, true, true);
|
||||
};
|
||||
_upNext.onOpenQueueClick.subscribe {
|
||||
_container_content_queue.updateQueue();
|
||||
|
||||
@@ -17,6 +17,7 @@ import kotlinx.coroutines.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.nio.ByteBuffer
|
||||
import java.time.OffsetDateTime
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
class PolycentricCache {
|
||||
data class CachedOwnedClaims(val ownedClaims: List<OwnedClaim>?, val creationTime: OffsetDateTime = OffsetDateTime.now()) {
|
||||
@@ -29,8 +30,15 @@ class PolycentricCache {
|
||||
|
||||
private val _cache = hashMapOf<PlatformID, CachedOwnedClaims>()
|
||||
private val _profileCache = hashMapOf<PublicKey, CachedPolycentricProfile>()
|
||||
private val _profileUrlCache = FragmentedStorage.get<CachedPolycentricProfileStorage>("profileUrlCache")
|
||||
private val _profileUrlCache: CachedPolycentricProfileStorage;
|
||||
private val _scope = CoroutineScope(Dispatchers.IO);
|
||||
init {
|
||||
Logger.i(TAG, "Initializing Polycentric cache");
|
||||
val time = measureTimeMillis {
|
||||
_profileUrlCache = FragmentedStorage.get<CachedPolycentricProfileStorage>("profileUrlCache")
|
||||
}
|
||||
Logger.i(TAG, "Initialized Polycentric cache (${_profileUrlCache.map.size}, ${time}ms)");
|
||||
}
|
||||
|
||||
private val _taskGetProfile = BatchedTaskHandler<PublicKey, CachedPolycentricProfile>(_scope,
|
||||
{ system ->
|
||||
@@ -222,7 +230,7 @@ class PolycentricCache {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getProfileAsync(id: PlatformID, url: String? = null): CachedPolycentricProfile? {
|
||||
suspend fun getProfileAsync(id: PlatformID, urlNullCache: String? = null): CachedPolycentricProfile? {
|
||||
if (!StatePolycentric.instance.enabled || id.claimType <= 0) {
|
||||
return CachedPolycentricProfile(null);
|
||||
}
|
||||
@@ -243,8 +251,8 @@ class PolycentricCache {
|
||||
Logger.v(TAG, "getProfileAsync (id: $id) != null (with retrieved valid claims)")
|
||||
return getProfileAsync(claims.ownedClaims.first().system).await()
|
||||
} else {
|
||||
if(url != null)
|
||||
_profileUrlCache.setAndSave(url, PolycentricCache.CachedPolycentricProfile(null));
|
||||
if(urlNullCache != null)
|
||||
_profileUrlCache.setAndSave(urlNullCache, PolycentricCache.CachedPolycentricProfile(null));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
|
||||
import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.futo.platformplayer.*
|
||||
@@ -250,7 +253,11 @@ class DownloadService : Service() {
|
||||
val notif = builder.build();
|
||||
notif.flags = notif.flags or NotificationCompat.FLAG_ONGOING_EVENT or NotificationCompat.FLAG_NO_CLEAR;
|
||||
|
||||
startForeground(DOWNLOAD_NOTIF_ID, notif);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
startForeground(DOWNLOAD_NOTIF_ID, notif, FOREGROUND_SERVICE_TYPE_DATA_SYNC);
|
||||
} else {
|
||||
startForeground(DOWNLOAD_NOTIF_ID, notif);
|
||||
}
|
||||
}
|
||||
|
||||
fun closeDownloadSession() {
|
||||
|
||||
@@ -7,6 +7,8 @@ import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.FileProvider
|
||||
@@ -173,7 +175,11 @@ class ExportingService : Service() {
|
||||
val notif = builder.build();
|
||||
notif.flags = notif.flags or NotificationCompat.FLAG_ONGOING_EVENT or NotificationCompat.FLAG_NO_CLEAR;
|
||||
|
||||
startForeground(EXPORT_NOTIF_ID, notif);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
startForeground(EXPORT_NOTIF_ID, notif, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
|
||||
} else {
|
||||
startForeground(EXPORT_NOTIF_ID, notif);
|
||||
}
|
||||
}
|
||||
|
||||
fun closeExportSession() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.futo.platformplayer.states
|
||||
|
||||
import android.content.Context
|
||||
import kotlin.streams.asSequence
|
||||
import kotlin.streams.toList
|
||||
|
||||
/***
|
||||
@@ -26,7 +27,7 @@ class StateAssets {
|
||||
else
|
||||
break;
|
||||
}
|
||||
return (parts1 + parts2.stream().skip(toSkip.toLong()).toList()).joinToString("/");
|
||||
return (parts1 + parts2.stream().skip(toSkip.toLong()).asSequence().toList()).joinToString("/");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -99,7 +99,7 @@ class StateCache {
|
||||
|
||||
if(existing != null && doUpdate) {
|
||||
_subscriptionCache.update(existing.id!!, serialized);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
else if(existing == null) {
|
||||
_subscriptionCache.insert(serialized);
|
||||
|
||||
@@ -57,12 +57,16 @@ class StatePlayer {
|
||||
var queueShuffle: Boolean = false
|
||||
private set;
|
||||
|
||||
val hasQueue: Boolean get() {
|
||||
val queueSize: Int get() {
|
||||
synchronized(_queue) {
|
||||
return _queue.isNotEmpty()
|
||||
return _queue.size
|
||||
}
|
||||
}
|
||||
|
||||
val hasQueue: Boolean get() {
|
||||
return queueSize > 1
|
||||
}
|
||||
|
||||
val queueName: String get() = _queueName ?: _queueType;
|
||||
|
||||
//Events
|
||||
|
||||
@@ -169,10 +169,10 @@ class StatePolycentric {
|
||||
}
|
||||
}
|
||||
|
||||
fun getChannelUrls(url: String, channelId: PlatformID? = null, cacheOnly: Boolean = false): List<String> {
|
||||
return getChannelUrlsWithUpdateResult(url, channelId, cacheOnly).second;
|
||||
fun getChannelUrls(url: String, channelId: PlatformID? = null, cacheOnly: Boolean = false, doCacheNull: Boolean = false): List<String> {
|
||||
return getChannelUrlsWithUpdateResult(url, channelId, cacheOnly, doCacheNull).second;
|
||||
}
|
||||
fun getChannelUrlsWithUpdateResult(url: String, channelId: PlatformID? = null, cacheOnly: Boolean = false): Pair<Boolean, List<String>> {
|
||||
fun getChannelUrlsWithUpdateResult(url: String, channelId: PlatformID? = null, cacheOnly: Boolean = false, doCacheNull: Boolean = false): Pair<Boolean, List<String>> {
|
||||
var didUpdate = false;
|
||||
if (!enabled) {
|
||||
return Pair(false, listOf(url));
|
||||
@@ -184,7 +184,7 @@ class StatePolycentric {
|
||||
if (polycentricCached == null && channelId != null) {
|
||||
Logger.i("StateSubscriptions", "Get polycentric profile not cached");
|
||||
if(!cacheOnly) {
|
||||
polycentricProfile = runBlocking { PolycentricCache.instance.getProfileAsync(channelId, url) }?.profile;
|
||||
polycentricProfile = runBlocking { PolycentricCache.instance.getProfileAsync(channelId, if(doCacheNull) url else null) }?.profile;
|
||||
didUpdate = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -258,11 +258,12 @@ class StateSubscriptions {
|
||||
var polycentricBudget: Int = 10;
|
||||
val subUrls = getSubscriptions().parallelStream().map {
|
||||
if(usePolycentric) {
|
||||
val result = StatePolycentric.instance.getChannelUrlsWithUpdateResult(it.channel.url, it.channel.id, polycentricBudget <= 0);
|
||||
if(result.first)
|
||||
val result = StatePolycentric.instance.getChannelUrlsWithUpdateResult(it.channel.url, it.channel.id, polycentricBudget <= 0, true);
|
||||
if(result.first) {
|
||||
synchronized(lock) {
|
||||
polycentricBudget--;
|
||||
}
|
||||
}
|
||||
Pair(it, result.second);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -106,6 +106,10 @@ class CastView : ConstraintLayout {
|
||||
_gestureControlView.stopAllGestures();
|
||||
}
|
||||
|
||||
fun setLoopVisible(visible: Boolean) {
|
||||
_buttonLoop.visibility = if (visible) View.VISIBLE else View.GONE;
|
||||
}
|
||||
|
||||
fun setIsPlaying(isPlaying: Boolean) {
|
||||
_updateTimeJob?.cancel();
|
||||
|
||||
|
||||
@@ -22,7 +22,10 @@ class QueueEditorOverlay : LinearLayout {
|
||||
|
||||
_topbar.onClose.subscribe(this, onClose::emit);
|
||||
_editor.onVideoOrderChanged.subscribe { StatePlayer.instance.setQueueWithExisting(it) }
|
||||
_editor.onVideoRemoved.subscribe { v -> StatePlayer.instance.removeFromQueue(v) }
|
||||
_editor.onVideoRemoved.subscribe { v ->
|
||||
StatePlayer.instance.removeFromQueue(v);
|
||||
_topbar.setInfo(context.getString(R.string.queue), "${StatePlayer.instance.queueSize} " + context.getString(R.string.videos));
|
||||
}
|
||||
_editor.onVideoClicked.subscribe { v -> StatePlayer.instance.setQueuePosition(v) }
|
||||
|
||||
_topbar.setInfo(context.getString(R.string.queue), "");
|
||||
|
||||
@@ -305,6 +305,7 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
|
||||
|
||||
StatePlayer.instance.onQueueChanged.subscribe(this) {
|
||||
CoroutineScope(Dispatchers.Main).launch(Dispatchers.Main) {
|
||||
setLoopVisible(!StatePlayer.instance.hasQueue)
|
||||
updateNextPrevious();
|
||||
}
|
||||
}
|
||||
@@ -361,6 +362,11 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
|
||||
_currentChapterLoopActive = false;
|
||||
}
|
||||
|
||||
fun setLoopVisible(visible: Boolean) {
|
||||
_control_loop.visibility = if (visible) View.VISIBLE else View.GONE;
|
||||
_control_loop_fullscreen.visibility = if (visible) View.VISIBLE else View.GONE;
|
||||
}
|
||||
|
||||
fun stopAllGestures() {
|
||||
gestureControl.stopAllGestures();
|
||||
}
|
||||
@@ -391,11 +397,11 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
|
||||
fun setArtwork(drawable: Drawable?) {
|
||||
if (drawable != null) {
|
||||
_videoView.defaultArtwork = drawable;
|
||||
_videoView.useArtwork = true;
|
||||
_videoView.artworkDisplayMode = StyledPlayerView.ARTWORK_DISPLAY_MODE_FILL;
|
||||
fitOrFill(isFullScreen);
|
||||
} else {
|
||||
_videoView.defaultArtwork = null;
|
||||
_videoView.useArtwork = false;
|
||||
_videoView.artworkDisplayMode = StyledPlayerView.ARTWORK_DISPLAY_MODE_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,16 @@
|
||||
android:paddingTop="10dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="10dp">
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:id="@+id/button_import_platform"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleY="0.9"
|
||||
android:scaleX="0.9"
|
||||
app:buttonIcon="@drawable/ic_sources_filled"
|
||||
app:buttonText="Import from Platform"
|
||||
app:buttonBackground="@drawable/background_big_button_black"
|
||||
app:buttonSubText="Import your data from a specific source" />
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:id="@+id/button_import_zip"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -70,10 +70,11 @@
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toRightOf="@id/image_thumbnail"
|
||||
app:layout_constraintLeft_toLeftOf="@id/text_body"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_body"
|
||||
android:layout_marginLeft="-10dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
@@ -83,7 +84,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginStart="10dp" />
|
||||
android:layout_marginStart="9dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_rating"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="13dp"
|
||||
android:gravity="center_vertical"
|
||||
tools:text="500K" />
|
||||
tools:text="50K" />
|
||||
|
||||
<com.futo.platformplayer.views.LoaderView
|
||||
android:id="@+id/loader_likes"
|
||||
@@ -42,6 +42,8 @@
|
||||
android:id="@+id/pill_seperator"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="7dp"
|
||||
android:layout_marginBottom="7dp"
|
||||
|
||||
android:background="#808080"/>
|
||||
|
||||
@@ -68,7 +70,7 @@
|
||||
android:textColor="@color/white"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="13dp"
|
||||
tools:text="500K" />
|
||||
tools:text="50K" />
|
||||
<com.futo.platformplayer.views.LoaderView
|
||||
android:id="@+id/loader_dislikes"
|
||||
android:layout_width="14dp"
|
||||
|
||||
@@ -577,6 +577,7 @@
|
||||
<string name="import_your_subscriptions_from_this_source">Import your subscriptions from this source</string>
|
||||
<string name="import_your_playlists_from_this_source">Import your playlists from this source</string>
|
||||
<string name="login">Login</string>
|
||||
<string name="login_required">Login Required</string>
|
||||
<string name="sign_into_the_platform_of_this_source">Sign into the platform of this source</string>
|
||||
<string name="management">Management</string>
|
||||
<string name="uninstall">Uninstall</string>
|
||||
|
||||
@@ -24,6 +24,12 @@
|
||||
<data android:host="www.youtube.com" />
|
||||
<data android:host="m.youtube.com" />
|
||||
<data android:host="rumble.com" />
|
||||
<data android:host="kick.com" />
|
||||
<data android:host="nebula.tv" />
|
||||
<data android:host="odysee.com" />
|
||||
<data android:host="patreon.com" />
|
||||
<data android:host="soundcloud.com" />
|
||||
<data android:host="twitch.tv" />
|
||||
<data android:pathPrefix="/" />
|
||||
</intent-filter>
|
||||
<intent-filter android:autoVerify="true">
|
||||
@@ -33,11 +39,18 @@
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
|
||||
<data android:host="youtube.com" />
|
||||
<data android:host="m.youtube.com" />
|
||||
<data android:host="you.be" />
|
||||
<data android:host="youtu.be" />
|
||||
<data android:host="www.you.be" />
|
||||
<data android:host="youtube.com" />
|
||||
<data android:host="www.youtube.com" />
|
||||
<data android:host="m.youtube.com" />
|
||||
<data android:host="rumble.com" />
|
||||
<data android:host="kick.com" />
|
||||
<data android:host="nebula.tv" />
|
||||
<data android:host="odysee.com" />
|
||||
<data android:host="patreon.com" />
|
||||
<data android:host="soundcloud.com" />
|
||||
<data android:host="twitch.tv" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
Submodule app/src/stable/assets/sources/youtube updated: 8b8fd55f39...fc5d17e190
Submodule app/src/unstable/assets/sources/youtube updated: 8b8fd55f39...fc5d17e190
Reference in New Issue
Block a user