diff --git a/app/src/main/java/com/futo/platformplayer/Settings.kt b/app/src/main/java/com/futo/platformplayer/Settings.kt index 38168b5f..5cbfb889 100644 --- a/app/src/main/java/com/futo/platformplayer/Settings.kt +++ b/app/src/main/java/com/futo/platformplayer/Settings.kt @@ -862,10 +862,14 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.clear_payment, FieldForm.BUTTON, R.string.deletes_license_keys_from_app, 2) fun clearPayment() { - StatePayment.instance.clearLicenses(); - SettingsActivity.getActivity()?.let { - UIDialogs.toast(it, it.getString(R.string.licenses_cleared_might_require_app_restart)); - it.reloadSettings(); + SettingsActivity.getActivity()?.let { context -> + UIDialogs.showConfirmationDialog(context, "Are you sure you want to delete your license?", { + StatePayment.instance.clearLicenses(); + SettingsActivity.getActivity()?.let { + UIDialogs.toast(it, it.getString(R.string.licenses_cleared_might_require_app_restart)); + it.reloadSettings(); + } + }) } } } diff --git a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/JSPager.kt b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/JSPager.kt index a7672823..8782b742 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/JSPager.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/JSPager.kt @@ -71,6 +71,8 @@ abstract class JSPager : IPager { warnIfMainThread("JSPager.getResults"); val items = pager.getOrThrow(config, "results", "JSPager"); + if(items.v8Runtime.isDead || items.v8Runtime.isClosed) + throw IllegalStateException("Runtime closed"); val newResults = items.toArray() .map { convertResult(it as V8ValueObject) } .toList(); diff --git a/app/src/main/java/com/futo/platformplayer/dialogs/AutomaticBackupDialog.kt b/app/src/main/java/com/futo/platformplayer/dialogs/AutomaticBackupDialog.kt index 93e6a330..18cb086b 100644 --- a/app/src/main/java/com/futo/platformplayer/dialogs/AutomaticBackupDialog.kt +++ b/app/src/main/java/com/futo/platformplayer/dialogs/AutomaticBackupDialog.kt @@ -22,6 +22,7 @@ class AutomaticBackupDialog(context: Context) : AlertDialog(context) { private lateinit var _buttonCancel: ImageButton; private lateinit var _editPassword: EditText; + private lateinit var _editPassword2: EditText; private lateinit var _inputMethodManager: InputMethodManager; @@ -34,6 +35,7 @@ class AutomaticBackupDialog(context: Context) : AlertDialog(context) { _buttonStop = findViewById(R.id.button_stop); _buttonStart = findViewById(R.id.button_start); _editPassword = findViewById(R.id.edit_password); + _editPassword2 = findViewById(R.id.edit_password2); _inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager; @@ -52,6 +54,13 @@ class AutomaticBackupDialog(context: Context) : AlertDialog(context) { } _buttonStart.setOnClickListener { + val p1 = _editPassword.text.toString(); + val p2 = _editPassword2.text.toString(); + if(!(p1?.equals(p2) ?: false)) { + UIDialogs.toast(context, "Password fields do not match, confirm that you typed it correctly."); + return@setOnClickListener; + } + val pbytes = _editPassword.text.toString().toByteArray(); if(pbytes.size < 4 || pbytes.size > 32) { UIDialogs.toast(context, "Password needs to be atleast 4 bytes long and smaller than 32 bytes", false); diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SubscriptionGroupFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SubscriptionGroupFragment.kt index c1863c64..9fd4d7d6 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SubscriptionGroupFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SubscriptionGroupFragment.kt @@ -253,7 +253,7 @@ class SubscriptionGroupFragment : MainFragment() { if(g.urls.isEmpty() && g.image == null) { //Obtain image for(sub in it) { - val sub = StateSubscriptions.instance.getSubscription(sub); + val sub = StateSubscriptions.instance.getSubscription(sub) ?: StateSubscriptions.instance.getSubscriptionOther(sub); if(sub != null && sub.channel.thumbnail != null) { g.image = ImageVariable.fromUrl(sub.channel.thumbnail!!); g.image?.setImageView(_imageGroup); @@ -308,8 +308,10 @@ class SubscriptionGroupFragment : MainFragment() { if(group != null) { val urls = group.urls.toList(); - val subs = StateSubscriptions.instance.getSubscriptions().map { it.channel } - _enabledCreators.addAll(subs.filter { urls.contains(it.url) }); + val subs = urls.map { + (StateSubscriptions.instance.getSubscription(it) ?: StateSubscriptions.instance.getSubscriptionOther(it))?.channel + }.filterNotNull(); + _enabledCreators.addAll(subs); } updateMeta(); filterCreators(); diff --git a/app/src/main/java/com/futo/platformplayer/helpers/VideoHelper.kt b/app/src/main/java/com/futo/platformplayer/helpers/VideoHelper.kt index 23fa2b73..8b4b5847 100644 --- a/app/src/main/java/com/futo/platformplayer/helpers/VideoHelper.kt +++ b/app/src/main/java/com/futo/platformplayer/helpers/VideoHelper.kt @@ -191,21 +191,21 @@ class VideoHelper { } - fun estimateSourceSize(source: IVideoSource?): Int { + fun estimateSourceSize(source: IVideoSource?): Long { if(source == null) return 0; if(source is IVideoSource) { if(source.bitrate ?: 0 <= 0 || source.duration.toInt() == 0) return 0; - return (source.duration / 8).toInt() * source.bitrate!!; + return (source.duration / 8) * source.bitrate!!; } else return 0; } - fun estimateSourceSize(source: IAudioSource?): Int { + fun estimateSourceSize(source: IAudioSource?): Long { if(source == null) return 0; if(source is IAudioSource) { if(source.bitrate <= 0 || source.duration?.toInt() ?: 0 == 0) return 0; - return (source.duration!! / 8).toInt() * source.bitrate; + return (source.duration!! / 8) * source.bitrate; } else return 0; } diff --git a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt index 416d106a..2b4883da 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt @@ -110,6 +110,15 @@ class StateSubscriptionGroups { } } + fun hasSubscriptionGroup(url: String): Boolean { + val groups = getSubscriptionGroups(); + for(group in groups){ + if(group.urls.contains(url)) + return true; + } + return false; + } + fun getSyncSubscriptionGroupsPackageString(): String{ return Json.encodeToString( diff --git a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt index 8e69d487..5bdc2d8e 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt @@ -202,13 +202,13 @@ class StateSubscriptions { return _subscriptionOthers.findItem { it.isChannel(url)}; } } - fun getSubscriptionOtherOrCreate(url: String) : Subscription { + fun getSubscriptionOtherOrCreate(url: String, name: String? = null, thumbnail: String? = null) : Subscription { synchronized(_subscriptionOthers) { val sub = getSubscriptionOther(url); if(sub == null) { - val newSub = Subscription(SerializedChannel(PlatformID.NONE, url, null, null, 0, null, url, mapOf())); + val newSub = Subscription(SerializedChannel(PlatformID.NONE, name ?: url, thumbnail, null, 0, null, url, mapOf())); newSub.isOther = true; - _subscriptions.save(newSub); + _subscriptionOthers.save(newSub); return newSub; } else return sub; @@ -295,6 +295,9 @@ class StateSubscriptions { onSubscriptionsChanged.emit(getSubscriptions(), false); if(isUserAction) _subscriptionsRemoved.setAndSave(sub.channel.url, OffsetDateTime.now()); + + if(StateSubscriptionGroups.instance.hasSubscriptionGroup(sub.channel.url)) + getSubscriptionOtherOrCreate(sub.channel.url, sub.channel.name, sub.channel.thumbnail); } return sub; } diff --git a/app/src/main/res/layout/dialog_automatic_backup.xml b/app/src/main/res/layout/dialog_automatic_backup.xml index 3804866b..1f570c4b 100644 --- a/app/src/main/res/layout/dialog_automatic_backup.xml +++ b/app/src/main/res/layout/dialog_automatic_backup.xml @@ -71,6 +71,16 @@ android:singleLine="true" android:inputType="textPassword" android:hint="@string/backup_password" /> + Set a password for your daily backup Set a password used to encrypt your daily backup that is written to external storage. Backup Password + Repeat Password Restore from Automatic Backup It appears an automatic backup exists on your device, if you would like to restore, enter your backup password. Restore