authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-07-15 12:48:55+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-07-15 10:48:55+00:00
logecb35f75839925dd1ac6f854efeef5c9e291d11b
tree147cfa26a60049c8b89f836b3c4fdb474906b6a7
parentd359789ed4ed99b19a0bc6db3c6f6eba4d2b53ce
signature Signed by PGP key B5690EEEBB952194

Fix Legal modal header crash (#4000)

Co-authored-by: codex <codex@users.noreply.github.com>

2 files changed, 22 insertions(+), 21 deletions(-)

apps/mobile/src/Stack.tsx+1-1
......@@ -115,7 +115,7 @@ const LEGAL_DOCUMENT_HEADER_OPTIONS: AppScreenOptions = {
115115 ...SHEET_SOLID_HEADER_OPTIONS,
116116 headerBackVisible: false,
117117 headerLeft: SettingsLegalDocumentCloseHeaderButton,
118 headerRight: SettingsLegalDocumentExternalHeaderButton,
118 headerRight: () => <SettingsLegalDocumentExternalHeaderButton />,
119119 presentation: "fullScreenModal",
120120};
121121
apps/mobile/src/features/settings/components/SettingsLegalDocumentRouteScreen.tsx+21-20
......@@ -1,11 +1,5 @@
1import {
2 type NavigationProp,
3 type ParamListBase,
4 type RouteProp,
5 useNavigation,
6 useRoute,
7} from "@react-navigation/native";
8import { useCallback, useState } from "react";
1import { type NavigationProp, type ParamListBase, useNavigation } from "@react-navigation/native";
2import { useCallback, useLayoutEffect, useState } from "react";
93import { ActivityIndicator, Linking, Pressable, View } from "react-native";
104import { WebView } from "react-native-webview";
115
......@@ -15,10 +9,6 @@ import { SymbolView } from "../../../components/AppSymbol";
159import { useThemeColor } from "../../../lib/useThemeColor";
1610import { isLegalDocumentUrl, LEGAL_URL } from "../lib/legal-document-url";
1711
18type SettingsLegalRouteParams = {
19 SettingsLegal: { readonly externalUrl?: string } | undefined;
20};
21
2212export function SettingsLegalDocumentCloseHeaderButton() {
2313 const navigation = useNavigation();
2414 const iconColor = useThemeColor("--color-icon");
......@@ -42,20 +32,20 @@ export function SettingsLegalDocumentCloseHeaderButton() {
4232 );
4333}
4434
45export function SettingsLegalDocumentExternalHeaderButton() {
35export function SettingsLegalDocumentExternalHeaderButton({
36 externalUrl = LEGAL_URL,
37}: {
38 readonly externalUrl?: string;
39}) {
4640 const iconColor = useThemeColor("--color-icon");
47 const route = useRoute<RouteProp<SettingsLegalRouteParams, "SettingsLegal">>();
48 const externalUrl =
49 route.params?.externalUrl && isLegalDocumentUrl(route.params.externalUrl)
50 ? route.params.externalUrl
51 : LEGAL_URL;
41 const safeExternalUrl = isLegalDocumentUrl(externalUrl) ? externalUrl : LEGAL_URL;
5242
5343 return (
5444 <Pressable
5545 accessibilityLabel="Open legal documents in external browser"
5646 accessibilityRole="button"
5747 hitSlop={12}
58 onPress={() => void Linking.openURL(externalUrl).catch(() => undefined)}
48 onPress={() => void Linking.openURL(safeExternalUrl).catch(() => undefined)}
5949 className="p-2 active:opacity-60"
6050 >
6151 <SymbolView
......@@ -83,6 +73,17 @@ export function SettingsLegalDocumentRouteScreen({
8373 const [reloadKey, setReloadKey] = useState(0);
8474 const [loadProgress, setLoadProgress] = useState(0);
8575 const [loadError, setLoadError] = useState<string | null>(null);
76 const [externalUrl, setExternalUrl] = useState(documentUrl);
77 const renderExternalHeaderButton = useCallback(
78 () => <SettingsLegalDocumentExternalHeaderButton externalUrl={externalUrl} />,
79 [externalUrl],
80 );
81
82 useLayoutEffect(() => {
83 navigation.setOptions({
84 headerRight: renderExternalHeaderButton,
85 });
86 }, [navigation, renderExternalHeaderButton]);
8687
8788 const openExternalUrl = useCallback((url: string) => {
8889 void Linking.openURL(url).catch(() => undefined);
......@@ -160,7 +161,7 @@ export function SettingsLegalDocumentRouteScreen({
160161 }}
161162 onLoadEnd={(event) => {
162163 if (isLegalDocumentUrl(event.nativeEvent.url)) {
163 navigation.setParams({ externalUrl: event.nativeEvent.url });
164 setExternalUrl(event.nativeEvent.url);
164165 }
165166 setLoadProgress(0);
166167 }}