diff --git a/android/app/src/main/java/com/therealaleph/mhrv/ConfigStore.kt b/android/app/src/main/java/com/therealaleph/mhrv/ConfigStore.kt index 383f0dd..8f7e671 100644 --- a/android/app/src/main/java/com/therealaleph/mhrv/ConfigStore.kt +++ b/android/app/src/main/java/com/therealaleph/mhrv/ConfigStore.kt @@ -135,6 +135,13 @@ data class MhrvConfig( /** Package names used by ONLY and EXCEPT. Empty under ALL. */ val splitApps: List = emptyList(), + /** + * Route YouTube traffic through Apps Script relay instead of the + * SNI-rewrite tunnel. Avoids Google SafeSearch-on-SNI / restricted + * mode, but slower for video. Maps to Rust `youtube_via_relay`. + */ + val youtubeViaRelay: Boolean = false, + /** UI language toggle. Non-Rust; honoured only by the Android wrapper. */ val uiLang: UiLang = UiLang.AUTO, ) { @@ -212,6 +219,7 @@ data class MhrvConfig( put("passthrough_hosts", JSONArray().apply { passthroughHosts.forEach { put(it) } }) } if (tunnelDoh) put("tunnel_doh", true) + if (youtubeViaRelay) put("youtube_via_relay", true) // Trim/drop-empty/dedupe before serializing — symmetric with the // read-side normalization in loadFromJson(), so a user typing // " doh.foo " or accidentally adding a duplicate doesn't end up @@ -317,6 +325,7 @@ object ConfigStore { if (cfg.upstreamSocks5.isNotBlank()) obj.put("upstream_socks5", cfg.upstreamSocks5) if (cfg.passthroughHosts.isNotEmpty()) obj.put("passthrough_hosts", JSONArray().apply { cfg.passthroughHosts.forEach { put(it) } }) if (cfg.tunnelDoh != defaults.tunnelDoh) obj.put("tunnel_doh", cfg.tunnelDoh) + if (cfg.youtubeViaRelay != defaults.youtubeViaRelay) obj.put("youtube_via_relay", cfg.youtubeViaRelay) val cleanBypassDohHosts = cfg.bypassDohHosts .map { it.trim() } .filter { it.isNotEmpty() } @@ -420,6 +429,7 @@ object ConfigStore { buildList { for (i in 0 until arr.length()) add(arr.optString(i)) } }?.filter { it.isNotBlank() }.orEmpty(), tunnelDoh = obj.optBoolean("tunnel_doh", false), + youtubeViaRelay = obj.optBoolean("youtube_via_relay", false), bypassDohHosts = obj.optJSONArray("bypass_doh_hosts")?.let { arr -> buildList { for (i in 0 until arr.length()) add(arr.optString(i)) } }?.filter { it.isNotBlank() }.orEmpty(), diff --git a/android/app/src/main/java/com/therealaleph/mhrv/ui/HomeScreen.kt b/android/app/src/main/java/com/therealaleph/mhrv/ui/HomeScreen.kt index 24323b7..0f795a6 100644 --- a/android/app/src/main/java/com/therealaleph/mhrv/ui/HomeScreen.kt +++ b/android/app/src/main/java/com/therealaleph/mhrv/ui/HomeScreen.kt @@ -1196,6 +1196,25 @@ private fun AdvancedSettings( ) } + // youtube_via_relay + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth(), + ) { + Column(modifier = Modifier.weight(1f)) { + Text(stringResource(R.string.adv_youtube_via_relay), style = MaterialTheme.typography.bodyMedium) + Text( + stringResource(R.string.adv_youtube_via_relay_help), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + Switch( + checked = cfg.youtubeViaRelay, + onCheckedChange = { onChange(cfg.copy(youtubeViaRelay = it)) }, + ) + } + // log_level dropdown var expanded by remember { mutableStateOf(false) } val levels = listOf("trace", "debug", "info", "warn", "error", "off") diff --git a/android/app/src/main/res/values-fa/strings.xml b/android/app/src/main/res/values-fa/strings.xml index 23c3cfd..2b8d198 100644 --- a/android/app/src/main/res/values-fa/strings.xml +++ b/android/app/src/main/res/values-fa/strings.xml @@ -67,6 +67,8 @@ بررسی TLS طرف مقابل خاموش کردن، بررسی گواهی را برای لبهٔ گوگل غیرفعال می‌کند. فقط برای اشکال‌زدایی کاربرد دارد. + ارسال یوتیوب از طریق رله + ترافیک youtube.com / youtu.be / ytimg.com را به‌جای تونل SNI-rewrite از رلهٔ Apps Script عبور می‌دهد. حالت محدود را دور می‌زند ولی پخش ویدیو کندتر می‌شود. log_level parallel_relay: %1$d تعداد درخواست‌های موازی هر بار. ۱ عادی است؛ روی لینک‌های با افت، ۲-۳ را امتحان کنید. diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 5f4d637..002f66e 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -67,6 +67,8 @@ Verify upstream TLS Off disables cert checks for the Google edge. Only useful for debugging. + Send YouTube through relay + Route youtube.com / youtu.be / ytimg.com through Apps Script relay instead of SNI-rewrite tunnel. Avoids restricted mode but slower for video. log_level parallel_relay: %1$d Fan-out per request. 1 is normal; bump to 2-3 on lossy links.