From 2eb79fe94e606b665a179bd7de9944a3d04632d1 Mon Sep 17 00:00:00 2001 From: aay <275768457+aayy-dev@users.noreply.github.com> Date: Fri, 23 Oct 2026 18:02:47 -0500 Subject: [PATCH] Honour the browser setting on every screen, and say which way it is set "Open links in a browser" was asked by Home alone. HomeScreen kept a private open() that checked it, but every other screen's onOpenUrl was wired in VectorApp straight to the in-app viewer, so module pages in the store, the canary list, the troubleshooter and the framework update screen opened the viewer whichever way the switch was set. The setting is now asked in one place, openLink in VectorApp, which every screen is handed as its onOpenUrl; Home's copy is gone. With the store's links in play, the browser path now sees URLs from the module catalogue rather than only ones the app built itself, so the fallback to the viewer catches any exception from startActivity, not just ActivityNotFoundException: a file:// homepage would otherwise throw FileUriExposedException and take the manager down. The row's subtitle also read "Off: GitHub pages open inside Vector." with the switch on. It now has an On line, added to every locale alongside the Off one. --- .../org/matrix/vector/manager/ui/VectorApp.kt | 37 ++++++++++++++---- .../ui/screens/home/HomeAppearanceSheet.kt | 4 +- .../manager/ui/screens/home/HomeScreen.kt | 38 ++++--------------- .../manager/ui/screens/home/HomeViewModel.kt | 2 - manager/src/main/res/values-ar/strings.xml | 1 + manager/src/main/res/values-de/strings.xml | 1 + manager/src/main/res/values-es/strings.xml | 1 + manager/src/main/res/values-fa/strings.xml | 1 + manager/src/main/res/values-fr/strings.xml | 1 + manager/src/main/res/values-in/strings.xml | 1 + manager/src/main/res/values-it/strings.xml | 1 + manager/src/main/res/values-iw/strings.xml | 1 + manager/src/main/res/values-ja/strings.xml | 1 + manager/src/main/res/values-ko/strings.xml | 1 + manager/src/main/res/values-pl/strings.xml | 1 + .../src/main/res/values-pt-rBR/strings.xml | 1 + manager/src/main/res/values-ru/strings.xml | 1 + manager/src/main/res/values-tr/strings.xml | 1 + manager/src/main/res/values-uk/strings.xml | 1 + manager/src/main/res/values-vi/strings.xml | 1 + .../src/main/res/values-zh-rCN/strings.xml | 1 + .../src/main/res/values-zh-rTW/strings.xml | 1 + manager/src/main/res/values/strings.xml | 1 + 23 files changed, 59 insertions(+), 41 deletions(-) diff --git a/manager/src/main/kotlin/org/matrix/vector/manager/ui/VectorApp.kt b/manager/src/main/kotlin/org/matrix/vector/manager/ui/VectorApp.kt index 2d308ef564..c53bd15cc4 100644 --- a/manager/src/main/kotlin/org/matrix/vector/manager/ui/VectorApp.kt +++ b/manager/src/main/kotlin/org/matrix/vector/manager/ui/VectorApp.kt @@ -1,5 +1,8 @@ package org.matrix.vector.manager.ui +import android.content.Context +import android.content.Intent +import android.net.Uri import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize @@ -14,6 +17,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator import androidx.navigation3.runtime.EntryProviderScope @@ -77,6 +81,7 @@ import org.matrix.vector.ui.store.RepoScreen @Composable fun VectorApp() { val navigator = rememberNavigator(VectorNavPanelStore, TOP_LEVEL_DESTINATIONS) + val context = LocalContext.current // Where the launch intent asked to open. The activity has no back stack to act on, so it leaves // the destination here and this is the first place there is one — on a cold start the splash is @@ -163,7 +168,7 @@ fun VectorApp() { rememberSaveableStateHolderNavEntryDecorator(), rememberViewModelStoreNavEntryDecorator(), ), - entryProvider = entryProvider { registerRoutes(navigator) }, + entryProvider = entryProvider { registerRoutes(navigator, context) }, ) // Last child of the Box so it draws over the destination, and inside the app window // rather than in one of its own: parasitically this app is com.android.shell, which @@ -195,11 +200,11 @@ fun VectorApp() { * its keys by class, and entryProvider throws for one it was never given, so dropping the * registration of a hidden panel would turn a stale saved stack into a crash. */ -private fun EntryProviderScope.registerRoutes(navigator: Navigator) { +private fun EntryProviderScope.registerRoutes(navigator: Navigator, context: Context) { entry { HomeScreen( onOpenStatus = { navigator.go(SystemStatus) }, - onOpenUrl = { url -> navigator.go(Web(url)) }, + onOpenUrl = { url -> openLink(context, navigator, url) }, onOpenCanary = { navigator.go(Canary) }, onOpenReport = { navigator.go(Troubleshoot) }, onOpenUpdate = { navigator.go(FrameworkUpdate()) }, @@ -234,7 +239,7 @@ private fun EntryProviderScope.registerRoutes(navigator: Navigator) { RepoDetailsScreen( packageName = route.packageName, onNavigateBack = { navigator.back() }, - onOpenUrl = { url -> navigator.go(Web(url)) }, + onOpenUrl = { url -> openLink(context, navigator, url) }, dataSource = ServiceLocator.store, settings = ServiceLocator.settings, host = remember(route.packageName) { VectorStoreInstallHost(route.packageName) }, @@ -255,14 +260,14 @@ private fun EntryProviderScope.registerRoutes(navigator: Navigator) { entry { TroubleshootScreen( onNavigateBack = { navigator.back() }, - onOpenUrl = { url -> navigator.go(Web(url)) }, + onOpenUrl = { url -> openLink(context, navigator, url) }, onOpenCanary = { navigator.go(Canary) }, ) } entry { CanaryScreen( onNavigateBack = { navigator.back() }, - onOpenUrl = { url -> navigator.go(Web(url)) }, + onOpenUrl = { url -> openLink(context, navigator, url) }, onInstall = { versionCode -> navigator.go(FrameworkUpdate(versionCode)) }, onOpenReport = { navigator.go(Troubleshoot) }, ) @@ -271,8 +276,26 @@ private fun EntryProviderScope.registerRoutes(navigator: Navigator) { FrameworkUpdateScreen( openOnVersionCode = route.versionCode.takeIf { it > 0 }, onNavigateBack = { navigator.back() }, - onOpenUrl = { url -> navigator.go(Web(url)) }, + onOpenUrl = { url -> openLink(context, navigator, url) }, ) } entry { route -> WebScreen(url = route.url, onNavigateBack = { navigator.back() }) } } + +/** + * Opens a link in the in-app viewer, or in a browser with "Open links in a browser" on. Every + * screen's `onOpenUrl` lands here, so the setting is asked in one place, and read at the tap. + */ +private fun openLink(context: Context, navigator: Navigator, url: String) { + if (ServiceLocator.settings.openLinksExternally.value) { + try { + context.startActivity( + Intent(Intent.ACTION_VIEW, Uri.parse(url)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + ) + return + } catch (_: Exception) { + // No app took it, or it was refused (a file:// URI): the viewer beats a dead tap. + } + } + navigator.go(Web(url)) +} diff --git a/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeAppearanceSheet.kt b/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeAppearanceSheet.kt index 902865048d..4eae606006 100644 --- a/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeAppearanceSheet.kt +++ b/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeAppearanceSheet.kt @@ -250,7 +250,9 @@ LocalizedOverlay { ToggleRow( title = stringResource(R.string.settings_open_externally), icon = Icons.Rounded.OpenInBrowser, - subtitle = stringResource(R.string.settings_open_externally_summary), + subtitle = + if (openExternally) stringResource(R.string.settings_open_externally_summary_on) + else stringResource(R.string.settings_open_externally_summary), checked = openExternally, onCheckedChange = settings::setOpenLinksExternally, ) diff --git a/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeScreen.kt b/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeScreen.kt index b6d00feb4c..feac6d2562 100644 --- a/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeScreen.kt +++ b/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeScreen.kt @@ -1,8 +1,5 @@ package org.matrix.vector.manager.ui.screens.home -import android.content.ActivityNotFoundException -import android.content.Intent -import android.net.Uri import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -145,7 +142,6 @@ fun HomeScreen( val status by viewModel.status.collectAsStateWithLifecycle() val feed by viewModel.feed.collectAsStateWithLifecycle() val refreshing by viewModel.refreshing.collectAsStateWithLifecycle() - val openExternally by viewModel.openLinksExternally.collectAsStateWithLifecycle() val feedItems by viewModel.feedItems.collectAsStateWithLifecycle() val loadingHistory by viewModel.loadingHistory.collectAsStateWithLifecycle() val historyStalled by viewModel.historyStalled.collectAsStateWithLifecycle() @@ -156,7 +152,6 @@ fun HomeScreen( val presence by viewModel.presence.collectAsStateWithLifecycle() val promptDismissed by viewModel.launcherPromptDismissed.collectAsStateWithLifecycle() val hintStatus by viewModel.statusBadgeHint.collectAsStateWithLifecycle() - val context = LocalContext.current var showSplash by rememberSaveable { mutableStateOf(false) } var showAppearance by rememberSaveable { mutableStateOf(false) } var showLanguage by rememberSaveable { mutableStateOf(false) } @@ -203,25 +198,6 @@ fun HomeScreen( } } - // Every GitHub link goes through the in-app viewer by default; the setting sends them to a - // browser instead for users who would rather stay in one. - fun open(url: String) { - if (openExternally) { - try { - context.startActivity( - Intent(Intent.ACTION_VIEW, Uri.parse(url)) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - ) - } catch (_: ActivityNotFoundException) { - // Nothing on the device took the intent. Falling back to the built-in viewer beats - // a link tap that does nothing at all. - onOpenUrl(url) - } - } else { - onOpenUrl(url) - } - } - Scaffold( // The header draws its own status-bar inset so it can run under the bar; letting the // Scaffold consume it here would leave a band of plain background above the pane. The @@ -284,12 +260,12 @@ fun HomeScreen( // is effectively unreachable without a long scroll. item { TakePartSection( - onOpen = ::open, + onOpen = onOpenUrl, onCanary = onOpenCanary, onReport = onOpenReport, ) Spacer(Modifier.height(14.dp)) - ProjectFooter(feed = feed, onClick = { open(GitHubRepository.REPO_URL) }) + ProjectFooter(feed, onClick = { onOpenUrl(GitHubRepository.REPO_URL) }) Spacer(Modifier.height(26.dp)) } @@ -303,9 +279,9 @@ fun HomeScreen( onLoadMoreHistory = viewModel::loadMoreHistory, onToggleAuthor = viewModel::toggleAuthorFilter, onClearAuthors = viewModel::clearAuthorFilter, - onOpenCommit = { c -> open(c.htmlUrl ?: GitHubRepository.REPO_URL) }, - onOpenPullRequest = { pr -> open("${GitHubRepository.REPO_URL}/pull/$pr") }, - onOpenProfile = { c -> open(c.profileUrl ?: GitHubRepository.REPO_URL) }, + onOpenCommit = { onOpenUrl(it.htmlUrl ?: GitHubRepository.REPO_URL) }, + onOpenPullRequest = { onOpenUrl("${GitHubRepository.REPO_URL}/pull/$it") }, + onOpenProfile = { onOpenUrl(it.profileUrl ?: GitHubRepository.REPO_URL) }, ) item { Spacer(Modifier.height(24.dp)) } @@ -377,8 +353,8 @@ fun HomeScreen( LanguageSheet( controller = VectorLocaleController, onDismiss = { showLanguage = false }, - onHelpTranslate = { open(CROWDIN_URL) }, - onOpenUrl = ::open, + onHelpTranslate = { onOpenUrl(CROWDIN_URL) }, + onOpenUrl = onOpenUrl, ) } diff --git a/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeViewModel.kt b/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeViewModel.kt index 725ff534dc..fea714d623 100644 --- a/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeViewModel.kt +++ b/manager/src/main/kotlin/org/matrix/vector/manager/ui/screens/home/HomeViewModel.kt @@ -172,8 +172,6 @@ class HomeViewModel( private val github: GitHubRepository, ) : ViewModel() { - val openLinksExternally: StateFlow = ServiceLocator.settings.openLinksExternally - val headerAmbience: StateFlow = ServiceLocator.settings.headerAmbience private val _status = MutableStateFlow(FrameworkStatus()) diff --git a/manager/src/main/res/values-ar/strings.xml b/manager/src/main/res/values-ar/strings.xml index 932f431a3d..77bba2ac43 100644 --- a/manager/src/main/res/values-ar/strings.xml +++ b/manager/src/main/res/values-ar/strings.xml @@ -166,6 +166,7 @@ فتح الروابط في المتصفح عند الإيقاف: تُفتح صفحات GitHub داخل Vector. + عند التشغيل: تُفتح صفحات GitHub في المتصفح. استخدام ما تطلبه الوحدة تحديد كل ما هو ظاهر diff --git a/manager/src/main/res/values-de/strings.xml b/manager/src/main/res/values-de/strings.xml index 55a712de70..370c98fe92 100644 --- a/manager/src/main/res/values-de/strings.xml +++ b/manager/src/main/res/values-de/strings.xml @@ -142,6 +142,7 @@ Links im Browser öffnen Aus: GitHub-Seiten öffnen sich in Vector. + An: GitHub-Seiten öffnen sich im Browser. Nehmen, was das Modul verlangt Alles Angezeigte auswählen diff --git a/manager/src/main/res/values-es/strings.xml b/manager/src/main/res/values-es/strings.xml index d3fc8ad5cd..c55b165488 100644 --- a/manager/src/main/res/values-es/strings.xml +++ b/manager/src/main/res/values-es/strings.xml @@ -142,6 +142,7 @@ Abrir los enlaces en un navegador Desactivado: las páginas de GitHub se abren dentro de Vector. + Activado: las páginas de GitHub se abren en el navegador. Usar lo que el módulo pide Seleccionar todo lo que se muestra diff --git a/manager/src/main/res/values-fa/strings.xml b/manager/src/main/res/values-fa/strings.xml index d4c8a06702..78887c7f2b 100644 --- a/manager/src/main/res/values-fa/strings.xml +++ b/manager/src/main/res/values-fa/strings.xml @@ -142,6 +142,7 @@ باز کردن پیوندها در مرورگر خاموش: صفحه‌های GitHub درون Vector باز می‌شوند. + روشن: صفحه‌های GitHub در مرورگر باز می‌شوند. همان چیزی که ماژول می‌خواهد گزینش همهٔ موارد نمایان diff --git a/manager/src/main/res/values-fr/strings.xml b/manager/src/main/res/values-fr/strings.xml index 3a401d36b6..71b7fb049b 100644 --- a/manager/src/main/res/values-fr/strings.xml +++ b/manager/src/main/res/values-fr/strings.xml @@ -142,6 +142,7 @@ Ouvrir les liens dans un navigateur Désactivé : les pages GitHub s\'ouvrent dans Vector. + Activé : les pages GitHub s\'ouvrent dans le navigateur. Prendre ce que le module demande Tout sélectionner à l\'écran diff --git a/manager/src/main/res/values-in/strings.xml b/manager/src/main/res/values-in/strings.xml index 3c6c6390e6..35b0684962 100644 --- a/manager/src/main/res/values-in/strings.xml +++ b/manager/src/main/res/values-in/strings.xml @@ -140,6 +140,7 @@ Buka tautan di peramban Mati: halaman GitHub dibuka di dalam Vector. + Hidup: halaman GitHub dibuka di peramban. Pakai yang diminta modul Pilih semua yang tampil diff --git a/manager/src/main/res/values-it/strings.xml b/manager/src/main/res/values-it/strings.xml index e71e14e18c..961e6e906f 100644 --- a/manager/src/main/res/values-it/strings.xml +++ b/manager/src/main/res/values-it/strings.xml @@ -142,6 +142,7 @@ Apri i link in un browser Disattivato: le pagine GitHub si aprono dentro Vector. + Attivato: le pagine GitHub si aprono nel browser. Usa quello che chiede il modulo Seleziona tutto ciò che è mostrato diff --git a/manager/src/main/res/values-iw/strings.xml b/manager/src/main/res/values-iw/strings.xml index 385c875830..61f62412b8 100644 --- a/manager/src/main/res/values-iw/strings.xml +++ b/manager/src/main/res/values-iw/strings.xml @@ -158,6 +158,7 @@ פתיחת קישורים בדפדפן כבוי: דפי GitHub נפתחים בתוך Vector. + מופעל: דפי GitHub נפתחים בדפדפן. להשתמש במה שהמודול מבקש בחירת כל מה שמוצג diff --git a/manager/src/main/res/values-ja/strings.xml b/manager/src/main/res/values-ja/strings.xml index 3b75f0c3f6..40f602e089 100644 --- a/manager/src/main/res/values-ja/strings.xml +++ b/manager/src/main/res/values-ja/strings.xml @@ -136,6 +136,7 @@ リンクをブラウザで開く オフのとき、GitHub のページは Vector 内で開きます。 + オンのとき、GitHub のページはブラウザで開きます。 モジュールの要求どおりにする 表示中のすべてを選択 diff --git a/manager/src/main/res/values-ko/strings.xml b/manager/src/main/res/values-ko/strings.xml index 533f397354..dbc1ff96a8 100644 --- a/manager/src/main/res/values-ko/strings.xml +++ b/manager/src/main/res/values-ko/strings.xml @@ -136,6 +136,7 @@ 링크를 브라우저에서 열기 꺼두면 GitHub 페이지가 Vector 안에서 열립니다. + 켜두면 GitHub 페이지가 브라우저에서 열립니다. 모듈이 요청한 대로 두기 표시된 항목 모두 선택 diff --git a/manager/src/main/res/values-pl/strings.xml b/manager/src/main/res/values-pl/strings.xml index e8f40a59c6..67742e11d9 100644 --- a/manager/src/main/res/values-pl/strings.xml +++ b/manager/src/main/res/values-pl/strings.xml @@ -234,6 +234,7 @@ Otwieraj linki w przeglądarce Wyłączone: strony GitHuba otwierają się wewnątrz Vectora. + Włączone: strony GitHuba otwierają się w przeglądarce. Użyj tego, czego wymaga moduł Zaznacz wszystko, co jest pokazane diff --git a/manager/src/main/res/values-pt-rBR/strings.xml b/manager/src/main/res/values-pt-rBR/strings.xml index 3977bb60ae..036ff22e2c 100644 --- a/manager/src/main/res/values-pt-rBR/strings.xml +++ b/manager/src/main/res/values-pt-rBR/strings.xml @@ -142,6 +142,7 @@ Abrir links em um navegador Desligado: as páginas do GitHub abrem dentro do Vector. + Ligado: as páginas do GitHub abrem no navegador. Usar o que o módulo pede Selecionar tudo que está à mostra diff --git a/manager/src/main/res/values-ru/strings.xml b/manager/src/main/res/values-ru/strings.xml index c0c7f53709..dcc7ad0d2e 100644 --- a/manager/src/main/res/values-ru/strings.xml +++ b/manager/src/main/res/values-ru/strings.xml @@ -142,6 +142,7 @@ Открывать ссылки в браузере Выключено: страницы GitHub открываются внутри Vector. + Включено: страницы GitHub открываются в браузере. Взять то, что просит модуль Выбрать всё показанное Снять со всего показанного diff --git a/manager/src/main/res/values-tr/strings.xml b/manager/src/main/res/values-tr/strings.xml index 701a438e64..0e9fe79d12 100644 --- a/manager/src/main/res/values-tr/strings.xml +++ b/manager/src/main/res/values-tr/strings.xml @@ -142,6 +142,7 @@ Bağlantıları tarayıcıda aç Kapalı: GitHub sayfaları Vector içinde açılır. + Açık: GitHub sayfaları tarayıcıda açılır. Modülün istediğini kullan Görünenlerin tümünü seç diff --git a/manager/src/main/res/values-uk/strings.xml b/manager/src/main/res/values-uk/strings.xml index 29cb7052f0..4bd4175ab1 100644 --- a/manager/src/main/res/values-uk/strings.xml +++ b/manager/src/main/res/values-uk/strings.xml @@ -154,6 +154,7 @@ Відкривати посилання в браузері Вимкнено: сторінки GitHub відкриваються всередині Vector. + Увімкнено: сторінки GitHub відкриваються в браузері. Узяти те, що просить модуль Вибрати все показане diff --git a/manager/src/main/res/values-vi/strings.xml b/manager/src/main/res/values-vi/strings.xml index c592b94e78..9d07bb6de2 100644 --- a/manager/src/main/res/values-vi/strings.xml +++ b/manager/src/main/res/values-vi/strings.xml @@ -136,6 +136,7 @@ Mở liên kết bằng trình duyệt Tắt: các trang GitHub mở ngay trong Vector. + Bật: các trang GitHub mở bằng trình duyệt. Dùng đúng những gì mô-đun yêu cầu Chọn hết những mục đang hiện diff --git a/manager/src/main/res/values-zh-rCN/strings.xml b/manager/src/main/res/values-zh-rCN/strings.xml index 5068e3cf5a..bbaaf112d1 100644 --- a/manager/src/main/res/values-zh-rCN/strings.xml +++ b/manager/src/main/res/values-zh-rCN/strings.xml @@ -136,6 +136,7 @@ 用浏览器打开链接 关闭时:GitHub 页面在 Vector 内打开。 + 开启时:GitHub 页面在浏览器中打开。 使用模块建议的范围 选中当前显示的全部 diff --git a/manager/src/main/res/values-zh-rTW/strings.xml b/manager/src/main/res/values-zh-rTW/strings.xml index 76a243e73c..9084d27fd4 100644 --- a/manager/src/main/res/values-zh-rTW/strings.xml +++ b/manager/src/main/res/values-zh-rTW/strings.xml @@ -136,6 +136,7 @@ 以瀏覽器開啟連結 關閉時:GitHub 頁面在 Vector 內開啟。 + 開啟時:GitHub 頁面在瀏覽器中開啟。 使用模組建議的範圍 選取目前顯示的全部 diff --git a/manager/src/main/res/values/strings.xml b/manager/src/main/res/values/strings.xml index ec54516e14..2f8832bfc5 100644 --- a/manager/src/main/res/values/strings.xml +++ b/manager/src/main/res/values/strings.xml @@ -231,6 +231,7 @@ Open links in a browser Off: GitHub pages open inside Vector. + On: GitHub pages open in your browser. Use what the module asks for