mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2026-05-16 04:52:39 +02:00
Browser package fixes, advanced settings for plugin support
This commit is contained in:
@@ -1051,7 +1051,7 @@ class Settings : FragmentedStorageFileJson() {
|
|||||||
|
|
||||||
|
|
||||||
fun shouldClearWebviewCookies(): Boolean {
|
fun shouldClearWebviewCookies(): Boolean {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -235,7 +235,8 @@ class SourcePluginConfig(
|
|||||||
val variable: String? = null,
|
val variable: String? = null,
|
||||||
val dependency: String? = null,
|
val dependency: String? = null,
|
||||||
val warningDialog: String? = null,
|
val warningDialog: String? = null,
|
||||||
val options: List<String>? = null
|
val options: List<String>? = null,
|
||||||
|
val isAdvanced: Boolean? = null
|
||||||
) {
|
) {
|
||||||
val variableOrName: String get() = variable ?: name;
|
val variableOrName: String get() = variable ?: name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,14 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.sync.Semaphore
|
import kotlinx.coroutines.sync.Semaphore
|
||||||
import kotlinx.coroutines.withTimeout
|
import kotlinx.coroutines.withTimeout
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
class PackageBrowser: V8Package {
|
class PackageBrowser: V8Package {
|
||||||
override val name: String get() = "Browser";
|
override val name: String get() = "Browser";
|
||||||
override val variableName: String = "browser";
|
override val variableName: String = "browser";
|
||||||
|
|
||||||
|
private val _json = Json { };
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
private var _readySemaphore: Semaphore? = null;
|
private var _readySemaphore: Semaphore? = null;
|
||||||
@Transient
|
@Transient
|
||||||
@@ -137,7 +140,9 @@ class PackageBrowser: V8Package {
|
|||||||
Logger.i("PackageBrowser", "Browser loading url [${url}]");
|
Logger.i("PackageBrowser", "Browser loading url [${url}]");
|
||||||
_readySemaphore = Semaphore(1, 1);
|
_readySemaphore = Semaphore(1, 1);
|
||||||
StateApp.instance.scope.launch(Dispatchers.Main) {
|
StateApp.instance.scope.launch(Dispatchers.Main) {
|
||||||
browser.loadUrl(url);
|
try {
|
||||||
|
browser.loadUrl(url);
|
||||||
|
} catch(ex: Throwable) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,12 +163,17 @@ class PackageBrowser: V8Package {
|
|||||||
}
|
}
|
||||||
StateApp.instance.scope.launch(Dispatchers.Main) {
|
StateApp.instance.scope.launch(Dispatchers.Main) {
|
||||||
try {
|
try {
|
||||||
Logger.i("PackageBrowser", "Browser running JS with callback [${callbackId}]\n${(if(js.length > 200) (js.substring(0, 200) + "...") else js)})");
|
try {
|
||||||
browser.evaluateJavascript(js, object : ValueCallback<String> {
|
Logger.i("PackageBrowser", "Browser running JS with callback [${callbackId}]\n${(if(js.length > 200) (js.substring(0, 200) + "...") else js)})");
|
||||||
override fun onReceiveValue(value: String?) {
|
browser.evaluateJavascript(js, object : ValueCallback<String> {
|
||||||
Logger.i("PackageBrowser", "Browser run finished");
|
override fun onReceiveValue(value: String?) {
|
||||||
}
|
Logger.i("PackageBrowser", "Browser run finished");
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
catch(ex: Throwable) {
|
||||||
|
Logger.e("PackageBrowser", "Browser running failed: " + ex.message, ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(ex: Throwable) {
|
catch(ex: Throwable) {
|
||||||
Logger.e("PackageBrowser", "Failed to invoke browser", ex);
|
Logger.e("PackageBrowser", "Failed to invoke browser", ex);
|
||||||
@@ -182,17 +192,27 @@ class PackageBrowser: V8Package {
|
|||||||
Logger.i("PackageBrowser", "Browser run returned: " + (value ?: ""));
|
Logger.i("PackageBrowser", "Browser run returned: " + (value ?: ""));
|
||||||
StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) {
|
StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) {
|
||||||
Logger.i("PackageBrowser", "Invoking V8 with result (${funcClone != null})");
|
Logger.i("PackageBrowser", "Invoking V8 with result (${funcClone != null})");
|
||||||
_plugin.busy {
|
try {
|
||||||
funcClone?.callVoid(null, arrayOf(value));
|
_plugin.busy {
|
||||||
|
if (value != null) {
|
||||||
|
val json = _json.decodeFromString<String>(value);
|
||||||
|
funcClone?.callVoid(null, arrayOf(json));
|
||||||
|
} else
|
||||||
|
funcClone?.callVoid(null, arrayOf((null as String?)));
|
||||||
|
}
|
||||||
|
if (!_plugin.isStopped)
|
||||||
|
JavetResourceUtils.safeClose(funcClone);
|
||||||
|
}
|
||||||
|
catch(ex: Throwable) {
|
||||||
|
Logger.e("PackageBrowser", "Browser Failed to callback: " + ex.message, ex);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!_plugin.isStopped)
|
|
||||||
JavetResourceUtils.safeClose(funcClone);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
catch(ex: Throwable) {
|
catch(ex: Throwable) {
|
||||||
Logger.e("PackageBrowser", "Failed to invoke browser", ex);
|
Logger.e("PackageBrowser", "Browser Failed to invoke browser", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import android.net.Uri
|
|||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.webkit.CookieManager
|
||||||
import androidx.documentfile.provider.DocumentFile
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@@ -448,7 +449,15 @@ class StateApp {
|
|||||||
_cacheDirectory?.let { ApiMethods.initCache(it) };
|
_cacheDirectory?.let { ApiMethods.initCache(it) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Settings.instance.other.shouldClearWebviewCookies()) {
|
||||||
|
try {
|
||||||
|
val cookieManager: CookieManager =
|
||||||
|
CookieManager.getInstance();
|
||||||
|
cookieManager.removeAllCookies(null);
|
||||||
|
} catch (ex: Throwable) {
|
||||||
|
Logger.e(SourceDetailFragment.Companion.TAG, "Failed to clear cookies", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Logger.i(TAG, "MainApp Starting: Initializing [ModerationsManager]");
|
Logger.i(TAG, "MainApp Starting: Initializing [ModerationsManager]");
|
||||||
ModerationsManager.initialize(context);
|
ModerationsManager.initialize(context);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class FieldForm : LinearLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSettingsVisibility(group: GroupField? = null) {
|
fun updateSettingsVisibility(group: GroupField? = null, allowEmptyGroups: Boolean = false) {
|
||||||
val settings = group?.getFields() ?: _fields;
|
val settings = group?.getFields() ?: _fields;
|
||||||
val query = _editSearch.text.toString().lowercase();
|
val query = _editSearch.text.toString().lowercase();
|
||||||
|
|
||||||
@@ -58,7 +58,8 @@ class FieldForm : LinearLayout {
|
|||||||
val isGroupMatch = query.isEmpty() || group?.searchContent?.lowercase()?.contains(query) == true;
|
val isGroupMatch = query.isEmpty() || group?.searchContent?.lowercase()?.contains(query) == true;
|
||||||
for(field in settings) {
|
for(field in settings) {
|
||||||
if(field is GroupField) {
|
if(field is GroupField) {
|
||||||
updateSettingsVisibility(field);
|
if(!allowEmptyGroups)
|
||||||
|
updateSettingsVisibility(field);
|
||||||
} else if(field is View && field.descriptor != null) {
|
} else if(field is View && field.descriptor != null) {
|
||||||
if(field.isAdvanced && !_showAdvancedSettings)
|
if(field.isAdvanced && !_showAdvancedSettings)
|
||||||
{
|
{
|
||||||
@@ -73,15 +74,21 @@ class FieldForm : LinearLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(field is View) {
|
||||||
|
if(field.isAdvanced && !_showAdvancedSettings)
|
||||||
|
field.visibility = View.GONE;
|
||||||
|
else
|
||||||
|
field.visibility = VISIBLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(group != null) {
|
if(group != null) {
|
||||||
group.visibility = if (groupVisible) View.VISIBLE else View.GONE;
|
group.visibility = if (groupVisible) View.VISIBLE else View.GONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setShowAdvancedSettings(show: Boolean) {
|
fun setShowAdvancedSettings(show: Boolean, allowEmptyGroups: Boolean = false) {
|
||||||
_showAdvancedSettings = show;
|
_showAdvancedSettings = show;
|
||||||
updateSettingsVisibility();
|
updateSettingsVisibility(null, allowEmptyGroups);
|
||||||
}
|
}
|
||||||
fun setSearchQuery(query: String) {
|
fun setSearchQuery(query: String) {
|
||||||
_editSearch.setText(query);
|
_editSearch.setText(query);
|
||||||
@@ -141,7 +148,9 @@ class FieldForm : LinearLayout {
|
|||||||
}
|
}
|
||||||
fun fromPluginSettings(settings: List<SourcePluginConfig.Setting>, values: HashMap<String, String?>, groupTitle: String? = null, groupDescription: String? = null) {
|
fun fromPluginSettings(settings: List<SourcePluginConfig.Setting>, values: HashMap<String, String?>, groupTitle: String? = null, groupDescription: String? = null) {
|
||||||
_fieldsContainer.removeAllViews();
|
_fieldsContainer.removeAllViews();
|
||||||
val newFields = getFieldsFromPluginSettings(context, settings, values);
|
val newFields = getFieldsFromPluginSettings(context, settings, values, {
|
||||||
|
setShowAdvancedSettings(it, true);
|
||||||
|
});
|
||||||
if (newFields.isEmpty()) {
|
if (newFields.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -157,6 +166,7 @@ class FieldForm : LinearLayout {
|
|||||||
_fieldsContainer.addView(v);
|
_fieldsContainer.addView(v);
|
||||||
}
|
}
|
||||||
_fields = newFields.map { it.second };
|
_fields = newFields.map { it.second };
|
||||||
|
updateSettingsVisibility(null, true);
|
||||||
} else {
|
} else {
|
||||||
for(field in newFields) {
|
for(field in newFields) {
|
||||||
finalizePluginSettingField(field.first, field.second, newFields);
|
finalizePluginSettingField(field.first, field.second, newFields);
|
||||||
@@ -164,6 +174,8 @@ class FieldForm : LinearLayout {
|
|||||||
val group = GroupField(context, groupTitle, groupDescription)
|
val group = GroupField(context, groupTitle, groupDescription)
|
||||||
.withFields(newFields.map { it.second });
|
.withFields(newFields.map { it.second });
|
||||||
_fieldsContainer.addView(group as View);
|
_fieldsContainer.addView(group as View);
|
||||||
|
_fields = newFields.map { it.second };
|
||||||
|
updateSettingsVisibility(null, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun finalizePluginSettingField(setting: SourcePluginConfig.Setting, field: IField, others: List<Pair<SourcePluginConfig.Setting, IField>>) {
|
private fun finalizePluginSettingField(setting: SourcePluginConfig.Setting, field: IField, others: List<Pair<SourcePluginConfig.Setting, IField>>) {
|
||||||
@@ -234,7 +246,7 @@ class FieldForm : LinearLayout {
|
|||||||
private val _json = Json;
|
private val _json = Json;
|
||||||
|
|
||||||
|
|
||||||
fun getFieldsFromPluginSettings(context: Context, settings: List<SourcePluginConfig.Setting>, values: HashMap<String, String?>): List<Pair<SourcePluginConfig.Setting, IField>> {
|
fun getFieldsFromPluginSettings(context: Context, settings: List<SourcePluginConfig.Setting>, values: HashMap<String, String?>, onAdvancedChanged: ((newVal: Boolean)->Unit)? = null): List<Pair<SourcePluginConfig.Setting, IField>> {
|
||||||
val fields = mutableListOf<Pair<SourcePluginConfig.Setting, IField>>()
|
val fields = mutableListOf<Pair<SourcePluginConfig.Setting, IField>>()
|
||||||
|
|
||||||
for(setting in settings) {
|
for(setting in settings) {
|
||||||
@@ -243,6 +255,7 @@ class FieldForm : LinearLayout {
|
|||||||
val field = when(setting.type.lowercase()) {
|
val field = when(setting.type.lowercase()) {
|
||||||
"header" -> {
|
"header" -> {
|
||||||
val groupField = GroupField(context, setting.name, setting.description);
|
val groupField = GroupField(context, setting.name, setting.description);
|
||||||
|
groupField.isAdvanced = (setting.isAdvanced ?: false);
|
||||||
groupField;
|
groupField;
|
||||||
}
|
}
|
||||||
"boolean" -> {
|
"boolean" -> {
|
||||||
@@ -252,6 +265,7 @@ class FieldForm : LinearLayout {
|
|||||||
field.onChanged.subscribe { _, v, _ ->
|
field.onChanged.subscribe { _, v, _ ->
|
||||||
values[setting.variableOrName] = _json.encodeToString (v == 1 || v == true);
|
values[setting.variableOrName] = _json.encodeToString (v == 1 || v == true);
|
||||||
}
|
}
|
||||||
|
field.isAdvanced = (setting.isAdvanced ?: false);
|
||||||
field;
|
field;
|
||||||
}
|
}
|
||||||
"dropdown" -> {
|
"dropdown" -> {
|
||||||
@@ -261,6 +275,7 @@ class FieldForm : LinearLayout {
|
|||||||
field.onChanged.subscribe { _, v, _ ->
|
field.onChanged.subscribe { _, v, _ ->
|
||||||
values[setting.variableOrName] = v.toString();
|
values[setting.variableOrName] = v.toString();
|
||||||
}
|
}
|
||||||
|
field.isAdvanced = (setting.isAdvanced ?: false);
|
||||||
field;
|
field;
|
||||||
}
|
}
|
||||||
else null;
|
else null;
|
||||||
@@ -272,6 +287,17 @@ class FieldForm : LinearLayout {
|
|||||||
fields.add(Pair(setting, field));
|
fields.add(Pair(setting, field));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(onAdvancedChanged != null && settings.any { it.isAdvanced == true }) {
|
||||||
|
val setting = SourcePluginConfig.Setting("Show Advanced", "See advanced settings, which may be counter productive to change", "boolean", "false");
|
||||||
|
val field = ToggleField(context).withValue(setting.name, setting.description, false);
|
||||||
|
|
||||||
|
field.onChanged.subscribe { field, new, old ->
|
||||||
|
onAdvancedChanged?.invoke(new as Boolean);
|
||||||
|
}
|
||||||
|
fields.add(Pair(setting, field));
|
||||||
|
}
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user