Files
paseo/packages/app/src/components/add-host-method-modal.tsx
T
b6d49da4df Support F-Droid Android builds (#1768)
* fix(android): support source-based APK builds

Co-authored-by: Anton Lazarev <22821309+antonok-edm@users.noreply.github.com>

* fix(android): address fdroid review feedback

Co-authored-by: Anton Lazarev <22821309+antonok-edm@users.noreply.github.com>

* fix(android): complete the F-Droid build profile

* fix(app): isolate the F-Droid runtime flag

---------

Co-authored-by: Anton Lazarev <22821309+antonok-edm@users.noreply.github.com>
2026-07-13 17:18:19 +08:00

125 lines
3.8 KiB
TypeScript

import { useCallback, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Pressable, Text, View } from "react-native";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { QrCode, Link2, ClipboardPaste } from "lucide-react-native";
import { AdaptiveModalSheet, type SheetHeader } from "./adaptive-modal-sheet";
import { isFdroidBuild } from "@/constants/build-profile";
import { isNative } from "@/constants/platform";
const styles = StyleSheet.create((theme) => ({
option: {
flexDirection: "row",
alignItems: "center",
gap: theme.spacing[4],
padding: theme.spacing[4],
borderRadius: theme.borderRadius.xl,
backgroundColor: theme.colors.surface2,
borderWidth: 1,
borderColor: theme.colors.border,
},
optionText: {
color: theme.colors.foreground,
fontSize: theme.fontSize.base,
fontWeight: theme.fontWeight.normal,
},
optionSubtext: {
color: theme.colors.foregroundMuted,
fontSize: theme.fontSize.sm,
marginTop: theme.spacing[1],
},
optionBody: {
flex: 1,
},
}));
export interface AddHostMethodModalProps {
visible: boolean;
onClose: () => void;
onDirectConnection: () => void;
onScanQr: () => void;
onPasteLink: () => void;
}
export function AddHostMethodModal({
visible,
onClose,
onDirectConnection,
onScanQr,
onPasteLink,
}: AddHostMethodModalProps) {
const { theme } = useUnistyles();
const { t } = useTranslation();
const header = useMemo<SheetHeader>(() => ({ title: t("pairing.connectionMethods.title") }), [t]);
const handleDirect = useCallback(() => {
onDirectConnection();
}, [onDirectConnection]);
const handleScan = useCallback(() => {
onScanQr();
}, [onScanQr]);
const handlePaste = useCallback(() => {
onPasteLink();
}, [onPasteLink]);
return (
<AdaptiveModalSheet
header={header}
visible={visible}
onClose={onClose}
testID="add-host-method-modal"
>
<Pressable
style={styles.option}
onPress={handleDirect}
accessibilityRole="button"
accessibilityLabel={t("pairing.connectionMethods.direct.title")}
testID="add-host-method-direct"
>
<Link2 size={18} color={theme.colors.foreground} />
<View style={styles.optionBody}>
<Text style={styles.optionText}>{t("pairing.connectionMethods.direct.title")}</Text>
<Text style={styles.optionSubtext}>
{t("pairing.connectionMethods.direct.description")}
</Text>
</View>
</Pressable>
{isNative && !isFdroidBuild ? (
<Pressable
style={styles.option}
onPress={handleScan}
accessibilityRole="button"
accessibilityLabel={t("pairing.connectionMethods.scanQr.title")}
>
<QrCode size={18} color={theme.colors.foreground} />
<View style={styles.optionBody}>
<Text style={styles.optionText}>{t("pairing.connectionMethods.scanQr.title")}</Text>
<Text style={styles.optionSubtext}>
{t("pairing.connectionMethods.scanQr.description")}
</Text>
</View>
</Pressable>
) : null}
<Pressable
style={styles.option}
onPress={handlePaste}
accessibilityRole="button"
accessibilityLabel={t("pairing.connectionMethods.pasteLink.title")}
testID="add-host-method-pair-link"
>
<ClipboardPaste size={18} color={theme.colors.foreground} />
<View style={styles.optionBody}>
<Text style={styles.optionText}>{t("pairing.connectionMethods.pasteLink.title")}</Text>
<Text style={styles.optionSubtext}>
{t("pairing.connectionMethods.pasteLink.description")}
</Text>
</View>
</Pressable>
</AdaptiveModalSheet>
);
}