From ea5aad0631c2506c936b70d44337e7e3bcf76565 Mon Sep 17 00:00:00 2001 From: Koen Date: Wed, 27 Dec 2023 11:11:29 +0100 Subject: [PATCH 1/2] Implemented check for updates. --- .../java/com/futo/platformplayer/Settings.kt | 4 +- .../activities/AddSourceActivity.kt | 4 +- .../activities/ExceptionActivity.kt | 4 +- .../mainactivity/main/SourceDetailFragment.kt | 1 + .../futo/platformplayer/states/StateApp.kt | 21 +++++- .../platformplayer/states/StatePlatform.kt | 63 ++++++++++++++++++ .../platformplayer/states/StatePlugins.kt | 2 - .../futo/platformplayer/states/StateUpdate.kt | 64 +++++++++---------- .../views/adapters/DisabledSourceAdapter.kt | 42 ------------ .../views/adapters/DisabledSourceView.kt | 12 ++-- .../adapters/DisabledSourceViewHolder.kt | 44 ------------- .../views/adapters/EnabledSourceViewHolder.kt | 14 +++- .../views/sources/SourceHeaderView.kt | 7 ++ .../main/res/layout/view_source_header.xml | 22 +++++++ app/src/main/res/values/strings.xml | 2 + app/src/stable/assets/sources/odysee | 2 +- app/src/stable/assets/sources/patreon | 2 +- app/src/stable/assets/sources/youtube | 2 +- app/src/unstable/assets/sources/odysee | 2 +- app/src/unstable/assets/sources/patreon | 2 +- app/src/unstable/assets/sources/youtube | 2 +- 21 files changed, 181 insertions(+), 137 deletions(-) delete mode 100644 app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceAdapter.kt delete mode 100644 app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceViewHolder.kt diff --git a/app/src/main/java/com/futo/platformplayer/Settings.kt b/app/src/main/java/com/futo/platformplayer/Settings.kt index f2d689ed..168cddfb 100644 --- a/app/src/main/java/com/futo/platformplayer/Settings.kt +++ b/app/src/main/java/com/futo/platformplayer/Settings.kt @@ -685,7 +685,9 @@ class Settings : FragmentedStorageFileJson() { fun manualCheck() { if (!BuildConfig.IS_PLAYSTORE_BUILD) { SettingsActivity.getActivity()?.let { - StateUpdate.instance.checkForUpdates(it, true); + StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { + StateUpdate.instance.checkForUpdates(it, true) + } } } else { SettingsActivity.getActivity()?.let { diff --git a/app/src/main/java/com/futo/platformplayer/activities/AddSourceActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/AddSourceActivity.kt index bc22d3dc..06720574 100644 --- a/app/src/main/java/com/futo/platformplayer/activities/AddSourceActivity.kt +++ b/app/src/main/java/com/futo/platformplayer/activities/AddSourceActivity.kt @@ -216,8 +216,10 @@ class AddSourceActivity : AppCompatActivity() { fun install(config: SourcePluginConfig, script: String) { StatePlugins.instance.installPlugin(this, lifecycleScope, config, script) { - if(it) + if(it) { + StatePlatform.instance.clearUpdateAvailable(config) backToSources(); + } } } diff --git a/app/src/main/java/com/futo/platformplayer/activities/ExceptionActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/ExceptionActivity.kt index a51c0f4a..99a6e1b0 100644 --- a/app/src/main/java/com/futo/platformplayer/activities/ExceptionActivity.kt +++ b/app/src/main/java/com/futo/platformplayer/activities/ExceptionActivity.kt @@ -9,9 +9,11 @@ import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope -import com.futo.platformplayer.* +import com.futo.platformplayer.BuildConfig +import com.futo.platformplayer.R import com.futo.platformplayer.logging.LogLevel import com.futo.platformplayer.logging.Logging +import com.futo.platformplayer.setNavigationBarColorAndIcons import com.futo.platformplayer.states.StateApp import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SourceDetailFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SourceDetailFragment.kt index 3af3f01d..6a743d4e 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SourceDetailFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SourceDetailFragment.kt @@ -454,6 +454,7 @@ class SourceDetailFragment : MainFragment() { } }); } + private fun checkForUpdatesSource() { val c = _config ?: return; val sourceUrl = c.sourceUrl ?: return; diff --git a/app/src/main/java/com/futo/platformplayer/states/StateApp.kt b/app/src/main/java/com/futo/platformplayer/states/StateApp.kt index bcf68592..412abd55 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateApp.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateApp.kt @@ -460,7 +460,9 @@ class StateApp { //Foreground download autoUpdateEnabled -> { - StateUpdate.instance.checkForUpdates(context, false); + scopeOrNull?.launch(Dispatchers.IO) { + StateUpdate.instance.checkForUpdates(context, false) + } } else -> { @@ -558,6 +560,23 @@ class StateApp { if(StateHistory.instance.shouldMigrateLegacyHistory()) StateHistory.instance.migrateLegacyHistory(); + + StateAnnouncement.instance.deleteAnnouncement("plugin-update") + + scopeOrNull?.launch(Dispatchers.IO) { + val updateAvailableCount = StatePlatform.instance.checkForUpdates() + + withContext(Dispatchers.Main) { + if (updateAvailableCount > 0) { + StateAnnouncement.instance.registerAnnouncement( + "plugin-update", + "Plugin updates available", + "There are $updateAvailableCount plugin updates available.", + AnnouncementType.SESSION_RECURRING + ) + } + } + } } fun mainAppStartedWithExternalFiles(context: Context) { diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePlatform.kt b/app/src/main/java/com/futo/platformplayer/states/StatePlatform.kt index a9aae85d..fe06e78d 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StatePlatform.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StatePlatform.kt @@ -5,6 +5,7 @@ import androidx.collection.LruCache import com.futo.platformplayer.R import com.futo.platformplayer.Settings import com.futo.platformplayer.UIDialogs +import com.futo.platformplayer.api.http.ManagedHttpClient import com.futo.platformplayer.api.media.IPlatformClient import com.futo.platformplayer.api.media.IPluginSourced import com.futo.platformplayer.api.media.PlatformMultiClientPool @@ -78,6 +79,7 @@ class StatePlatform { private val _clientsLock = Object(); private val _availableClients : ArrayList = ArrayList(); private val _enabledClients : ArrayList = ArrayList(); + private var _updatesAvailableMap: HashSet = hashSetOf(); //ClientPools are used to isolate plugin usage of certain components from others //This prevents for example a background task like subscriptions from blocking a user from opening a video @@ -932,6 +934,67 @@ class StatePlatform { } } + fun hasUpdateAvailable(c: SourcePluginConfig): Boolean { + val updatesAvailableMap = _updatesAvailableMap + synchronized(updatesAvailableMap) { + return updatesAvailableMap.contains(c.id) + } + } + + suspend fun checkForUpdates(): Int = withContext(Dispatchers.IO) { + var updateAvailableCount = 0 + val updatesAvailableFor = hashSetOf() + for (availableClient in getAvailableClients()) { + if (availableClient !is JSClient) { + continue + } + + if (checkForUpdates(availableClient.config)) { + updateAvailableCount++ + updatesAvailableFor.add(availableClient.config.id) + } + } + + _updatesAvailableMap = updatesAvailableFor + return@withContext updateAvailableCount + } + + fun clearUpdateAvailable(c: SourcePluginConfig) { + val updatesAvailableMap = _updatesAvailableMap + synchronized(updatesAvailableMap) { + updatesAvailableMap.remove(c.id) + } + } + + private suspend fun checkForUpdates(c: SourcePluginConfig): Boolean = withContext(Dispatchers.IO) { + val sourceUrl = c.sourceUrl ?: return@withContext false; + + Logger.i(TAG, "Check for source updates '${c.name}'."); + try { + val client = ManagedHttpClient(); + val response = client.get(sourceUrl); + Logger.i(TAG, "Downloading source config '$sourceUrl'."); + + if (!response.isOk || response.body == null) { + return@withContext false; + } + + val configJson = response.body.string(); + Logger.i(TAG, "Downloaded source config ($sourceUrl):\n${configJson}"); + + val config = SourcePluginConfig.fromJson(configJson); + if (config.version <= c.version) { + return@withContext false; + } + + Logger.i(TAG, "Update is available (config.version=${config.version}, source.config.version=${c.version})."); + return@withContext true; + } catch (e: Throwable) { + Logger.e(TAG, "Failed to check for updates.", e); + return@withContext false; + } + } + companion object { private var _instance : StatePlatform? = null; val instance : StatePlatform diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePlugins.kt b/app/src/main/java/com/futo/platformplayer/states/StatePlugins.kt index 2f08937d..34848c1d 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StatePlugins.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StatePlugins.kt @@ -10,7 +10,6 @@ import com.futo.platformplayer.api.media.platforms.js.SourceAuth import com.futo.platformplayer.api.media.platforms.js.SourceCaptchaData import com.futo.platformplayer.api.media.platforms.js.SourcePluginConfig import com.futo.platformplayer.api.media.platforms.js.SourcePluginDescriptor -import com.futo.platformplayer.developer.DeveloperEndpoints import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.ImageVariable import com.futo.platformplayer.stores.FragmentedStorage @@ -467,7 +466,6 @@ class StatePlugins { _plugins.save(descriptor); } - @Serializable private data class PluginConfig( val SOURCES_EMBEDDED: Map, diff --git a/app/src/main/java/com/futo/platformplayer/states/StateUpdate.kt b/app/src/main/java/com/futo/platformplayer/states/StateUpdate.kt index 1a5e4c80..7a625a15 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateUpdate.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateUpdate.kt @@ -2,15 +2,15 @@ package com.futo.platformplayer.states import android.content.Context import android.os.Build -import android.os.Environment -import com.futo.platformplayer.* +import com.futo.platformplayer.BuildConfig +import com.futo.platformplayer.UIDialogs import com.futo.platformplayer.api.http.ManagedHttpClient +import com.futo.platformplayer.copyToOutputStream import com.futo.platformplayer.logging.Logger import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File -import java.io.FileNotFoundException import java.io.InputStream import java.io.OutputStream @@ -155,47 +155,45 @@ class StateUpdate { } } - fun checkForUpdates(context: Context, showUpToDateToast: Boolean) { - StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { - try { - val client = ManagedHttpClient(); - val latestVersion = downloadVersionCode(client); + suspend fun checkForUpdates(context: Context, showUpToDateToast: Boolean) = withContext(Dispatchers.IO) { + try { + val client = ManagedHttpClient(); + val latestVersion = downloadVersionCode(client); - if (latestVersion != null) { - val currentVersion = BuildConfig.VERSION_CODE; - Logger.i(TAG, "Current version ${currentVersion} latest version ${latestVersion}."); + if (latestVersion != null) { + val currentVersion = BuildConfig.VERSION_CODE; + Logger.i(TAG, "Current version ${currentVersion} latest version ${latestVersion}."); - if (latestVersion > currentVersion) { - withContext(Dispatchers.Main) { - try { - UIDialogs.showUpdateAvailableDialog(context, latestVersion); - } catch (e: Throwable) { - UIDialogs.toast(context, "Failed to show update dialog"); - Logger.w(TAG, "Error occurred in update dialog."); - } - } - } else { - if (showUpToDateToast) { - withContext(Dispatchers.Main) { - UIDialogs.toast(context, "Already on latest version"); - } + if (latestVersion > currentVersion) { + withContext(Dispatchers.Main) { + try { + UIDialogs.showUpdateAvailableDialog(context, latestVersion); + } catch (e: Throwable) { + UIDialogs.toast(context, "Failed to show update dialog"); + Logger.w(TAG, "Error occurred in update dialog."); } } } else { - Logger.w(TAG, "Failed to retrieve version from version URL."); - - withContext(Dispatchers.Main) { - UIDialogs.toast(context, "Failed to retrieve version"); + if (showUpToDateToast) { + withContext(Dispatchers.Main) { + UIDialogs.toast(context, "Already on latest version"); + } } } - } catch (e: Throwable) { - Logger.w(TAG, "Failed to check for updates.", e); + } else { + Logger.w(TAG, "Failed to retrieve version from version URL."); withContext(Dispatchers.Main) { - UIDialogs.toast(context, "Failed to check for updates"); + UIDialogs.toast(context, "Failed to retrieve version"); } } - }; + } catch (e: Throwable) { + Logger.w(TAG, "Failed to check for updates.", e); + + withContext(Dispatchers.Main) { + UIDialogs.toast(context, "Failed to check for updates"); + } + } } private fun downloadApkToFile(client: ManagedHttpClient, destinationFile: File, isCancelled: (() -> Boolean)? = null) { diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceAdapter.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceAdapter.kt deleted file mode 100644 index 4ce52646..00000000 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceAdapter.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.futo.platformplayer.views.adapters - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import com.futo.platformplayer.R -import com.futo.platformplayer.api.media.IPlatformClient -import com.futo.platformplayer.constructs.Event1 - -class DisabledSourceAdapter : RecyclerView.Adapter { - private val _sources: MutableList; - - var onClick = Event1(); - var onAdd = Event1(); - - constructor(sources: MutableList) : super() { - _sources = sources; - } - - override fun getItemCount() = _sources.size - - override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): DisabledSourceViewHolder { - val holder = DisabledSourceViewHolder(viewGroup); - holder.onAdd.subscribe { - val source = holder.source; - if (source != null) { - onAdd.emit(source); - } - } - holder.onClick.subscribe { - val source = holder.source; - if (source != null) { - onClick.emit(source); - } - }; - return holder; - } - - override fun onBindViewHolder(viewHolder: DisabledSourceViewHolder, position: Int) { - viewHolder.bind(_sources[position]) - } -} diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceView.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceView.kt index 83cc2d95..492a4c1b 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceView.kt @@ -1,17 +1,15 @@ package com.futo.platformplayer.views.adapters import android.content.Context -import android.view.LayoutInflater -import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView -import androidx.recyclerview.widget.RecyclerView.ViewHolder import com.futo.platformplayer.R import com.futo.platformplayer.api.media.IPlatformClient import com.futo.platformplayer.api.media.platforms.js.JSClient import com.futo.platformplayer.constructs.Event0 import com.futo.platformplayer.constructs.Event1 +import com.futo.platformplayer.states.StatePlatform class DisabledSourceView : LinearLayout { private val _root: LinearLayout; @@ -38,7 +36,13 @@ class DisabledSourceView : LinearLayout { client.icon?.setImageView(_imageSource); _textSource.text = client.name; - _textSourceSubtitle.text = context.getString(R.string.tap_to_open); + if (client is JSClient && StatePlatform.instance.hasUpdateAvailable(client.config)) { + _textSourceSubtitle.text = context.getString(R.string.update_available_exclamation) + _textSourceSubtitle.setTextColor(context.getColor(R.color.light_blue_400)) + } else { + _textSourceSubtitle.text = context.getString(R.string.tap_to_open) + _textSourceSubtitle.setTextColor(context.getColor(R.color.gray_ac)) + } _buttonAdd.setOnClickListener { onAdd.emit(source) } _root.setOnClickListener { onClick.emit(); }; diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceViewHolder.kt deleted file mode 100644 index ed55fe62..00000000 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceViewHolder.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.futo.platformplayer.views.adapters - -import android.view.LayoutInflater -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.TextView -import androidx.recyclerview.widget.RecyclerView.ViewHolder -import com.futo.platformplayer.R -import com.futo.platformplayer.api.media.IPlatformClient -import com.futo.platformplayer.api.media.platforms.js.JSClient -import com.futo.platformplayer.constructs.Event0 - -class DisabledSourceViewHolder : ViewHolder { - private val _imageSource: ImageView; - private val _textSource: TextView; - private val _textSourceSubtitle: TextView; - - private val _buttonAdd: LinearLayout; - - var onClick = Event0(); - var onAdd = Event0(); - var source: IPlatformClient? = null - private set - - constructor(viewGroup: ViewGroup) : super(LayoutInflater.from(viewGroup.context).inflate(R.layout.list_source_disabled, viewGroup, false)) { - _imageSource = itemView.findViewById(R.id.image_source); - _textSource = itemView.findViewById(R.id.text_source); - _textSourceSubtitle = itemView.findViewById(R.id.text_source_subtitle); - _buttonAdd = itemView.findViewById(R.id.button_add); - - val root = itemView.findViewById(R.id.root); - _buttonAdd.setOnClickListener { onAdd.emit() } - root.setOnClickListener { onClick.emit(); }; - } - - fun bind(client: IPlatformClient) { - client.icon?.setImageView(_imageSource); - - _textSource.text = client.name; - _textSourceSubtitle.text = itemView.context.getString(R.string.tap_to_open); - source = client; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/EnabledSourceViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/EnabledSourceViewHolder.kt index 78cb55c4..315571ce 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/EnabledSourceViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/EnabledSourceViewHolder.kt @@ -10,7 +10,9 @@ import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView.ViewHolder import com.futo.platformplayer.R import com.futo.platformplayer.api.media.IPlatformClient +import com.futo.platformplayer.api.media.platforms.js.JSClient import com.futo.platformplayer.constructs.Event1 +import com.futo.platformplayer.states.StatePlatform class EnabledSourceViewHolder : ViewHolder { private val _imageSource: ImageView; @@ -57,8 +59,16 @@ class EnabledSourceViewHolder : ViewHolder { fun bind(client: IPlatformClient) { client.icon?.setImageView(_imageSource); - _textSource.text = client.name; - _textSourceSubtitle.text = itemView.context.getString(R.string.tap_to_open); + _textSource.text = client.name + + if (client is JSClient && StatePlatform.instance.hasUpdateAvailable(client.config)) { + _textSourceSubtitle.text = itemView.context.getString(R.string.update_available_exclamation) + _textSourceSubtitle.setTextColor(itemView.context.getColor(R.color.light_blue_400)) + } else { + _textSourceSubtitle.text = itemView.context.getString(R.string.tap_to_open) + _textSourceSubtitle.setTextColor(itemView.context.getColor(R.color.gray_ac)) + } + source = client } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/views/sources/SourceHeaderView.kt b/app/src/main/java/com/futo/platformplayer/views/sources/SourceHeaderView.kt index 2b0c4e10..614f7d06 100644 --- a/app/src/main/java/com/futo/platformplayer/views/sources/SourceHeaderView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/sources/SourceHeaderView.kt @@ -25,6 +25,7 @@ class SourceHeaderView : LinearLayout { private val _sourcePlatformUrl: TextView; private val _sourceRepositoryUrl: TextView; private val _sourceScriptUrl: TextView; + private val _sourceScriptConfig: TextView; private val _sourceSignature: TextView; private val _sourcePlatformUrlContainer: LinearLayout; @@ -45,6 +46,7 @@ class SourceHeaderView : LinearLayout { _sourcePlatformUrl = findViewById(R.id.source_platform); _sourcePlatformUrlContainer = findViewById(R.id.source_platform_container); _sourceScriptUrl = findViewById(R.id.source_script); + _sourceScriptConfig = findViewById(R.id.source_config); _sourceSignature = findViewById(R.id.source_signature); _sourceBy.setOnClickListener { @@ -59,6 +61,10 @@ class SourceHeaderView : LinearLayout { if(!_config?.absoluteScriptUrl.isNullOrEmpty()) context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(_config?.absoluteScriptUrl))); }; + _sourceScriptConfig.setOnClickListener { + if(!_config?.sourceUrl.isNullOrEmpty()) + context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(_config?.sourceUrl))); + } _sourcePlatformUrl.setOnClickListener { if(!_config?.platformUrl.isNullOrEmpty()) context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(_config?.platformUrl))); @@ -82,6 +88,7 @@ class SourceHeaderView : LinearLayout { _sourceVersion.text = config.version.toString(); _sourceScriptUrl.text = config.absoluteScriptUrl; _sourceRepositoryUrl.text = config.repositoryUrl; + _sourceScriptConfig.text = config.sourceUrl _sourceAuthorID.text = ""; _sourcePlatformUrl.text = config.platformUrl ?: ""; diff --git a/app/src/main/res/layout/view_source_header.xml b/app/src/main/res/layout/view_source_header.xml index 2042fa48..6a62c45b 100644 --- a/app/src/main/res/layout/view_source_header.xml +++ b/app/src/main/res/layout/view_source_header.xml @@ -170,6 +170,28 @@ tools:text="https://some.repository.url/whatever/someScript.js" /> + + + + + Platform URL Repository URL Script URL + Config URL These are the permissions the plugin requires to function The plugin will have access to eval capacity The plugin will have access to the following domains @@ -651,6 +652,7 @@ Please use at least 3 characters Are you sure you want to delete this video? Tap to open + Update available! watching available in seconds diff --git a/app/src/stable/assets/sources/odysee b/app/src/stable/assets/sources/odysee index a21ad568..206d9968 160000 --- a/app/src/stable/assets/sources/odysee +++ b/app/src/stable/assets/sources/odysee @@ -1 +1 @@ -Subproject commit a21ad56829b0f0b45bbd677979f3d260e13abb34 +Subproject commit 206d996801b9734cae13093859375c70be980a8d diff --git a/app/src/stable/assets/sources/patreon b/app/src/stable/assets/sources/patreon index 55aef15f..13944460 160000 --- a/app/src/stable/assets/sources/patreon +++ b/app/src/stable/assets/sources/patreon @@ -1 +1 @@ -Subproject commit 55aef15f4b4ad1359266bb77908b48726d32594b +Subproject commit 139444608dbd561a317fc4666dfe01b868335e80 diff --git a/app/src/stable/assets/sources/youtube b/app/src/stable/assets/sources/youtube index 058e3752..a1980eea 160000 --- a/app/src/stable/assets/sources/youtube +++ b/app/src/stable/assets/sources/youtube @@ -1 +1 @@ -Subproject commit 058e37525756c285848f0774e4e3eb6f65282280 +Subproject commit a1980eeac4e917c21fed3feb97b3dee24e536726 diff --git a/app/src/unstable/assets/sources/odysee b/app/src/unstable/assets/sources/odysee index a21ad568..206d9968 160000 --- a/app/src/unstable/assets/sources/odysee +++ b/app/src/unstable/assets/sources/odysee @@ -1 +1 @@ -Subproject commit a21ad56829b0f0b45bbd677979f3d260e13abb34 +Subproject commit 206d996801b9734cae13093859375c70be980a8d diff --git a/app/src/unstable/assets/sources/patreon b/app/src/unstable/assets/sources/patreon index 55aef15f..13944460 160000 --- a/app/src/unstable/assets/sources/patreon +++ b/app/src/unstable/assets/sources/patreon @@ -1 +1 @@ -Subproject commit 55aef15f4b4ad1359266bb77908b48726d32594b +Subproject commit 139444608dbd561a317fc4666dfe01b868335e80 diff --git a/app/src/unstable/assets/sources/youtube b/app/src/unstable/assets/sources/youtube index 058e3752..a1980eea 160000 --- a/app/src/unstable/assets/sources/youtube +++ b/app/src/unstable/assets/sources/youtube @@ -1 +1 @@ -Subproject commit 058e37525756c285848f0774e4e3eb6f65282280 +Subproject commit a1980eeac4e917c21fed3feb97b3dee24e536726 From 89603d0ff3bd5fb7685cff0b9222d09f7bb04277 Mon Sep 17 00:00:00 2001 From: Koen Date: Wed, 27 Dec 2023 14:31:26 +0100 Subject: [PATCH 2/2] changed typeface when update is available. --- .../futo/platformplayer/views/adapters/DisabledSourceView.kt | 3 +++ .../platformplayer/views/adapters/EnabledSourceViewHolder.kt | 2 ++ 2 files changed, 5 insertions(+) diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceView.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceView.kt index 492a4c1b..a7194ae7 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/DisabledSourceView.kt @@ -36,12 +36,15 @@ class DisabledSourceView : LinearLayout { client.icon?.setImageView(_imageSource); _textSource.text = client.name; + if (client is JSClient && StatePlatform.instance.hasUpdateAvailable(client.config)) { _textSourceSubtitle.text = context.getString(R.string.update_available_exclamation) _textSourceSubtitle.setTextColor(context.getColor(R.color.light_blue_400)) + _textSourceSubtitle.typeface = resources.getFont(R.font.inter_regular) } else { _textSourceSubtitle.text = context.getString(R.string.tap_to_open) _textSourceSubtitle.setTextColor(context.getColor(R.color.gray_ac)) + _textSourceSubtitle.typeface = resources.getFont(R.font.inter_extra_light) } _buttonAdd.setOnClickListener { onAdd.emit(source) } diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/EnabledSourceViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/EnabledSourceViewHolder.kt index 315571ce..9eed743b 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/EnabledSourceViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/EnabledSourceViewHolder.kt @@ -64,9 +64,11 @@ class EnabledSourceViewHolder : ViewHolder { if (client is JSClient && StatePlatform.instance.hasUpdateAvailable(client.config)) { _textSourceSubtitle.text = itemView.context.getString(R.string.update_available_exclamation) _textSourceSubtitle.setTextColor(itemView.context.getColor(R.color.light_blue_400)) + _textSourceSubtitle.typeface = itemView.resources.getFont(R.font.inter_regular) } else { _textSourceSubtitle.text = itemView.context.getString(R.string.tap_to_open) _textSourceSubtitle.setTextColor(itemView.context.getColor(R.color.gray_ac)) + _textSourceSubtitle.typeface = itemView.resources.getFont(R.font.inter_extra_light) } source = client