From 75eb7359dead28967517673ff92d8a020c7d78bc Mon Sep 17 00:00:00 2001 From: Kelvin Date: Wed, 12 Nov 2025 23:55:44 +0100 Subject: [PATCH] Fix various ref to old activity settings --- .../java/com/futo/platformplayer/Settings.kt | 68 +++--- .../com/futo/platformplayer/SettingsDev.kt | 28 +-- .../futo/platformplayer/UISlideOverlays.kt | 14 +- .../activities/DeveloperActivity.kt | 58 ----- .../activities/SettingsActivity.kt | 208 ------------------ .../bottombar/MenuBottomBarFragment.kt | 1 - .../mainactivity/main/DeveloperFragment.kt | 50 +---- .../mainactivity/main/SettingsFragment.kt | 54 ++--- .../mainactivity/main/VideoDetailFragment.kt | 6 +- .../futo/platformplayer/states/StateApp.kt | 13 +- .../futo/platformplayer/states/StateBackup.kt | 7 +- 11 files changed, 92 insertions(+), 415 deletions(-) delete mode 100644 app/src/main/java/com/futo/platformplayer/activities/DeveloperActivity.kt delete mode 100644 app/src/main/java/com/futo/platformplayer/activities/SettingsActivity.kt diff --git a/app/src/main/java/com/futo/platformplayer/Settings.kt b/app/src/main/java/com/futo/platformplayer/Settings.kt index 4068505c..90ac51bb 100644 --- a/app/src/main/java/com/futo/platformplayer/Settings.kt +++ b/app/src/main/java/com/futo/platformplayer/Settings.kt @@ -10,11 +10,11 @@ import com.futo.platformplayer.activities.MainActivity import com.futo.platformplayer.activities.ManageTabsActivity import com.futo.platformplayer.activities.PolycentricHomeActivity import com.futo.platformplayer.activities.PolycentricProfileActivity -import com.futo.platformplayer.activities.SettingsActivity import com.futo.platformplayer.activities.SyncHomeActivity import com.futo.platformplayer.api.http.ManagedHttpClient import com.futo.platformplayer.constructs.Event0 import com.futo.platformplayer.fragment.mainactivity.bottombar.MenuBottomBarFragment +import com.futo.platformplayer.fragment.mainactivity.main.SettingsFragment import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.serializers.FlexibleBooleanSerializer import com.futo.platformplayer.serializers.OffsetDateTimeSerializer @@ -42,7 +42,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.serialization.Serializable import kotlinx.serialization.Transient -import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import java.io.File import java.time.OffsetDateTime @@ -64,7 +63,7 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.sync_grayjay, FieldForm.BUTTON, R.string.sync_grayjay_description, -8) @FormFieldButton(R.drawable.ic_update) fun syncGrayjay() { - SettingsActivity.getActivity()?.let { + StateApp?.instance?.activity?.let { it.startActivity(Intent(it, SyncHomeActivity::class.java)) } } @@ -73,7 +72,7 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.manage_polycentric_identity, FieldForm.BUTTON, R.string.manage_your_polycentric_identity, -7) @FormFieldButton(R.drawable.ic_person) fun managePolycentricIdentity() { - SettingsActivity.getActivity()?.let { + StateApp?.instance?.activity?.let { if (StatePolycentric.instance.enabled) { if (StatePolycentric.instance.processHandle != null) { it.startActivity(Intent(it, PolycentricProfileActivity::class.java)); @@ -91,7 +90,7 @@ class Settings : FragmentedStorageFileJson() { fun openFAQ() { try { val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(Settings.URL_FAQ)) - SettingsActivity.getActivity()?.startActivity(browserIntent); + StateApp?.instance?.activity?.startActivity(browserIntent); } catch (e: Throwable) { //Ignored } @@ -101,7 +100,7 @@ class Settings : FragmentedStorageFileJson() { fun openIssues() { try { val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/futo-org/grayjay-android/issues")) - SettingsActivity.getActivity()?.startActivity(browserIntent); + StateApp?.instance?.activity?.startActivity(browserIntent); } catch (e: Throwable) { //Ignored } @@ -132,7 +131,7 @@ class Settings : FragmentedStorageFileJson() { @FormFieldButton(R.drawable.ic_tabs) fun manageTabs() { try { - SettingsActivity.getActivity()?.let { + StateApp?.instance?.activity?.let { it.startActivity(Intent(it, ManageTabsActivity::class.java)); } } catch (e: Throwable) { @@ -145,7 +144,7 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.import_data, FieldForm.BUTTON, R.string.import_data_description, -3) @FormFieldButton(R.drawable.ic_move_up) fun import() { - val act = SettingsActivity.getActivity() ?: return; + val act = StateApp.instance.activity ?: return; val intent = MainActivity.getImportOptionsIntent(act); act.startActivity(intent); } @@ -154,7 +153,7 @@ class Settings : FragmentedStorageFileJson() { @FormFieldButton(R.drawable.ic_link) fun manageLinks() { try { - SettingsActivity.getActivity()?.let { UIDialogs.showUrlHandlingPrompt(it) } + StateApp.instance.activity?.let { UIDialogs.showUrlHandlingPrompt(it) } } catch (e: Throwable) { Logger.e(TAG, "Failed to show url handling prompt", e) } @@ -163,7 +162,7 @@ class Settings : FragmentedStorageFileJson() { /*@FormField(R.string.disable_battery_optimization, FieldForm.BUTTON, R.string.click_to_go_to_battery_optimization_settings_disabling_battery_optimization_will_prevent_the_os_from_killing_media_sessions, -1) @FormFieldButton(R.drawable.battery_full_24px) fun ignoreBatteryOptimization() { - SettingsActivity.getActivity()?.let { + StateApp.instance.activity?.let { val intent = Intent() val packageName = it.packageName val pm = it.getSystemService(POWER_SERVICE) as PowerManager; @@ -244,7 +243,7 @@ class Settings : FragmentedStorageFileJson() { fun clearHidden() { StateMeta.instance.removeAllHiddenCreators(); StateMeta.instance.removeAllHiddenVideos(); - SettingsActivity.getActivity()?.let { + StateApp.instance.activity?.let { UIDialogs.toast(it, "Creators and videos should show up again"); } } @@ -374,9 +373,9 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.clear_channel_cache, FieldForm.BUTTON, R.string.clear_channel_cache_description, 16) fun clearChannelCache() { - UIDialogs.toast(SettingsActivity.getActivity()!!, "Started clearing.."); + UIDialogs.toast(StateApp.instance.activity!!, "Started clearing.."); StateCache.instance.clear(); - UIDialogs.toast(SettingsActivity.getActivity()!!, "Finished clearing"); + UIDialogs.toast(StateApp.instance.activity!!, "Finished clearing"); } } @@ -760,7 +759,7 @@ class Settings : FragmentedStorageFileJson() { try { if (!Logger.submitLogs()) { withContext(Dispatchers.Main) { - SettingsActivity.getActivity()?.let { UIDialogs.toast(it, it.getString(R.string.please_enable_logging_to_submit_logs)) } + StateApp.instance.activity?.let { UIDialogs.toast(it, it.getString(R.string.please_enable_logging_to_submit_logs)) } } } } catch (e: Throwable) { @@ -777,7 +776,7 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.reset_announcements, FieldForm.BUTTON, R.string.reset_hidden_announcements, 1) fun resetAnnouncements() { StateAnnouncement.instance.resetAnnouncements(); - SettingsActivity.getActivity()?.let { UIDialogs.toast(it, it.getString(R.string.announcements_reset)); }; + StateApp.instance.activity?.let { UIDialogs.toast(it, it.getString(R.string.announcements_reset)); }; } } @@ -845,13 +844,13 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.change_external_general_directory, FieldForm.BUTTON, R.string.change_the_external_directory_for_general_files, 3) fun changeStorageGeneral() { - SettingsActivity.getActivity()?.let { + StateApp.instance.activity?.let { StateApp.instance.changeExternalGeneralDirectory(it); } } @FormField(R.string.change_external_downloads_directory, FieldForm.BUTTON, R.string.change_the_external_storage_for_download_files, 4) fun changeStorageDownload() { - SettingsActivity.getActivity()?.let { + StateApp.instance.activity?.let { StateApp.instance.changeExternalDownloadDirectory(it); } } @@ -860,7 +859,7 @@ class Settings : FragmentedStorageFileJson() { fun clearStorageDownload() { Settings.instance.storage.storage_download = null; Settings.instance.save(); - SettingsActivity.getActivity()?.let { UIDialogs.toast(it, "Cleared download storage directory") }; + StateApp.instance.activity?.let { UIDialogs.toast(it, "Cleared download storage directory") }; } } @@ -897,13 +896,13 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.manual_check, FieldForm.BUTTON, R.string.manually_check_for_updates, 3) fun manualCheck() { if (!BuildConfig.IS_PLAYSTORE_BUILD) { - SettingsActivity.getActivity()?.let { + StateApp.instance.activity?.let { StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { StateUpdate.instance.checkForUpdates(it, true) } } } else { - SettingsActivity.getActivity()?.let { + StateApp.instance.activity?.let { try { it.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=${it.packageName}"))) } catch (e: ActivityNotFoundException) { @@ -915,7 +914,7 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.view_changelog, FieldForm.BUTTON, R.string.review_the_current_and_past_changelogs, 4) fun viewChangelog() { - SettingsActivity.getActivity()?.let { + StateApp.instance.activity?.let { UIDialogs.toast(it.getString(R.string.retrieving_changelog)); StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { @@ -964,13 +963,13 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.set_automatic_backup, FieldForm.BUTTON, R.string.configure_daily_backup_in_case_of_catastrophic_failure, 1) fun configureAutomaticBackup() { - UIDialogs.showAutomaticBackupDialog(SettingsActivity.getActivity()!!, autoBackupPassword != null) { - SettingsActivity.getActivity()?.reloadSettings(); + UIDialogs.showAutomaticBackupDialog(StateApp.instance.activity!!, autoBackupPassword != null) { + SettingsFragment.currentView?.reloadSettings(); }; } @FormField(R.string.restore_automatic_backup, FieldForm.BUTTON, R.string.restore_a_previous_automatic_backup, 2) fun restoreAutomaticBackup() { - val activity = SettingsActivity.getActivity()!! + val activity = StateApp.instance.activity!! if(!StateBackup.hasAutomaticBackup()) UIDialogs.toast(activity, activity.getString(R.string.you_don_t_have_any_automatic_backups), false); @@ -981,8 +980,9 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.export_data, FieldForm.BUTTON, R.string.creates_a_zip_file_with_your_data_which_can_be_imported_by_opening_it_with_grayjay, 3) fun export() { - val activity = SettingsActivity.getActivity() ?: return; - UISlideOverlays.showOverlay(activity.overlay, "Select export type", null, {}, + val activity = StateApp.instance.activity ?: return; + val fragView = SettingsFragment.currentView ?: return; + UISlideOverlays.showOverlay(fragView.overlay, "Select export type", null, {}, SlideUpMenuItem(activity, R.drawable.ic_share, "Share", "", tag = null, call = { StateBackup.shareExternalBackup(); }), @@ -998,11 +998,11 @@ class Settings : FragmentedStorageFileJson() { @Serializable class Payment { @FormField(R.string.payment_status, FieldForm.READONLYTEXT, -1, 1) - val paymentStatus: String get() = SettingsActivity.getActivity()?.let { if (StatePayment.instance.hasPaid) it.getString(R.string.paid) else it.getString(R.string.not_paid); } ?: "Unknown"; + val paymentStatus: String get() = StateApp.instance.activity?.let { if (StatePayment.instance.hasPaid) it.getString(R.string.paid) else it.getString(R.string.not_paid); } ?: "Unknown"; @FormField(R.string.license_status, FieldForm.BUTTON, R.string.view_license_status, 2) fun viewLicenseStatus() { - SettingsActivity.getActivity()?.let { + StateApp.instance.activity?.let { try { if (StatePayment.instance.hasPaid) { val paymentKey = StatePayment.instance.getPaymentKey() @@ -1018,12 +1018,12 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.clear_payment, FieldForm.BUTTON, R.string.deletes_license_keys_from_app, 3) fun clearPayment() { - SettingsActivity.getActivity()?.let { context -> + StateApp.instance.activity?.let { context -> UIDialogs.showConfirmationDialog(context, "Are you sure you want to delete your license?", { StatePayment.instance.clearLicenses(); - SettingsActivity.getActivity()?.let { + StateApp.instance.activity?.let { UIDialogs.toast(it, it.getString(R.string.licenses_cleared_might_require_app_restart)); - it.reloadSettings(); + SettingsFragment.currentView?.reloadSettings(); } }) } @@ -1120,7 +1120,7 @@ class Settings : FragmentedStorageFileJson() { @AdvancedField @FormField(R.string.configure_sync_server, FieldForm.BUTTON, R.string.configure_sync_server_description, 7) fun configureSyncServer() { - SettingsActivity.getActivity()?.let { context -> + StateApp.instance.activity?.let { context -> UIDialogs.showDialog(context, R.drawable.device_sync, false, "Enter the url to your relay server", "Using your own relay server requires a proper setup with portforwarding.\nUse at your own risk.", @@ -1131,13 +1131,13 @@ class Settings : FragmentedStorageFileJson() { UIDialogs.Action("Reset", { syncServerUrl = null; instance.save(); - context.reloadSettings(); + SettingsFragment.currentView?.reloadSettings(); UIDialogs.toast("Sync server changes require a restart"); }, UIDialogs.ActionStyle.ACCENT), UIDialogs.Action.withInput("Configure", { syncServerUrl = it?.text instance.save(); - context.reloadSettings(); + SettingsFragment.currentView?.reloadSettings(); UIDialogs.toast("Sync server changes require a restart"); }, UIDialogs.ActionStyle.PRIMARY), ) diff --git a/app/src/main/java/com/futo/platformplayer/SettingsDev.kt b/app/src/main/java/com/futo/platformplayer/SettingsDev.kt index d79c5b3b..13074c31 100644 --- a/app/src/main/java/com/futo/platformplayer/SettingsDev.kt +++ b/app/src/main/java/com/futo/platformplayer/SettingsDev.kt @@ -8,9 +8,7 @@ import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import com.caoccao.javet.values.primitive.V8ValueInteger import com.caoccao.javet.values.primitive.V8ValueString -import com.futo.platformplayer.activities.DeveloperActivity import com.futo.platformplayer.activities.MainActivity -import com.futo.platformplayer.activities.SettingsActivity import com.futo.platformplayer.api.http.ManagedHttpClient import com.futo.platformplayer.api.media.models.contents.IPlatformContent import com.futo.platformplayer.api.media.models.video.IPlatformVideo @@ -20,6 +18,8 @@ import com.futo.platformplayer.api.media.platforms.js.SourcePluginDescriptor import com.futo.platformplayer.api.media.structures.IPager import com.futo.platformplayer.background.BackgroundWorker import com.futo.platformplayer.engine.V8Plugin +import com.futo.platformplayer.fragment.mainactivity.main.DeveloperFragment +import com.futo.platformplayer.fragment.mainactivity.main.SettingsFragment import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.serializers.FlexibleBooleanSerializer import com.futo.platformplayer.states.StateAnnouncement @@ -97,10 +97,10 @@ class SettingsDev : FragmentedStorageFileJson() { fun subscriptionsCache5000() { Logger.i("SettingsDev", "Started caching 5000 sub items"); UIDialogs.toast( - SettingsActivity.getActivity()!!, + StateApp.instance.activity!!, "Started caching 5000 sub items" ); - val button = DeveloperActivity.getActivity()?.getField("subscription_cache_button"); + val button = DeveloperFragment.currentView?.getField("subscription_cache_button"); if(button is ButtonField) button.setButtonEnabled(false); StateApp.instance.scope.launch(Dispatchers.IO) { @@ -121,7 +121,7 @@ class SettingsDev : FragmentedStorageFileJson() { val diff = System.currentTimeMillis() - lastToast; lastToast = System.currentTimeMillis(); UIDialogs.toast( - SettingsActivity.getActivity()!!, + StateApp.instance.activity!!, "Page: ${page}, Total: ${total}, Speed: ${diff}ms" ); } @@ -130,7 +130,7 @@ class SettingsDev : FragmentedStorageFileJson() { withContext(Dispatchers.Main) { UIDialogs.toast( - SettingsActivity.getActivity()!!, + StateApp.instance.activity!!, "FINISHED Page: ${page}, Total: ${total}" ); } @@ -152,10 +152,10 @@ class SettingsDev : FragmentedStorageFileJson() { fun historyCache100() { Logger.i("SettingsDev", "Started caching 100 history items (from home)"); UIDialogs.toast( - SettingsActivity.getActivity()!!, + StateApp.instance.activity!!, "Started caching 100 history items (from home)" ); - val button = DeveloperActivity.getActivity()?.getField("history_cache_button"); + val button = DeveloperFragment.currentView?.getField("history_cache_button"); if(button is ButtonField) button.setButtonEnabled(false); StateApp.instance.scope.launch(Dispatchers.IO) { @@ -186,7 +186,7 @@ class SettingsDev : FragmentedStorageFileJson() { val diff = System.currentTimeMillis() - lastToast; lastToast = System.currentTimeMillis(); UIDialogs.toast( - SettingsActivity.getActivity()!!, + StateApp.instance.activity!!, "Page: ${page}, Total: ${total}, Speed: ${diff}ms" ); } @@ -195,7 +195,7 @@ class SettingsDev : FragmentedStorageFileJson() { withContext(Dispatchers.Main) { UIDialogs.toast( - SettingsActivity.getActivity()!!, + StateApp.instance.activity!!, "FINISHED Page: ${page}, Total: ${total}" ); } @@ -235,9 +235,9 @@ class SettingsDev : FragmentedStorageFileJson() { @FormField(R.string.test_background_worker, FieldForm.BUTTON, R.string.test_background_worker_description, 4) fun triggerBackgroundUpdate() { - val act = SettingsActivity.getActivity()!!; + val act = StateApp.instance.activity!!; try { - UIDialogs.toast(SettingsActivity.getActivity()!!, "Starting test background worker"); + UIDialogs.toast(StateApp.instance.activity!!, "Starting test background worker"); val wm = WorkManager.getInstance(act); val req = OneTimeWorkRequestBuilder() @@ -251,9 +251,9 @@ class SettingsDev : FragmentedStorageFileJson() { @FormField(R.string.clear_channel_cache, FieldForm.BUTTON, R.string.test_background_worker_description, 4) fun clearChannelContentCache() { - UIDialogs.toast(SettingsActivity.getActivity()!!, "Clearing cache"); + UIDialogs.toast(StateApp.instance.activity!!, "Clearing cache"); StateCache.instance.clearToday(); - UIDialogs.toast(SettingsActivity.getActivity()!!, "Cleared"); + UIDialogs.toast(StateApp.instance.activity!!, "Cleared"); } diff --git a/app/src/main/java/com/futo/platformplayer/UISlideOverlays.kt b/app/src/main/java/com/futo/platformplayer/UISlideOverlays.kt index 409adbf5..75681154 100644 --- a/app/src/main/java/com/futo/platformplayer/UISlideOverlays.kt +++ b/app/src/main/java/com/futo/platformplayer/UISlideOverlays.kt @@ -14,7 +14,6 @@ import androidx.media3.exoplayer.hls.playlist.HlsMediaPlaylist import androidx.media3.exoplayer.hls.playlist.HlsMultivariantPlaylist import androidx.recyclerview.widget.RecyclerView import com.futo.platformplayer.activities.MainActivity -import com.futo.platformplayer.activities.SettingsActivity import com.futo.platformplayer.api.http.ManagedHttpClient import com.futo.platformplayer.api.media.models.ResultCapabilities import com.futo.platformplayer.api.media.models.channels.IPlatformChannel @@ -74,6 +73,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.ByteArrayInputStream import androidx.core.net.toUri +import com.futo.platformplayer.fragment.mainactivity.main.SettingsFragment class UISlideOverlays { companion object { @@ -331,15 +331,9 @@ class UISlideOverlays { 0, UIDialogs.Action("Cancel", {}), UIDialogs.Action("Configure", { - val intent = Intent( - mainContext, - SettingsActivity::class.java - ); - intent.putExtra( - "query", - mainContext.getString(R.string.background_update) - ); - mainContext.startActivity(intent); + StateApp.instance.activity?.let { + it.navigate(it.getFragment(), mainContext.getString(R.string.background_update)) + } }, UIDialogs.ActionStyle.PRIMARY) ); } diff --git a/app/src/main/java/com/futo/platformplayer/activities/DeveloperActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/DeveloperActivity.kt deleted file mode 100644 index b8dbb261..00000000 --- a/app/src/main/java/com/futo/platformplayer/activities/DeveloperActivity.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.futo.platformplayer.activities - -import android.annotation.SuppressLint -import android.os.Bundle -import android.widget.ImageButton -import androidx.appcompat.app.AppCompatActivity -import com.futo.platformplayer.* -import com.futo.platformplayer.views.fields.FieldForm -import com.futo.platformplayer.views.fields.IField - -class DeveloperActivity : AppCompatActivity() { - private lateinit var _form: FieldForm; - private lateinit var _buttonBack: ImageButton; - - fun getField(id: String): IField? { - return _form.findField(id); - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState); - DeveloperActivity._lastActivity = this; - setContentView(R.layout.activity_dev); - setNavigationBarColorAndIcons(); - - _buttonBack = findViewById(R.id.button_back); - _form = findViewById(R.id.settings_form); - - _form.fromObject(SettingsDev.instance); - _form.onChanged.subscribe { _, _ -> - _form.setObjectValues(); - SettingsDev.instance.save(); - }; - - _buttonBack.setOnClickListener { - finish(); - } - } - - override fun finish() { - super.finish() - overridePendingTransition(R.anim.slide_lighten, R.anim.slide_out_up) - } - - - - companion object { - //TODO: Temporary for solving Settings issues - @SuppressLint("StaticFieldLeak") - private var _lastActivity: DeveloperActivity? = null; - - fun getActivity(): DeveloperActivity? { - val act = _lastActivity; - if(act != null) - return act; - return null; - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/activities/SettingsActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/SettingsActivity.kt deleted file mode 100644 index f7513f6e..00000000 --- a/app/src/main/java/com/futo/platformplayer/activities/SettingsActivity.kt +++ /dev/null @@ -1,208 +0,0 @@ -package com.futo.platformplayer.activities - -import android.annotation.SuppressLint -import android.app.NotificationManager -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import android.os.Bundle -import android.view.View -import android.widget.FrameLayout -import android.widget.ImageButton -import android.widget.LinearLayout -import androidx.activity.result.ActivityResult -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts -import androidx.appcompat.app.AppCompatActivity -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat -import androidx.lifecycle.lifecycleScope -import com.futo.platformplayer.* -import com.futo.platformplayer.constructs.Event0 -import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.states.StateApp -import com.futo.platformplayer.views.LoaderView -import com.futo.platformplayer.views.fields.FieldForm -import com.futo.platformplayer.views.fields.ReadOnlyTextField -import com.google.android.material.button.MaterialButton - -class SettingsActivity : AppCompatActivity(), IWithResultLauncher { - private lateinit var _form: FieldForm; - private lateinit var _buttonBack: ImageButton; - private lateinit var _loaderView: LoaderView; - - private lateinit var _devSets: LinearLayout; - private lateinit var _buttonDev: MaterialButton; - - private var _isFinished = false; - - lateinit var overlay: FrameLayout; - - val notifPermission = "android.permission.POST_NOTIFICATIONS"; - val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean -> - if (isGranted) - UIDialogs.toast(this, "Notification permission granted"); - else - UIDialogs.toast(this, "Notification permission denied"); - } - - override fun attachBaseContext(newBase: Context?) { - Logger.i("SettingsActivity", "SettingsActivity.attachBaseContext") - super.attachBaseContext(StateApp.instance.getLocaleContext(newBase)) - } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_settings); - setNavigationBarColorAndIcons(); - - _form = findViewById(R.id.settings_form); - _buttonBack = findViewById(R.id.button_back); - _buttonDev = findViewById(R.id.button_dev); - _devSets = findViewById(R.id.dev_settings); - _loaderView = findViewById(R.id.loader); - overlay = findViewById(R.id.overlay_container); - - _form.onChanged.subscribe { field, _ -> - Logger.i("SettingsActivity", "Setting [${field.field?.name}] changed, saving"); - _form.setObjectValues(); - Settings.instance.save(); - - if(field.descriptor?.id == "app_language") { - Logger.i("SettingsActivity", "App language change detected, propogating to shared preferences"); - StateApp.instance.setLocaleSetting(this, Settings.instance.language.getAppLanguageLocaleString()); - } - - if(field.descriptor?.id == "background_update") { - Logger.i("SettingsActivity", "Detected change in background work ${field.value}"); - if(Settings.instance.subscriptions.subscriptionsBackgroundUpdateInterval > 0) { - val notifManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager; - if(!notifManager.areNotificationsEnabled()) { - UIDialogs.toast(this, "Notifications aren't enabled"); - - when { - ContextCompat.checkSelfPermission(this, notifPermission) == PackageManager.PERMISSION_GRANTED -> { - - } - ActivityCompat.shouldShowRequestPermissionRationale(this, notifPermission) -> { - UIDialogs.showDialog(this, R.drawable.ic_notifications, "Notifications Required", - "Notifications need to be enabled for background updating to function", null, 0, - UIDialogs.Action("Cancel", {}), - UIDialogs.Action("Enable", { - requestPermissionLauncher.launch(notifPermission); - }, UIDialogs.ActionStyle.PRIMARY)); - } - else -> { - requestPermissionLauncher.launch(notifPermission); - } - } - } - } - } - }; - _buttonBack.setOnClickListener { - finish(); - } - - _buttonDev.setOnClickListener { - startActivity(Intent(this, DeveloperActivity::class.java)); - } - - _lastActivity = this; - - reloadSettings(); - } - - var isFirstLoad = true; - fun reloadSettings() { - val firstLoad = isFirstLoad; - isFirstLoad = false; - _form.setSearchVisible(false); - _loaderView.start(); - _form.fromObject(lifecycleScope, Settings.instance) { - _loaderView.stop(); - _form.setSearchVisible(true); - - var devCounter = 0; - _form.findField("code")?.assume()?.setOnClickListener { - devCounter++; - if(devCounter > 5) { - devCounter = 0; - SettingsDev.instance.developerMode = true; - SettingsDev.instance.save(); - updateDevMode(); - UIDialogs.toast(this, getString(R.string.you_are_now_in_developer_mode)); - } - }; - - if(firstLoad) { - val query = intent.getStringExtra("query"); - if(!query.isNullOrEmpty()) { - _form.setSearchQuery(query); - } - } - }; - } - - override fun onResume() { - super.onResume() - updateDevMode(); - } - - fun updateDevMode() { - if(SettingsDev.instance.developerMode) - _devSets.visibility = View.VISIBLE; - else - _devSets.visibility = View.GONE; - } - - override fun finish() { - super.finish() - _isFinished = true; - if(_lastActivity == this) - _lastActivity = null; - overridePendingTransition(R.anim.slide_lighten, R.anim.slide_out_up) - } - - - - - private var resultLauncherMap = mutableMapOfUnit>(); - private var requestCode: Int? = -1; - private val resultLauncher: ActivityResultLauncher = registerForActivityResult( - ActivityResultContracts.StartActivityForResult()) { - result: ActivityResult -> - val handler = synchronized(resultLauncherMap) { - resultLauncherMap.remove(requestCode); - } - if(handler != null) - handler(result); - }; - override fun launchForResult(intent: Intent, code: Int, handler: (ActivityResult)->Unit) { - synchronized(resultLauncherMap) { - resultLauncherMap[code] = handler; - } - requestCode = code; - resultLauncher.launch(intent); - } - - override fun onDestroy() { - super.onDestroy() - settingsActivityClosed.emit() - } - - - companion object { - //TODO: Temporary for solving Settings issues - @SuppressLint("StaticFieldLeak") - private var _lastActivity: SettingsActivity? = null; - - val settingsActivityClosed = Event0() - - fun getActivity(): SettingsActivity? { - val act = _lastActivity; - if(act != null && !act._isFinished) - return act; - return null; - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/bottombar/MenuBottomBarFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/bottombar/MenuBottomBarFragment.kt index b26988bd..d9c9c1b5 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/bottombar/MenuBottomBarFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/bottombar/MenuBottomBarFragment.kt @@ -20,7 +20,6 @@ import com.futo.platformplayer.R import com.futo.platformplayer.Settings import com.futo.platformplayer.UIDialogs import com.futo.platformplayer.activities.MainActivity -import com.futo.platformplayer.activities.SettingsActivity import com.futo.platformplayer.dp import com.futo.platformplayer.fragment.mainactivity.MainActivityFragment import com.futo.platformplayer.fragment.mainactivity.main.* diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/DeveloperFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/DeveloperFragment.kt index 29b17301..095a09be 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/DeveloperFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/DeveloperFragment.kt @@ -1,62 +1,18 @@ package com.futo.platformplayer.fragment.mainactivity.main -import android.app.NotificationManager -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager import android.os.Bundle -import android.provider.MediaStore -import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageButton import android.widget.LinearLayout -import android.widget.TextView -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts import androidx.constraintlayout.widget.ConstraintLayout -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat import androidx.core.view.isVisible -import androidx.core.view.updateLayoutParams -import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.RecyclerView import com.futo.platformplayer.R -import com.futo.platformplayer.Settings import com.futo.platformplayer.SettingsDev -import com.futo.platformplayer.UIDialogs -import com.futo.platformplayer.activities.DeveloperActivity -import com.futo.platformplayer.activities.MainActivity -import com.futo.platformplayer.api.media.models.contents.IPlatformContent -import com.futo.platformplayer.api.media.models.video.IPlatformVideo -import com.futo.platformplayer.assume -import com.futo.platformplayer.dp -import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.states.Album -import com.futo.platformplayer.states.Artist -import com.futo.platformplayer.states.ArtistOrdering -import com.futo.platformplayer.states.FileEntry -import com.futo.platformplayer.states.StateApp -import com.futo.platformplayer.states.StateLibrary -import com.futo.platformplayer.views.AnyAdapterView.Companion.asAny -import com.futo.platformplayer.views.AnyInsertedAdapterView -import com.futo.platformplayer.views.AnyInsertedAdapterView.Companion.asAnyWithTop -import com.futo.platformplayer.views.AnyInsertedAdapterView.Companion.asAnyWithViews -import com.futo.platformplayer.views.LibrarySection -import com.futo.platformplayer.views.LoaderView -import com.futo.platformplayer.views.adapters.AnyAdapter -import com.futo.platformplayer.views.adapters.InsertedViewAdapter -import com.futo.platformplayer.views.adapters.viewholders.AlbumTileViewHolder -import com.futo.platformplayer.views.adapters.viewholders.ArtistTileViewHolder -import com.futo.platformplayer.views.adapters.viewholders.FileViewHolder -import com.futo.platformplayer.views.adapters.viewholders.LocalVideoTileViewHolder -import com.futo.platformplayer.views.buttons.BigButton import com.futo.platformplayer.views.fields.FieldForm import com.futo.platformplayer.views.fields.IField -import com.futo.platformplayer.views.fields.ReadOnlyTextField -import com.google.android.material.button.MaterialButton class DeveloperFragment : MainFragment() { @@ -70,6 +26,7 @@ class DeveloperFragment : MainFragment() { override fun onCreateMainView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { val newView = FragView(this); view = newView; + _currentView = view; return newView; } @@ -80,11 +37,16 @@ class DeveloperFragment : MainFragment() { override fun onDestroyMainView() { view = null; + _currentView = null; super.onDestroyMainView(); } companion object { fun newInstance() = DeveloperFragment().apply {} + + private var _currentView: FragView? = null; + val currentView: FragView? + get() = _currentView; } diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SettingsFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SettingsFragment.kt index eff9dfd9..4dd03fc4 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SettingsFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SettingsFragment.kt @@ -2,57 +2,26 @@ package com.futo.platformplayer.fragment.mainactivity.main import android.app.NotificationManager import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager import android.os.Bundle -import android.provider.MediaStore -import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageButton import android.widget.LinearLayout -import android.widget.TextView -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts import androidx.constraintlayout.widget.ConstraintLayout -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat import androidx.core.view.isVisible -import androidx.core.view.updateLayoutParams import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.RecyclerView import com.futo.platformplayer.R import com.futo.platformplayer.Settings import com.futo.platformplayer.SettingsDev import com.futo.platformplayer.UIDialogs -import com.futo.platformplayer.activities.DeveloperActivity import com.futo.platformplayer.activities.MainActivity -import com.futo.platformplayer.api.media.models.contents.IPlatformContent -import com.futo.platformplayer.api.media.models.video.IPlatformVideo import com.futo.platformplayer.assume -import com.futo.platformplayer.dp +import com.futo.platformplayer.constructs.Event0 import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.states.Album -import com.futo.platformplayer.states.Artist -import com.futo.platformplayer.states.ArtistOrdering -import com.futo.platformplayer.states.FileEntry import com.futo.platformplayer.states.StateApp -import com.futo.platformplayer.states.StateLibrary -import com.futo.platformplayer.views.AnyAdapterView.Companion.asAny -import com.futo.platformplayer.views.AnyInsertedAdapterView -import com.futo.platformplayer.views.AnyInsertedAdapterView.Companion.asAnyWithTop -import com.futo.platformplayer.views.AnyInsertedAdapterView.Companion.asAnyWithViews -import com.futo.platformplayer.views.LibrarySection import com.futo.platformplayer.views.LoaderView -import com.futo.platformplayer.views.adapters.AnyAdapter -import com.futo.platformplayer.views.adapters.InsertedViewAdapter -import com.futo.platformplayer.views.adapters.viewholders.AlbumTileViewHolder -import com.futo.platformplayer.views.adapters.viewholders.ArtistTileViewHolder -import com.futo.platformplayer.views.adapters.viewholders.FileViewHolder -import com.futo.platformplayer.views.adapters.viewholders.LocalVideoTileViewHolder -import com.futo.platformplayer.views.buttons.BigButton import com.futo.platformplayer.views.fields.FieldForm import com.futo.platformplayer.views.fields.ReadOnlyTextField import com.google.android.material.button.MaterialButton @@ -65,7 +34,6 @@ class SettingsFragment : MainFragment() { private var view: FragView? = null; - override fun onCreateMainView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): android.view.View { val newView = FragView(this); view = newView; @@ -74,16 +42,30 @@ class SettingsFragment : MainFragment() { override fun onShownWithView(parameter: Any?, isBack: Boolean) { super.onShownWithView(parameter, isBack); - view?.onShown(); + _currentView = view; + view?.onShown(parameter); + } + + override fun onHide() { + super.onHide(); + onClosed.emit(); } override fun onDestroyMainView() { view = null; + _currentView = null; super.onDestroyMainView(); } companion object { fun newInstance() = SettingsFragment().apply {} + + val onClosed = Event0(); + + private var _currentView: FragView? = null; + val currentView: FragView? + get() = _currentView; + } @@ -185,8 +167,10 @@ class SettingsFragment : MainFragment() { } - fun onShown() { + fun onShown(str: Any? = null) { updateDevMode(); + if(str is String) + _form.setSearchQuery(str); } fun updateDevMode() { diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailFragment.kt index af228bf7..cbcbce73 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailFragment.kt @@ -24,7 +24,6 @@ import androidx.media3.common.util.UnstableApi import com.futo.platformplayer.R import com.futo.platformplayer.Settings import com.futo.platformplayer.UIDialogs -import com.futo.platformplayer.activities.SettingsActivity import com.futo.platformplayer.api.media.models.video.IPlatformVideo import com.futo.platformplayer.api.media.models.video.IPlatformVideoDetails import com.futo.platformplayer.casting.StateCasting @@ -401,9 +400,10 @@ class VideoDetailFragment() : MainFragment() { _loadUrlOnCreate?.let { _viewDetail?.setVideo(it.url, it.timeSeconds, it.playWhenReady) }; maximizeVideoDetail(); + /* SettingsActivity.settingsActivityClosed.subscribe(this) { updateOrientation() - } + } */ StatePlayer.instance.onRotationLockChanged.subscribe(this) { updateOrientation() @@ -547,7 +547,7 @@ class VideoDetailFragment() : MainFragment() { super.onDestroyMainView(); Logger.v(TAG, "onDestroyMainView"); - SettingsActivity.settingsActivityClosed.remove(this) + //SettingsActivity.settingsActivityClosed.remove(this) StatePlayer.instance.onRotationLockChanged.remove(this) _landscapeOrientationListener?.disableListener() 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 2e8653d8..4116a682 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateApp.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateApp.kt @@ -28,8 +28,6 @@ import com.futo.platformplayer.UIDialogs.Companion.showDialog import com.futo.platformplayer.activities.CaptchaActivity import com.futo.platformplayer.activities.IWithResultLauncher import com.futo.platformplayer.activities.MainActivity -import com.futo.platformplayer.activities.SettingsActivity -import com.futo.platformplayer.activities.SettingsActivity.Companion.settingsActivityClosed import com.futo.platformplayer.api.media.platforms.js.DevJSClient import com.futo.platformplayer.api.media.platforms.js.JSClient import com.futo.platformplayer.background.BackgroundWorker @@ -38,6 +36,7 @@ import com.futo.platformplayer.constructs.Event0 import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.engine.exceptions.ScriptCaptchaRequiredException import com.futo.platformplayer.fragment.mainactivity.main.HomeFragment +import com.futo.platformplayer.fragment.mainactivity.main.SettingsFragment import com.futo.platformplayer.fragment.mainactivity.main.SourceDetailFragment import com.futo.platformplayer.logging.AndroidLogConsumer import com.futo.platformplayer.logging.FileLogConsumer @@ -164,6 +163,12 @@ class StateApp { ?: throw IllegalStateException("Attempted to use a global context while MainActivity is no longer available"); return thisContext; } + val activity: MainActivity? get() { + val context = contextOrNull; + if(context is MainActivity) + return context; + return null; + } private var _mainId: String? = null; @@ -475,7 +480,7 @@ class StateApp { StateSync.instance.start(context) } - settingsActivityClosed.subscribe { + SettingsFragment.onClosed.subscribe { if (Settings.instance.synchronization.enabled) { StateSync.instance.start(context) } else { @@ -487,7 +492,7 @@ class StateApp { scopeOrNull?.launch(Dispatchers.Main) { try { if (!it.isNullOrEmpty()) { - (SettingsActivity.getActivity() ?: contextOrNull)?.let { c -> + (StateApp.instance.activity ?: contextOrNull)?.let { c -> val okButtonAction = Action(c.getString(R.string.ok), {}, ActionStyle.PRIMARY) val copyButtonAction = Action(c.getString(R.string.copy), { val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager diff --git a/app/src/main/java/com/futo/platformplayer/states/StateBackup.kt b/app/src/main/java/com/futo/platformplayer/states/StateBackup.kt index 7cf3d976..11aae89e 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateBackup.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateBackup.kt @@ -9,7 +9,6 @@ import com.futo.platformplayer.Settings import com.futo.platformplayer.UIDialogs import com.futo.platformplayer.activities.IWithResultLauncher import com.futo.platformplayer.activities.MainActivity -import com.futo.platformplayer.activities.SettingsActivity import com.futo.platformplayer.api.media.models.channels.SerializedChannel import com.futo.platformplayer.api.media.models.video.IPlatformVideo import com.futo.platformplayer.api.media.models.video.SerializedPlatformVideo @@ -157,8 +156,8 @@ class StateBackup { } catch (exSec: FileNotFoundException) { Logger.e(TAG, "Failed to access backup file", exSec); - val activity = if(SettingsActivity.getActivity() != null) - SettingsActivity.getActivity(); + val activity = if(StateApp.instance.activity != null) + StateApp.instance.activity else if(StateApp.instance.isMainActive) StateApp.instance.contextOrNull; else null; @@ -226,7 +225,7 @@ class StateBackup { StateApp.instance.contextOrNull?.let { val uri = FileProvider.getUriForFile(it, it.resources.getString(R.string.authority), exportFile); - val activity = SettingsActivity.getActivity() ?: return@let; + val activity = StateApp.instance.activity ?: return@let; activity.startActivity( ShareCompat.IntentBuilder(activity) .setType("application/zip")