mirror of
https://github.com/EthanShoeDev/fressh.git
synced 2026-01-11 06:12:51 +00:00
inline styles
This commit is contained in:
@@ -36,9 +36,9 @@
|
||||
"@tanstack/react-form": "^1.20.0",
|
||||
"@tanstack/react-query": "^5.87.4",
|
||||
"date-fns": "^4.1.0",
|
||||
"expo": "54.0.7",
|
||||
"expo": "54.0.8",
|
||||
"expo-clipboard": "~8.0.7",
|
||||
"expo-constants": "~18.0.8",
|
||||
"expo-constants": "~18.0.9",
|
||||
"expo-crypto": "~15.0.7",
|
||||
"expo-dev-client": "~6.0.12",
|
||||
"expo-document-picker": "~14.0.7",
|
||||
@@ -48,7 +48,7 @@
|
||||
"expo-haptics": "~15.0.7",
|
||||
"expo-image": "~3.0.8",
|
||||
"expo-linking": "~8.0.8",
|
||||
"expo-router": "6.0.5",
|
||||
"expo-router": "6.0.6",
|
||||
"expo-secure-store": "~15.0.7",
|
||||
"expo-splash-screen": "~31.0.10",
|
||||
"expo-status-bar": "~3.0.8",
|
||||
|
||||
@@ -28,6 +28,3 @@ export default function KeyManagerModalRoute() {
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
// // styles kept for potential future local additions
|
||||
// const styles = StyleSheet.create({});
|
||||
|
||||
@@ -2,14 +2,7 @@ import SegmentedControl from '@react-native-segmented-control/segmented-control'
|
||||
import { useStore } from '@tanstack/react-form';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import React from 'react';
|
||||
import {
|
||||
Modal,
|
||||
Pressable,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { Modal, Pressable, ScrollView, Text, View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { useAppForm, useFieldContext } from '@/components/form-components';
|
||||
import { KeyList } from '@/components/key-manager/KeyList';
|
||||
@@ -19,7 +12,7 @@ import {
|
||||
secretsManager,
|
||||
type InputConnectionDetails,
|
||||
} from '@/lib/secrets-manager';
|
||||
import { useTheme, type AppTheme } from '@/lib/theme';
|
||||
import { useTheme } from '@/lib/theme';
|
||||
|
||||
export default function TabsIndex() {
|
||||
return <Host />;
|
||||
@@ -37,7 +30,6 @@ const defaultValues: InputConnectionDetails = {
|
||||
|
||||
function Host() {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
// const insets = useSafeAreaInsets();
|
||||
const sshConnMutation = useSshConnMutation();
|
||||
const connectionForm = useAppForm({
|
||||
@@ -62,23 +54,74 @@ function Host() {
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1, backgroundColor: theme.colors.background }}>
|
||||
<ScrollView
|
||||
contentContainerStyle={[styles.scrollContent]}
|
||||
contentContainerStyle={[{ paddingBottom: 32 }]}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
style={{ backgroundColor: theme.colors.background }}
|
||||
>
|
||||
<View
|
||||
style={[
|
||||
styles.container,
|
||||
{
|
||||
flex: 1,
|
||||
padding: 24,
|
||||
backgroundColor: theme.colors.background,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
{ backgroundColor: theme.colors.background },
|
||||
]}
|
||||
>
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.appName}>fressh</Text>
|
||||
<Text style={styles.appTagline}>A fast, friendly SSH client</Text>
|
||||
<View style={{ marginBottom: 16, alignItems: 'center' }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 28,
|
||||
fontWeight: '800',
|
||||
color: theme.colors.textPrimary,
|
||||
letterSpacing: 1,
|
||||
}}
|
||||
>
|
||||
fressh
|
||||
</Text>
|
||||
<Text
|
||||
style={{ marginTop: 4, fontSize: 13, color: theme.colors.muted }}
|
||||
>
|
||||
A fast, friendly SSH client
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.title}>Connect to SSH Server</Text>
|
||||
<Text style={styles.subtitle}>Enter your server credentials</Text>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: theme.colors.surface,
|
||||
borderRadius: 20,
|
||||
padding: 24,
|
||||
marginHorizontal: 4,
|
||||
shadowColor: theme.colors.shadow,
|
||||
shadowOpacity: 0.3,
|
||||
shadowRadius: 16,
|
||||
shadowOffset: { width: 0, height: 4 },
|
||||
elevation: 8,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.borderStrong,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 24,
|
||||
fontWeight: '700',
|
||||
color: theme.colors.textPrimary,
|
||||
marginBottom: 6,
|
||||
letterSpacing: 0.5,
|
||||
}}
|
||||
>
|
||||
Connect to SSH Server
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 15,
|
||||
color: theme.colors.muted,
|
||||
marginBottom: 24,
|
||||
lineHeight: 20,
|
||||
}}
|
||||
>
|
||||
Enter your server credentials
|
||||
</Text>
|
||||
|
||||
<connectionForm.AppForm>
|
||||
<connectionForm.AppField name="host">
|
||||
@@ -114,7 +157,7 @@ function Host() {
|
||||
</connectionForm.AppField>
|
||||
<connectionForm.AppField name="security.type">
|
||||
{(field) => (
|
||||
<View style={styles.inputGroup}>
|
||||
<View style={{ marginBottom: 12 }}>
|
||||
<SegmentedControl
|
||||
values={['Password', 'Private Key']}
|
||||
selectedIndex={field.state.value === 'password' ? 0 : 1}
|
||||
@@ -146,7 +189,7 @@ function Host() {
|
||||
</connectionForm.AppField>
|
||||
)}
|
||||
|
||||
<View style={styles.actions}>
|
||||
<View style={{ marginTop: 20 }}>
|
||||
<connectionForm.SubmitButton
|
||||
title="Connect"
|
||||
testID="connect"
|
||||
@@ -188,7 +231,6 @@ function Host() {
|
||||
|
||||
function KeyIdPickerField() {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
const field = useFieldContext<string>();
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
@@ -216,10 +258,29 @@ function KeyIdPickerField() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>Private Key</Text>
|
||||
<View style={{ marginBottom: 12 }}>
|
||||
<Text
|
||||
style={{
|
||||
marginBottom: 6,
|
||||
fontSize: 14,
|
||||
color: theme.colors.textSecondary,
|
||||
fontWeight: '600',
|
||||
}}
|
||||
>
|
||||
Private Key
|
||||
</Text>
|
||||
<Pressable
|
||||
style={[styles.input, { justifyContent: 'center' }]}
|
||||
style={[
|
||||
{
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
backgroundColor: theme.colors.inputBackground,
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
]}
|
||||
onPress={() => {
|
||||
void listPrivateKeysQuery.refetch();
|
||||
setOpen(true);
|
||||
@@ -228,7 +289,7 @@ function KeyIdPickerField() {
|
||||
<Text style={{ color: theme.colors.textPrimary }}>{display}</Text>
|
||||
</Pressable>
|
||||
{!selected && (
|
||||
<Text style={styles.mutedText}>
|
||||
<Text style={{ color: theme.colors.muted, fontSize: 14 }}>
|
||||
Open Key Manager to add/select a key
|
||||
</Text>
|
||||
)}
|
||||
@@ -239,15 +300,59 @@ function KeyIdPickerField() {
|
||||
animationType="slide"
|
||||
onRequestClose={() => setOpen(false)}
|
||||
>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.modalSheet}>
|
||||
<View style={styles.modalHeader}>
|
||||
<Text style={styles.title}>Select Key</Text>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: theme.colors.overlay,
|
||||
justifyContent: 'flex-end',
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: theme.colors.background,
|
||||
borderTopLeftRadius: 16,
|
||||
borderTopRightRadius: 16,
|
||||
padding: 16,
|
||||
borderColor: theme.colors.borderStrong,
|
||||
borderWidth: 1,
|
||||
maxHeight: '85%',
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
}}
|
||||
>
|
||||
Select Key
|
||||
</Text>
|
||||
<Pressable
|
||||
style={styles.modalCloseButton}
|
||||
style={{
|
||||
paddingHorizontal: 8,
|
||||
paddingVertical: 6,
|
||||
borderRadius: 8,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
}}
|
||||
onPress={() => setOpen(false)}
|
||||
>
|
||||
<Text style={styles.modalCloseText}>Close</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textSecondary,
|
||||
fontWeight: '600',
|
||||
}}
|
||||
>
|
||||
Close
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<KeyList
|
||||
@@ -268,18 +373,32 @@ function PreviousConnectionsSection(props: {
|
||||
onSelect: (connection: InputConnectionDetails) => void;
|
||||
}) {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
const listConnectionsQuery = useQuery(secretsManager.connections.query.list);
|
||||
|
||||
return (
|
||||
<View style={styles.listSection}>
|
||||
<Text style={styles.listTitle}>Previous Connections</Text>
|
||||
<View style={{ marginTop: 20 }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 16,
|
||||
fontWeight: '700',
|
||||
color: theme.colors.textPrimary,
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
Previous Connections
|
||||
</Text>
|
||||
{listConnectionsQuery.isLoading ? (
|
||||
<Text style={styles.mutedText}>Loading connections...</Text>
|
||||
<Text style={{ color: theme.colors.muted, fontSize: 14 }}>
|
||||
Loading connections...
|
||||
</Text>
|
||||
) : listConnectionsQuery.isError ? (
|
||||
<Text style={styles.errorText}>Error loading connections</Text>
|
||||
<Text
|
||||
style={{ marginTop: 6, color: theme.colors.danger, fontSize: 12 }}
|
||||
>
|
||||
Error loading connections
|
||||
</Text>
|
||||
) : listConnectionsQuery.data?.length ? (
|
||||
<View style={styles.listContainer}>
|
||||
<View>
|
||||
{listConnectionsQuery.data?.map((conn) => (
|
||||
<ConnectionRow
|
||||
key={conn.id}
|
||||
@@ -289,7 +408,9 @@ function PreviousConnectionsSection(props: {
|
||||
))}
|
||||
</View>
|
||||
) : (
|
||||
<Text style={styles.mutedText}>No saved connections yet</Text>
|
||||
<Text style={{ color: theme.colors.muted, fontSize: 14 }}>
|
||||
No saved connections yet
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
@@ -300,223 +421,51 @@ function ConnectionRow(props: {
|
||||
onSelect: (connection: InputConnectionDetails) => void;
|
||||
}) {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
const detailsQuery = useQuery(secretsManager.connections.query.get(props.id));
|
||||
const details = detailsQuery.data?.value;
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
style={styles.row}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: theme.colors.inputBackground,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
marginBottom: 8,
|
||||
}}
|
||||
onPress={() => {
|
||||
if (details) props.onSelect(details);
|
||||
}}
|
||||
disabled={!details}
|
||||
>
|
||||
<View style={styles.rowTextContainer}>
|
||||
<Text style={styles.rowTitle}>
|
||||
<View style={{ flex: 1, marginRight: 12 }}>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
}}
|
||||
>
|
||||
{details ? `${details.username}@${details.host}` : 'Loading...'}
|
||||
</Text>
|
||||
<Text style={styles.rowSubtitle}>
|
||||
<Text style={{ color: theme.colors.muted, marginTop: 2, fontSize: 12 }}>
|
||||
{details ? `Port ${details.port} • ${details.security.type}` : ''}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.rowChevron}>›</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.muted,
|
||||
fontSize: 22,
|
||||
paddingHorizontal: 4,
|
||||
}}
|
||||
>
|
||||
›
|
||||
</Text>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
function makeStyles(theme: AppTheme) {
|
||||
return StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
padding: 24,
|
||||
backgroundColor: theme.colors.background,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
scrollContent: {
|
||||
paddingBottom: 32,
|
||||
},
|
||||
header: {
|
||||
marginBottom: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
appName: {
|
||||
fontSize: 28,
|
||||
fontWeight: '800',
|
||||
color: theme.colors.textPrimary,
|
||||
letterSpacing: 1,
|
||||
},
|
||||
appTagline: {
|
||||
marginTop: 4,
|
||||
fontSize: 13,
|
||||
color: theme.colors.muted,
|
||||
},
|
||||
card: {
|
||||
backgroundColor: theme.colors.surface,
|
||||
borderRadius: 20,
|
||||
padding: 24,
|
||||
marginHorizontal: 4,
|
||||
shadowColor: theme.colors.shadow,
|
||||
shadowOpacity: 0.3,
|
||||
shadowRadius: 16,
|
||||
shadowOffset: { width: 0, height: 4 },
|
||||
elevation: 8,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.borderStrong,
|
||||
},
|
||||
title: {
|
||||
fontSize: 24,
|
||||
fontWeight: '700',
|
||||
color: theme.colors.textPrimary,
|
||||
marginBottom: 6,
|
||||
letterSpacing: 0.5,
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 15,
|
||||
color: theme.colors.muted,
|
||||
marginBottom: 24,
|
||||
lineHeight: 20,
|
||||
},
|
||||
inputGroup: {
|
||||
marginBottom: 12,
|
||||
},
|
||||
label: {
|
||||
marginBottom: 6,
|
||||
fontSize: 14,
|
||||
color: theme.colors.textSecondary,
|
||||
fontWeight: '600',
|
||||
},
|
||||
input: {
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
backgroundColor: theme.colors.inputBackground,
|
||||
color: theme.colors.textPrimary,
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
fontSize: 16,
|
||||
},
|
||||
errorText: {
|
||||
marginTop: 6,
|
||||
color: theme.colors.danger,
|
||||
fontSize: 12,
|
||||
},
|
||||
actions: {
|
||||
marginTop: 20,
|
||||
},
|
||||
mutedText: {
|
||||
color: theme.colors.muted,
|
||||
fontSize: 14,
|
||||
},
|
||||
submitButton: {
|
||||
backgroundColor: theme.colors.primary,
|
||||
borderRadius: 12,
|
||||
paddingVertical: 16,
|
||||
alignItems: 'center',
|
||||
shadowColor: theme.colors.primary,
|
||||
shadowOpacity: 0.3,
|
||||
shadowRadius: 8,
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
elevation: 4,
|
||||
},
|
||||
submitButtonText: {
|
||||
color: theme.colors.buttonTextOnPrimary,
|
||||
fontWeight: '700',
|
||||
fontSize: 16,
|
||||
letterSpacing: 0.5,
|
||||
},
|
||||
buttonDisabled: {
|
||||
backgroundColor: theme.colors.primaryDisabled,
|
||||
opacity: 0.6,
|
||||
},
|
||||
secondaryButton: {
|
||||
backgroundColor: theme.colors.transparent,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingVertical: 14,
|
||||
alignItems: 'center',
|
||||
marginTop: 12,
|
||||
},
|
||||
secondaryButtonText: {
|
||||
color: theme.colors.textSecondary,
|
||||
fontWeight: '600',
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
},
|
||||
listSection: {
|
||||
marginTop: 20,
|
||||
},
|
||||
listTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: '700',
|
||||
color: theme.colors.textPrimary,
|
||||
marginBottom: 8,
|
||||
},
|
||||
listContainer: {
|
||||
// Intentionally empty for RN compatibility
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: theme.colors.inputBackground,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
marginBottom: 8,
|
||||
},
|
||||
rowTextContainer: {
|
||||
flex: 1,
|
||||
marginRight: 12,
|
||||
},
|
||||
rowTitle: {
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
},
|
||||
rowSubtitle: {
|
||||
color: theme.colors.muted,
|
||||
marginTop: 2,
|
||||
fontSize: 12,
|
||||
},
|
||||
rowChevron: {
|
||||
color: theme.colors.muted,
|
||||
fontSize: 22,
|
||||
paddingHorizontal: 4,
|
||||
},
|
||||
modalOverlay: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.colors.overlay,
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
modalSheet: {
|
||||
backgroundColor: theme.colors.background,
|
||||
borderTopLeftRadius: 16,
|
||||
borderTopRightRadius: 16,
|
||||
padding: 16,
|
||||
borderColor: theme.colors.borderStrong,
|
||||
borderWidth: 1,
|
||||
maxHeight: '85%',
|
||||
},
|
||||
modalHeader: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 8,
|
||||
},
|
||||
modalCloseButton: {
|
||||
paddingHorizontal: 8,
|
||||
paddingVertical: 6,
|
||||
borderRadius: 8,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
},
|
||||
modalCloseText: {
|
||||
color: theme.colors.textSecondary,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
import { Link } from 'expo-router';
|
||||
import React from 'react';
|
||||
import { Pressable, StyleSheet, Text, View } from 'react-native';
|
||||
import { useTheme, useThemeControls, type AppTheme } from '@/lib/theme';
|
||||
import { Pressable, Text, View } from 'react-native';
|
||||
import { useTheme, useThemeControls } from '@/lib/theme';
|
||||
|
||||
export default function Tab() {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
const { themeName, setThemeName } = useThemeControls();
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Theme</Text>
|
||||
<View style={styles.rowGroup}>
|
||||
<View
|
||||
style={{ flex: 1, padding: 16, backgroundColor: theme.colors.background }}
|
||||
>
|
||||
<View style={{ marginBottom: 24 }}>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textSecondary,
|
||||
fontSize: 14,
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
Theme
|
||||
</Text>
|
||||
<View style={{ gap: 8 }}>
|
||||
<Row
|
||||
label="Dark"
|
||||
selected={themeName === 'dark'}
|
||||
@@ -26,12 +35,49 @@ export default function Tab() {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Security</Text>
|
||||
<View style={{ marginBottom: 24 }}>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textSecondary,
|
||||
fontSize: 14,
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
Security
|
||||
</Text>
|
||||
<Link href="/(tabs)/settings/key-manager" asChild>
|
||||
<Pressable style={styles.callout} accessibilityRole="button">
|
||||
<Text style={styles.calloutLabel}>Manage Keys</Text>
|
||||
<Text style={styles.calloutChevron}>›</Text>
|
||||
<Pressable
|
||||
style={{
|
||||
backgroundColor: theme.colors.surface,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 14,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
accessibilityRole="button"
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
}}
|
||||
>
|
||||
Manage Keys
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.muted,
|
||||
fontSize: 22,
|
||||
paddingHorizontal: 4,
|
||||
}}
|
||||
>
|
||||
›
|
||||
</Text>
|
||||
</Pressable>
|
||||
</Link>
|
||||
</View>
|
||||
@@ -49,81 +95,40 @@ function Row({
|
||||
onPress: () => void;
|
||||
}) {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
return (
|
||||
<Pressable
|
||||
onPress={onPress}
|
||||
style={[styles.row, selected && styles.rowSelected]}
|
||||
style={[
|
||||
{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: theme.colors.surface,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
},
|
||||
selected ? { borderColor: theme.colors.primary } : undefined,
|
||||
]}
|
||||
accessibilityRole="button"
|
||||
accessibilityState={{ selected }}
|
||||
>
|
||||
<Text style={styles.rowLabel}>{label}</Text>
|
||||
<Text style={styles.rowCheck}>{selected ? '✔' : ''}</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
<Text
|
||||
style={{ color: theme.colors.primary, fontSize: 16, fontWeight: '800' }}
|
||||
>
|
||||
{selected ? '✔' : ''}
|
||||
</Text>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
function makeStyles(theme: AppTheme) {
|
||||
return StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
padding: 16,
|
||||
backgroundColor: theme.colors.background,
|
||||
},
|
||||
// Title removed; screen header provides the title
|
||||
section: {
|
||||
marginBottom: 24,
|
||||
},
|
||||
sectionTitle: {
|
||||
color: theme.colors.textSecondary,
|
||||
fontSize: 14,
|
||||
marginBottom: 8,
|
||||
},
|
||||
rowGroup: { gap: 8 },
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: theme.colors.surface,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
},
|
||||
rowSelected: {
|
||||
borderColor: theme.colors.primary,
|
||||
},
|
||||
rowLabel: {
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
rowCheck: {
|
||||
color: theme.colors.primary,
|
||||
fontSize: 16,
|
||||
fontWeight: '800',
|
||||
},
|
||||
callout: {
|
||||
backgroundColor: theme.colors.surface,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 14,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
calloutLabel: {
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
calloutChevron: {
|
||||
color: theme.colors.muted,
|
||||
fontSize: 22,
|
||||
paddingHorizontal: 4,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
Platform,
|
||||
Pressable,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
@@ -36,8 +35,6 @@ function ShellDetail() {
|
||||
: undefined;
|
||||
|
||||
const [shellData, setShellData] = useState('');
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const hiddenInputRef = useRef<TextInput | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!connection) return;
|
||||
@@ -61,42 +58,11 @@ function ShellDetail() {
|
||||
scrollViewRef.current?.scrollToEnd({ animated: true });
|
||||
}, [shellData]);
|
||||
|
||||
useEffect(() => {
|
||||
const focusTimeout = setTimeout(() => {
|
||||
hiddenInputRef.current?.focus();
|
||||
}, 0);
|
||||
return () => clearTimeout(focusTimeout);
|
||||
}, []);
|
||||
|
||||
async function sendChunk(chunk: string) {
|
||||
if (!shell || !chunk) return;
|
||||
const bytes = Uint8Array.from(new TextEncoder().encode(chunk)).buffer;
|
||||
try {
|
||||
await shell.sendData(bytes);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1, backgroundColor: theme.colors.background }}>
|
||||
<Stack.Screen
|
||||
options={{
|
||||
headerBackVisible: true,
|
||||
headerLeft:
|
||||
Platform.OS === 'android'
|
||||
? () => (
|
||||
<Pressable
|
||||
onPress={() => router.back()}
|
||||
hitSlop={10}
|
||||
style={{ paddingHorizontal: 4, paddingVertical: 4 }}
|
||||
>
|
||||
<Ionicons
|
||||
name="chevron-back"
|
||||
size={22}
|
||||
color={theme.colors.textPrimary}
|
||||
/>
|
||||
</Pressable>
|
||||
)
|
||||
: undefined,
|
||||
headerRight: () => (
|
||||
<Pressable
|
||||
accessibilityLabel="Disconnect"
|
||||
@@ -114,93 +80,120 @@ function ShellDetail() {
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={[styles.container, { backgroundColor: theme.colors.background }]}
|
||||
style={[
|
||||
{ flex: 1, backgroundColor: '#0B1324', padding: 12 },
|
||||
{ backgroundColor: theme.colors.background },
|
||||
]}
|
||||
>
|
||||
<View
|
||||
style={styles.terminal}
|
||||
onStartShouldSetResponder={() => {
|
||||
hiddenInputRef.current?.focus();
|
||||
return false;
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: '#0E172B',
|
||||
borderRadius: 12,
|
||||
height: 400,
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
overflow: 'hidden',
|
||||
marginBottom: 12,
|
||||
}}
|
||||
>
|
||||
<ScrollView
|
||||
ref={scrollViewRef}
|
||||
contentContainerStyle={styles.terminalContent}
|
||||
contentContainerStyle={{
|
||||
paddingHorizontal: 12,
|
||||
paddingTop: 4,
|
||||
paddingBottom: 12,
|
||||
}}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
>
|
||||
<Text selectable style={styles.terminalText}>
|
||||
<Text
|
||||
selectable
|
||||
style={{
|
||||
color: '#D1D5DB',
|
||||
fontSize: 14,
|
||||
lineHeight: 18,
|
||||
fontFamily: Platform.select({
|
||||
ios: 'Menlo',
|
||||
android: 'monospace',
|
||||
default: 'monospace',
|
||||
}),
|
||||
}}
|
||||
>
|
||||
{shellData || 'Connected. Output will appear here...'}
|
||||
</Text>
|
||||
</ScrollView>
|
||||
<TextInput
|
||||
ref={hiddenInputRef}
|
||||
value={inputValue}
|
||||
onChangeText={async (text) => {
|
||||
if (!text) return;
|
||||
await sendChunk(text);
|
||||
setInputValue('');
|
||||
}}
|
||||
onKeyPress={async (e) => {
|
||||
const key = e.nativeEvent.key;
|
||||
if (key === 'Backspace') {
|
||||
await sendChunk('\b');
|
||||
}
|
||||
}}
|
||||
onSubmitEditing={async () => {
|
||||
await sendChunk('\n');
|
||||
}}
|
||||
style={styles.hiddenInput}
|
||||
autoFocus
|
||||
multiline
|
||||
caretHidden
|
||||
autoCorrect={false}
|
||||
autoCapitalize="none"
|
||||
keyboardType="visible-password"
|
||||
blurOnSubmit={false}
|
||||
/>
|
||||
</View>
|
||||
<CommandInput
|
||||
executeCommand={async (command) => {
|
||||
await shell?.sendData(
|
||||
Uint8Array.from(new TextEncoder().encode(command + '\n')).buffer,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#0B1324',
|
||||
padding: 12,
|
||||
},
|
||||
terminal: {
|
||||
flex: 1,
|
||||
backgroundColor: '#0E172B',
|
||||
borderRadius: 12,
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
overflow: 'hidden',
|
||||
marginBottom: 12,
|
||||
},
|
||||
terminalContent: {
|
||||
paddingHorizontal: 12,
|
||||
paddingTop: 4,
|
||||
paddingBottom: 12,
|
||||
},
|
||||
terminalText: {
|
||||
color: '#D1D5DB',
|
||||
fontSize: 14,
|
||||
lineHeight: 18,
|
||||
fontFamily: Platform.select({
|
||||
ios: 'Menlo',
|
||||
android: 'monospace',
|
||||
default: 'monospace',
|
||||
}),
|
||||
},
|
||||
hiddenInput: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
opacity: 0,
|
||||
color: 'transparent',
|
||||
},
|
||||
});
|
||||
function CommandInput(props: {
|
||||
executeCommand: (command: string) => Promise<void>;
|
||||
}) {
|
||||
const [command, setCommand] = useState('');
|
||||
|
||||
async function handleExecute() {
|
||||
if (!command.trim()) return;
|
||||
await props.executeCommand(command);
|
||||
setCommand('');
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
||||
<TextInput
|
||||
testID="command-input"
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: '#0E172B',
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
color: '#E5E7EB',
|
||||
fontSize: 16,
|
||||
fontFamily: Platform.select({
|
||||
ios: 'Menlo',
|
||||
android: 'monospace',
|
||||
default: 'monospace',
|
||||
}),
|
||||
}}
|
||||
value={command}
|
||||
onChangeText={setCommand}
|
||||
placeholder="Type a command and press Enter or Execute"
|
||||
placeholderTextColor="#9AA0A6"
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
returnKeyType="send"
|
||||
onSubmitEditing={handleExecute}
|
||||
/>
|
||||
<Pressable
|
||||
style={[
|
||||
{
|
||||
backgroundColor: '#2563EB',
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
{ marginTop: 8 },
|
||||
]}
|
||||
onPress={handleExecute}
|
||||
testID="execute-button"
|
||||
>
|
||||
<Text style={{ color: '#FFFFFF', fontWeight: '700', fontSize: 14 }}>
|
||||
Execute
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
Modal,
|
||||
Platform,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
@@ -25,7 +24,7 @@ import {
|
||||
listSshShellsQueryOptions,
|
||||
type ShellWithConnection,
|
||||
} from '@/lib/query-fns';
|
||||
import { useTheme, type AppTheme } from '@/lib/theme';
|
||||
import { useTheme } from '@/lib/theme';
|
||||
|
||||
export default function TabsShellList() {
|
||||
const theme = useTheme();
|
||||
@@ -59,10 +58,16 @@ function ShellContent() {
|
||||
|
||||
function LoadingState() {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
return (
|
||||
<View style={styles.centerContent}>
|
||||
<Text style={styles.mutedText}>Loading...</Text>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 12,
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: theme.colors.muted }}>Loading...</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -177,7 +182,6 @@ function GroupedView({
|
||||
setActionTarget: (target: ActionTarget) => void;
|
||||
}) {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
const [expanded, setExpanded] = React.useState<Record<string, boolean>>({});
|
||||
return (
|
||||
<FlashList
|
||||
@@ -185,9 +189,19 @@ function GroupedView({
|
||||
// estimatedItemSize={80}
|
||||
keyExtractor={(item) => item.connectionId}
|
||||
renderItem={({ item }) => (
|
||||
<View style={styles.groupContainer}>
|
||||
<View style={{ gap: 12 }}>
|
||||
<Pressable
|
||||
style={styles.groupHeader}
|
||||
style={{
|
||||
backgroundColor: theme.colors.surface,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
onPress={() =>
|
||||
setExpanded((prev) => ({
|
||||
...prev,
|
||||
@@ -196,15 +210,27 @@ function GroupedView({
|
||||
}
|
||||
>
|
||||
<View>
|
||||
<Text style={styles.groupTitle}>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 16,
|
||||
fontWeight: '700',
|
||||
}}
|
||||
>
|
||||
{item.connectionDetails.username}@{item.connectionDetails.host}
|
||||
</Text>
|
||||
<Text style={styles.groupSubtitle}>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.muted,
|
||||
fontSize: 12,
|
||||
marginTop: 2,
|
||||
}}
|
||||
>
|
||||
Port {item.connectionDetails.port} • {item.shells.length} shell
|
||||
{item.shells.length === 1 ? '' : 's'}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.groupChevron}>
|
||||
<Text style={{ color: theme.colors.muted, fontSize: 18 }}>
|
||||
{expanded[item.connectionId] ? '▾' : '▸'}
|
||||
</Text>
|
||||
</Pressable>
|
||||
@@ -237,13 +263,19 @@ function GroupedView({
|
||||
|
||||
function EmptyState() {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
return (
|
||||
<View style={styles.centerContent}>
|
||||
<Text style={styles.mutedText}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 12,
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: theme.colors.muted }}>
|
||||
No active shells. Connect from Host tab.
|
||||
</Text>
|
||||
<Link href="/" style={styles.link}>
|
||||
<Link href="/" style={{ color: theme.colors.primary, fontWeight: '600' }}>
|
||||
Go to Hosts
|
||||
</Link>
|
||||
</View>
|
||||
@@ -258,14 +290,23 @@ function ShellCard({
|
||||
onLongPress?: () => void;
|
||||
}) {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
const router = useRouter();
|
||||
const since = formatDistanceToNow(new Date(shell.createdAtMs), {
|
||||
addSuffix: true,
|
||||
});
|
||||
return (
|
||||
<Pressable
|
||||
style={styles.card}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: theme.colors.inputBackground,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
}}
|
||||
onPress={() =>
|
||||
router.push({
|
||||
pathname: '/shell/detail',
|
||||
@@ -278,16 +319,40 @@ function ShellCard({
|
||||
onLongPress={onLongPress}
|
||||
>
|
||||
<View style={{ flex: 1 }}>
|
||||
<Text style={styles.cardTitle} numberOfLines={1}>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
}}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{shell.connection.connectionDetails.username}@
|
||||
{shell.connection.connectionDetails.host}
|
||||
</Text>
|
||||
<Text style={styles.cardSubtitle} numberOfLines={1}>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textSecondary,
|
||||
fontSize: 12,
|
||||
marginTop: 2,
|
||||
}}
|
||||
numberOfLines={1}
|
||||
>
|
||||
Port {shell.connection.connectionDetails.port} • {shell.pty}
|
||||
</Text>
|
||||
<Text style={styles.cardMeta}>Started {since}</Text>
|
||||
<Text style={{ color: theme.colors.muted, fontSize: 12, marginTop: 6 }}>
|
||||
Started {since}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.cardChevron}>›</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.muted,
|
||||
fontSize: 22,
|
||||
paddingHorizontal: 4,
|
||||
}}
|
||||
>
|
||||
›
|
||||
</Text>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
@@ -304,7 +369,6 @@ function ActionsSheet({
|
||||
onDisconnect: () => void;
|
||||
}) {
|
||||
const theme = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(theme), [theme]);
|
||||
const open = !!target;
|
||||
return (
|
||||
<Modal
|
||||
@@ -313,22 +377,98 @@ function ActionsSheet({
|
||||
animationType="slide"
|
||||
onRequestClose={onClose}
|
||||
>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.modalSheet}>
|
||||
<Text style={styles.title}>Shell Actions</Text>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: theme.colors.overlay,
|
||||
justifyContent: 'flex-end',
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: theme.colors.background,
|
||||
borderTopLeftRadius: 16,
|
||||
borderTopRightRadius: 16,
|
||||
padding: 16,
|
||||
borderColor: theme.colors.borderStrong,
|
||||
borderWidth: 1,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
}}
|
||||
>
|
||||
Shell Actions
|
||||
</Text>
|
||||
<View style={{ height: 12 }} />
|
||||
<Pressable style={styles.primaryButton} onPress={onCloseShell}>
|
||||
<Text style={styles.primaryButtonText}>Close Shell</Text>
|
||||
<Pressable
|
||||
style={{
|
||||
backgroundColor: theme.colors.primary,
|
||||
borderRadius: 12,
|
||||
paddingVertical: 14,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onPress={onCloseShell}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.buttonTextOnPrimary,
|
||||
fontWeight: '700',
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
}}
|
||||
>
|
||||
Close Shell
|
||||
</Text>
|
||||
</Pressable>
|
||||
<View style={{ height: 8 }} />
|
||||
<Pressable style={styles.secondaryButton} onPress={onDisconnect}>
|
||||
<Text style={styles.secondaryButtonText}>
|
||||
<Pressable
|
||||
style={{
|
||||
backgroundColor: theme.colors.transparent,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingVertical: 14,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onPress={onDisconnect}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textSecondary,
|
||||
fontWeight: '600',
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
}}
|
||||
>
|
||||
Disconnect Connection
|
||||
</Text>
|
||||
</Pressable>
|
||||
<View style={{ height: 8 }} />
|
||||
<Pressable style={styles.secondaryButton} onPress={onClose}>
|
||||
<Text style={styles.secondaryButtonText}>Cancel</Text>
|
||||
<Pressable
|
||||
style={{
|
||||
backgroundColor: theme.colors.transparent,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingVertical: 14,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onPress={onClose}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colors.textSecondary,
|
||||
fontWeight: '600',
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
@@ -382,125 +522,3 @@ function HeaderViewModeButton() {
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
function makeStyles(theme: AppTheme) {
|
||||
return StyleSheet.create({
|
||||
centerContent: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 12,
|
||||
},
|
||||
mutedText: { color: theme.colors.muted },
|
||||
link: { color: theme.colors.primary, fontWeight: '600' },
|
||||
|
||||
// headerBar/title removed in favor of TopBarToggle
|
||||
|
||||
groupContainer: {
|
||||
gap: 12,
|
||||
},
|
||||
groupHeader: {
|
||||
backgroundColor: theme.colors.surface,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
groupTitle: {
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 16,
|
||||
fontWeight: '700',
|
||||
},
|
||||
groupSubtitle: {
|
||||
color: theme.colors.muted,
|
||||
fontSize: 12,
|
||||
marginTop: 2,
|
||||
},
|
||||
groupChevron: {
|
||||
color: theme.colors.muted,
|
||||
fontSize: 18,
|
||||
},
|
||||
|
||||
card: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: theme.colors.inputBackground,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
},
|
||||
cardTitle: {
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
},
|
||||
cardSubtitle: {
|
||||
color: theme.colors.textSecondary,
|
||||
fontSize: 12,
|
||||
marginTop: 2,
|
||||
},
|
||||
cardMeta: {
|
||||
color: theme.colors.muted,
|
||||
fontSize: 12,
|
||||
marginTop: 6,
|
||||
},
|
||||
cardChevron: {
|
||||
color: theme.colors.muted,
|
||||
fontSize: 22,
|
||||
paddingHorizontal: 4,
|
||||
},
|
||||
|
||||
modalOverlay: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.colors.overlay,
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
modalSheet: {
|
||||
backgroundColor: theme.colors.background,
|
||||
borderTopLeftRadius: 16,
|
||||
borderTopRightRadius: 16,
|
||||
padding: 16,
|
||||
borderColor: theme.colors.borderStrong,
|
||||
borderWidth: 1,
|
||||
},
|
||||
title: {
|
||||
color: theme.colors.textPrimary,
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
},
|
||||
|
||||
primaryButton: {
|
||||
backgroundColor: theme.colors.primary,
|
||||
borderRadius: 12,
|
||||
paddingVertical: 14,
|
||||
alignItems: 'center',
|
||||
},
|
||||
primaryButtonText: {
|
||||
color: theme.colors.buttonTextOnPrimary,
|
||||
fontWeight: '700',
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
},
|
||||
secondaryButton: {
|
||||
backgroundColor: theme.colors.transparent,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.colors.border,
|
||||
borderRadius: 12,
|
||||
paddingVertical: 14,
|
||||
alignItems: 'center',
|
||||
},
|
||||
secondaryButtonText: {
|
||||
color: theme.colors.textSecondary,
|
||||
fontWeight: '600',
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { QueryClientProvider } from '@tanstack/react-query';
|
||||
import * as DevClient from 'expo-dev-client';
|
||||
import { isLiquidGlassAvailable } from 'expo-glass-effect';
|
||||
import { Stack } from 'expo-router';
|
||||
import React from 'react';
|
||||
@@ -10,6 +11,15 @@ console.log('Fressh App Init', {
|
||||
isLiquidGlassAvailable: isLiquidGlassAvailable(),
|
||||
});
|
||||
|
||||
void DevClient.registerDevMenuItems([
|
||||
{
|
||||
callback: () => {
|
||||
console.log('Hello from dev menu');
|
||||
},
|
||||
name: 'Hello from dev menu',
|
||||
},
|
||||
]);
|
||||
|
||||
export default function RootLayout() {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
|
||||
@@ -3,14 +3,7 @@ import {
|
||||
createFormHookContexts,
|
||||
useStore,
|
||||
} from '@tanstack/react-form';
|
||||
import {
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Switch,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { Pressable, Switch, Text, TextInput, View } from 'react-native';
|
||||
|
||||
function FieldInfo() {
|
||||
const field = useFieldContext();
|
||||
@@ -18,9 +11,11 @@ function FieldInfo() {
|
||||
const errorMessage = meta?.errors?.[0]; // TODO: typesafe errors
|
||||
|
||||
return (
|
||||
<View style={styles.fieldInfo}>
|
||||
<View style={{ marginTop: 6 }}>
|
||||
{errorMessage ? (
|
||||
<Text style={styles.errorText}>{String(errorMessage)}</Text>
|
||||
<Text style={{ color: '#FCA5A5', fontSize: 12 }}>
|
||||
{String(errorMessage)}
|
||||
</Text>
|
||||
) : null}
|
||||
</View>
|
||||
);
|
||||
@@ -36,10 +31,33 @@ export function TextField(
|
||||
const field = useFieldContext<string>();
|
||||
|
||||
return (
|
||||
<View style={styles.inputGroup}>
|
||||
{label ? <Text style={styles.label}>{label}</Text> : null}
|
||||
<View style={{ marginBottom: 16 }}>
|
||||
{label ? (
|
||||
<Text
|
||||
style={{
|
||||
marginBottom: 6,
|
||||
fontSize: 14,
|
||||
color: '#C6CBD3',
|
||||
fontWeight: '600',
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
) : null}
|
||||
<TextInput
|
||||
style={[styles.input, style]}
|
||||
style={[
|
||||
{
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
backgroundColor: '#0E172B',
|
||||
color: '#E5E7EB',
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
fontSize: 16,
|
||||
},
|
||||
style,
|
||||
]}
|
||||
placeholderTextColor="#9AA0A6"
|
||||
value={field.state.value}
|
||||
onChangeText={field.handleChange}
|
||||
@@ -59,11 +77,34 @@ export function NumberField(
|
||||
const { label, style, keyboardType, onChangeText, ...rest } = props;
|
||||
const field = useFieldContext<number>();
|
||||
return (
|
||||
<View style={styles.inputGroup}>
|
||||
{label ? <Text style={styles.label}>{label}</Text> : null}
|
||||
<View style={{ marginBottom: 16 }}>
|
||||
{label ? (
|
||||
<Text
|
||||
style={{
|
||||
marginBottom: 6,
|
||||
fontSize: 14,
|
||||
color: '#C6CBD3',
|
||||
fontWeight: '600',
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
) : null}
|
||||
<TextInput
|
||||
keyboardType={keyboardType ?? 'numeric'}
|
||||
style={[styles.input, style]}
|
||||
style={[
|
||||
{
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
backgroundColor: '#0E172B',
|
||||
color: '#E5E7EB',
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
fontSize: 16,
|
||||
},
|
||||
style,
|
||||
]}
|
||||
placeholderTextColor="#9AA0A6"
|
||||
value={field.state.value.toString()}
|
||||
onChangeText={(text) => field.handleChange(Number(text))}
|
||||
@@ -84,10 +125,31 @@ export function SwitchField(
|
||||
const field = useFieldContext<boolean>();
|
||||
|
||||
return (
|
||||
<View style={styles.inputGroup}>
|
||||
{label ? <Text style={styles.label}>{label}</Text> : null}
|
||||
<View style={{ marginBottom: 16 }}>
|
||||
{label ? (
|
||||
<Text
|
||||
style={{
|
||||
marginBottom: 6,
|
||||
fontSize: 14,
|
||||
color: '#C6CBD3',
|
||||
fontWeight: '600',
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
) : null}
|
||||
<Switch
|
||||
style={[styles.input, style]}
|
||||
style={[
|
||||
{
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
backgroundColor: '#0E172B',
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
},
|
||||
style,
|
||||
]}
|
||||
value={field.state.value}
|
||||
onChange={(event) => field.handleChange(event.nativeEvent.value)}
|
||||
onBlur={field.handleBlur}
|
||||
@@ -114,13 +176,18 @@ export function SubmitButton(
|
||||
<Pressable
|
||||
{...rest}
|
||||
style={[
|
||||
styles.submitButton,
|
||||
disabled ? styles.buttonDisabled : undefined,
|
||||
{
|
||||
backgroundColor: '#2563EB',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 14,
|
||||
alignItems: 'center',
|
||||
},
|
||||
disabled ? { backgroundColor: '#3B82F6', opacity: 0.6 } : undefined,
|
||||
]}
|
||||
onPress={onPress}
|
||||
disabled={disabled || isSubmitting}
|
||||
>
|
||||
<Text style={styles.submitButtonText}>
|
||||
<Text style={{ color: '#FFFFFF', fontWeight: '700', fontSize: 16 }}>
|
||||
{isSubmitting ? 'Connecting...' : title}
|
||||
</Text>
|
||||
</Pressable>
|
||||
@@ -145,56 +212,4 @@ export const { useAppForm, withForm, withFieldGroup } = createFormHook({
|
||||
formContext,
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
inputGroup: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
label: {
|
||||
marginBottom: 6,
|
||||
fontSize: 14,
|
||||
color: '#C6CBD3',
|
||||
fontWeight: '600',
|
||||
},
|
||||
input: {
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
backgroundColor: '#0E172B',
|
||||
color: '#E5E7EB',
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
fontSize: 16,
|
||||
},
|
||||
errorText: {
|
||||
marginTop: 6,
|
||||
color: '#FCA5A5',
|
||||
fontSize: 12,
|
||||
},
|
||||
submitButton: {
|
||||
backgroundColor: '#2563EB',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 14,
|
||||
alignItems: 'center',
|
||||
},
|
||||
submitButtonText: {
|
||||
color: '#FFFFFF',
|
||||
fontWeight: '700',
|
||||
fontSize: 16,
|
||||
},
|
||||
buttonDisabled: {
|
||||
backgroundColor: '#3B82F6',
|
||||
opacity: 0.6,
|
||||
},
|
||||
fieldInfo: {
|
||||
marginTop: 6,
|
||||
color: '#FCA5A5',
|
||||
fontSize: 12,
|
||||
},
|
||||
pickerContainer: {
|
||||
paddingHorizontal: 8,
|
||||
paddingVertical: 4,
|
||||
},
|
||||
picker: {
|
||||
color: '#E5E7EB',
|
||||
},
|
||||
});
|
||||
// Styles inlined per component
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
import React from 'react';
|
||||
import {
|
||||
Pressable,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { Pressable, ScrollView, Text, TextInput, View } from 'react-native';
|
||||
import { secretsManager } from '@/lib/secrets-manager';
|
||||
|
||||
export type KeyListMode = 'manage' | 'select';
|
||||
@@ -38,13 +31,19 @@ export function KeyList(props: {
|
||||
<ScrollView contentContainerStyle={{ padding: 16 }}>
|
||||
<Pressable
|
||||
style={[
|
||||
styles.primaryButton,
|
||||
{
|
||||
backgroundColor: '#2563EB',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 12,
|
||||
alignItems: 'center',
|
||||
marginBottom: 12,
|
||||
},
|
||||
generateMutation.isPending && { opacity: 0.7 },
|
||||
]}
|
||||
disabled={generateMutation.isPending}
|
||||
onPress={() => generateMutation.mutate()}
|
||||
>
|
||||
<Text style={styles.primaryButtonText}>
|
||||
<Text style={{ color: '#FFFFFF', fontWeight: '700', fontSize: 14 }}>
|
||||
{generateMutation.isPending
|
||||
? 'Generating…'
|
||||
: 'Generate New RSA 4096 Key'}
|
||||
@@ -52,9 +51,9 @@ export function KeyList(props: {
|
||||
</Pressable>
|
||||
|
||||
{listKeysQuery.isLoading ? (
|
||||
<Text style={styles.muted}>Loading keys…</Text>
|
||||
<Text style={{ color: '#9AA0A6' }}>Loading keys…</Text>
|
||||
) : listKeysQuery.isError ? (
|
||||
<Text style={styles.error}>Error loading keys</Text>
|
||||
<Text style={{ color: '#FCA5A5' }}>Error loading keys</Text>
|
||||
) : listKeysQuery.data?.length ? (
|
||||
<View>
|
||||
{listKeysQuery.data.map((k) => (
|
||||
@@ -67,7 +66,7 @@ export function KeyList(props: {
|
||||
))}
|
||||
</View>
|
||||
) : (
|
||||
<Text style={styles.muted}>No keys yet</Text>
|
||||
<Text style={{ color: '#9AA0A6' }}>No keys yet</Text>
|
||||
)}
|
||||
</ScrollView>
|
||||
);
|
||||
@@ -135,16 +134,41 @@ function KeyRow(props: {
|
||||
if (!entry) return null;
|
||||
|
||||
return (
|
||||
<View style={styles.row}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: '#0E172B',
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
<View style={{ flex: 1, marginRight: 8 }}>
|
||||
<Text style={styles.rowTitle}>
|
||||
<Text style={{ color: '#E5E7EB', fontSize: 15, fontWeight: '600' }}>
|
||||
{entry.manifestEntry.metadata?.label ?? entry.manifestEntry.id}
|
||||
{entry.manifestEntry.metadata?.isDefault ? ' • Default' : ''}
|
||||
</Text>
|
||||
<Text style={styles.rowSub}>ID: {entry.manifestEntry.id}</Text>
|
||||
<Text style={{ color: '#9AA0A6', fontSize: 12, marginTop: 2 }}>
|
||||
ID: {entry.manifestEntry.id}
|
||||
</Text>
|
||||
{props.mode === 'manage' ? (
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
backgroundColor: '#0E172B',
|
||||
color: '#E5E7EB',
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 10,
|
||||
fontSize: 16,
|
||||
marginTop: 8,
|
||||
}}
|
||||
placeholder="Display name"
|
||||
placeholderTextColor="#9AA0A6"
|
||||
value={label}
|
||||
@@ -152,103 +176,80 @@ function KeyRow(props: {
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
<View style={styles.rowActions}>
|
||||
<View style={{ gap: 6, alignItems: 'flex-end' }}>
|
||||
{props.mode === 'select' ? (
|
||||
<Pressable
|
||||
onPress={() => setDefaultMutation.mutate()}
|
||||
style={styles.primaryButton}
|
||||
style={{
|
||||
backgroundColor: '#2563EB',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 10,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Text style={styles.primaryButtonText}>Select</Text>
|
||||
<Text style={{ color: '#FFFFFF', fontWeight: '700', fontSize: 12 }}>
|
||||
Select
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
{props.mode === 'manage' ? (
|
||||
<Pressable
|
||||
style={[
|
||||
styles.secondaryButton,
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 10,
|
||||
alignItems: 'center',
|
||||
},
|
||||
renameMutation.isPending && { opacity: 0.6 },
|
||||
]}
|
||||
onPress={() => renameMutation.mutate(label)}
|
||||
disabled={renameMutation.isPending}
|
||||
>
|
||||
<Text style={styles.secondaryButtonText}>
|
||||
<Text style={{ color: '#C6CBD3', fontWeight: '600', fontSize: 12 }}>
|
||||
{renameMutation.isPending ? 'Saving…' : 'Save'}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
{!entry.manifestEntry.metadata?.isDefault ? (
|
||||
<Pressable
|
||||
style={styles.secondaryButton}
|
||||
style={{
|
||||
backgroundColor: 'transparent',
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 10,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onPress={() => setDefaultMutation.mutate()}
|
||||
>
|
||||
<Text style={styles.secondaryButtonText}>Set Default</Text>
|
||||
<Text style={{ color: '#C6CBD3', fontWeight: '600', fontSize: 12 }}>
|
||||
Set Default
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
<Pressable
|
||||
style={styles.dangerButton}
|
||||
style={{
|
||||
backgroundColor: 'transparent',
|
||||
borderWidth: 1,
|
||||
borderColor: '#7F1D1D',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 10,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onPress={() => deleteMutation.mutate()}
|
||||
>
|
||||
<Text style={styles.dangerButtonText}>Delete</Text>
|
||||
<Text style={{ color: '#FCA5A5', fontWeight: '700', fontSize: 12 }}>
|
||||
Delete
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
primaryButton: {
|
||||
backgroundColor: '#2563EB',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 12,
|
||||
alignItems: 'center',
|
||||
marginBottom: 12,
|
||||
},
|
||||
primaryButtonText: { color: '#FFFFFF', fontWeight: '700', fontSize: 14 },
|
||||
muted: { color: '#9AA0A6' },
|
||||
error: { color: '#FCA5A5' },
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: '#0E172B',
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
marginBottom: 10,
|
||||
},
|
||||
rowTitle: { color: '#E5E7EB', fontSize: 15, fontWeight: '600' },
|
||||
rowSub: { color: '#9AA0A6', fontSize: 12, marginTop: 2 },
|
||||
rowActions: { gap: 6, alignItems: 'flex-end' },
|
||||
secondaryButton: {
|
||||
backgroundColor: 'transparent',
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 10,
|
||||
alignItems: 'center',
|
||||
},
|
||||
secondaryButtonText: { color: '#C6CBD3', fontWeight: '600', fontSize: 12 },
|
||||
dangerButton: {
|
||||
backgroundColor: 'transparent',
|
||||
borderWidth: 1,
|
||||
borderColor: '#7F1D1D',
|
||||
borderRadius: 10,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 10,
|
||||
alignItems: 'center',
|
||||
},
|
||||
dangerButtonText: { color: '#FCA5A5', fontWeight: '700', fontSize: 12 },
|
||||
input: {
|
||||
borderWidth: 1,
|
||||
borderColor: '#2A3655',
|
||||
backgroundColor: '#0E172B',
|
||||
color: '#E5E7EB',
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 10,
|
||||
fontSize: 16,
|
||||
marginTop: 8,
|
||||
},
|
||||
});
|
||||
|
||||
284
pnpm-lock.yaml
generated
284
pnpm-lock.yaml
generated
@@ -42,7 +42,7 @@ importers:
|
||||
dependencies:
|
||||
'@expo/vector-icons':
|
||||
specifier: ^15.0.2
|
||||
version: 15.0.2(expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
version: 15.0.2(expo-font@14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
'@fressh/assets':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/assets
|
||||
@@ -74,59 +74,59 @@ importers:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0
|
||||
expo:
|
||||
specifier: 54.0.7
|
||||
version: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
specifier: 54.0.8
|
||||
version: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-clipboard:
|
||||
specifier: ~8.0.7
|
||||
version: 8.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
version: 8.0.7(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-constants:
|
||||
specifier: ~18.0.8
|
||||
version: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
specifier: ~18.0.9
|
||||
version: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-crypto:
|
||||
specifier: ~15.0.7
|
||||
version: 15.0.7(expo@54.0.7)
|
||||
version: 15.0.7(expo@54.0.8)
|
||||
expo-dev-client:
|
||||
specifier: ~6.0.12
|
||||
version: 6.0.12(expo@54.0.7)
|
||||
version: 6.0.12(expo@54.0.8)
|
||||
expo-document-picker:
|
||||
specifier: ~14.0.7
|
||||
version: 14.0.7(expo@54.0.7)
|
||||
version: 14.0.7(expo@54.0.8)
|
||||
expo-file-system:
|
||||
specifier: ~19.0.14
|
||||
version: 19.0.14(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
version: 19.0.14(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-font:
|
||||
specifier: ~14.0.8
|
||||
version: 14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
version: 14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-glass-effect:
|
||||
specifier: ^0.1.3
|
||||
version: 0.1.3(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
version: 0.1.3(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-haptics:
|
||||
specifier: ~15.0.7
|
||||
version: 15.0.7(expo@54.0.7)
|
||||
version: 15.0.7(expo@54.0.8)
|
||||
expo-image:
|
||||
specifier: ~3.0.8
|
||||
version: 3.0.8(expo@54.0.7)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
version: 3.0.8(expo@54.0.8)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-linking:
|
||||
specifier: ~8.0.8
|
||||
version: 8.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
version: 8.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-router:
|
||||
specifier: 6.0.5
|
||||
version: 6.0.5(750b4158402c81723fe42a215de7942a)
|
||||
specifier: 6.0.6
|
||||
version: 6.0.6(be6ce5c43438e2db372447bf3c6a78fa)
|
||||
expo-secure-store:
|
||||
specifier: ~15.0.7
|
||||
version: 15.0.7(expo@54.0.7)
|
||||
version: 15.0.7(expo@54.0.8)
|
||||
expo-splash-screen:
|
||||
specifier: ~31.0.10
|
||||
version: 31.0.10(expo@54.0.7)
|
||||
version: 31.0.10(expo@54.0.8)
|
||||
expo-status-bar:
|
||||
specifier: ~3.0.8
|
||||
version: 3.0.8(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-symbols:
|
||||
specifier: ~1.0.7
|
||||
version: 1.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
version: 1.0.7(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-system-ui:
|
||||
specifier: ~6.0.7
|
||||
version: 6.0.7(expo@54.0.7)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
version: 6.0.7(expo@54.0.8)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
react:
|
||||
specifier: 19.1.0
|
||||
version: 19.1.0
|
||||
@@ -1297,8 +1297,8 @@ packages:
|
||||
resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@expo/cli@54.0.5':
|
||||
resolution: {integrity: sha512-8MZOZKHfHRHTBQu2/PXBi7eCKc2aF1i1JsZweL/P7aX8nivhrP6KV6An5PtO1/rrdnS9z7pmX2KwMygvvaFNhg==}
|
||||
'@expo/cli@54.0.6':
|
||||
resolution: {integrity: sha512-BgxJshNqSODb4Rq4q4lHLBVWVL4683Q+PSJ2fd+m3D5Jqd8nu9zGvcq6I/H8AXV/Ux31eIuUgAojPCjW8LRyZA==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
expo: '*'
|
||||
@@ -1348,8 +1348,8 @@ packages:
|
||||
'@expo/env@2.0.7':
|
||||
resolution: {integrity: sha512-BNETbLEohk3HQ2LxwwezpG8pq+h7Fs7/vAMP3eAtFT1BCpprLYoBBFZH7gW4aqGfqOcVP4Lc91j014verrYNGg==}
|
||||
|
||||
'@expo/fingerprint@0.15.0':
|
||||
resolution: {integrity: sha512-PrLA6fxScZfnLy7OHZ2GHXsDG9YbE7L5DbNhion6j/U/O+FQgz4VbxJarW5C00kMg1ll2u6EghB7ENAvL1T4qg==}
|
||||
'@expo/fingerprint@0.15.1':
|
||||
resolution: {integrity: sha512-U1S9DwiapCHQjHdHDDyO/oXsl/1oEHSHZRRkWDDrHgXRUDiAVIySw9Unvvcr118Ee6/x4NmKSZY1X0VagrqmFg==}
|
||||
hasBin: true
|
||||
|
||||
'@expo/image-utils@0.8.7':
|
||||
@@ -1361,6 +1361,14 @@ packages:
|
||||
'@expo/json-file@10.0.7':
|
||||
resolution: {integrity: sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw==}
|
||||
|
||||
'@expo/mcp-tunnel@0.0.7':
|
||||
resolution: {integrity: sha512-ht8Q1nKtiHobZqkUqt/7awwjW2D59ardP6XDVmGceGjQtoZELVaJDHyMIX+aVG9SZ9aj8+uGlhQYeBi57SZPMA==}
|
||||
peerDependencies:
|
||||
'@modelcontextprotocol/sdk': ^1.13.2
|
||||
peerDependenciesMeta:
|
||||
'@modelcontextprotocol/sdk':
|
||||
optional: true
|
||||
|
||||
'@expo/metro-config@54.0.3':
|
||||
resolution: {integrity: sha512-TQ5MKSGFB6zJxi+Yr8VYXQFHzRXgvSJzNsHX1otTqnxjXbptwYiXhljAqGSjr3pByq4+sHX/GifMk6fGgAANmA==}
|
||||
peerDependencies:
|
||||
@@ -1387,8 +1395,8 @@ packages:
|
||||
resolution: {integrity: sha512-IClSOXxR0YUFxIriUJVqyYki7lLMIHrrzOaP01yxAL1G8pj2DWV5eW1y5jSzIcIfSCNhtGsshGd1tU/AYup5iQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@expo/package-manager@1.9.7':
|
||||
resolution: {integrity: sha512-k3uky8Qzlv21rxuPvP2KUTAy8NI0b/LP7BSXcwJpS/rH7RmiAqUXgzPar3I1OmKGgxpod78Y9Mae//F8d3aiOQ==}
|
||||
'@expo/package-manager@1.9.8':
|
||||
resolution: {integrity: sha512-4/I6OWquKXYnzo38pkISHCOCOXxfeEmu4uDoERq1Ei/9Ur/s9y3kLbAamEkitUkDC7gHk1INxRWEfFNzGbmOrA==}
|
||||
|
||||
'@expo/plist@0.4.6':
|
||||
resolution: {integrity: sha512-6yklhtUWohs1rBSC8dGyBBpElEbosjXN0zJN/+1/B121n7pPWvd9y/UGJm+2x7b81VnW3AHmWVnbU/u0INQsqA==}
|
||||
@@ -4704,8 +4712,8 @@ packages:
|
||||
react: '*'
|
||||
react-native: '*'
|
||||
|
||||
expo-constants@18.0.8:
|
||||
resolution: {integrity: sha512-Tetphsx6RVImCTZeBAclRQMy0WOODY3y6qrUoc88YGUBVm8fAKkErCSWxLTCc6nFcJxdoOMYi62LgNIUFjZCLA==}
|
||||
expo-constants@18.0.9:
|
||||
resolution: {integrity: sha512-sqoXHAOGDcr+M9NlXzj1tGoZyd3zxYDy215W6E0Z0n8fgBaqce9FAYQE2bu5X4G629AYig5go7U6sQz7Pjcm8A==}
|
||||
peerDependencies:
|
||||
expo: '*'
|
||||
react-native: '*'
|
||||
@@ -4796,24 +4804,24 @@ packages:
|
||||
peerDependencies:
|
||||
expo: '*'
|
||||
|
||||
expo-modules-autolinking@3.0.10:
|
||||
resolution: {integrity: sha512-6pwaz9H7aK/iYraHbX7zjg8QFTUuMfGEs8Vyc6bAoBd8Rovtb91WX955Kq5sazwNrQjs3WePwQ23LEAmls3u5g==}
|
||||
expo-modules-autolinking@3.0.11:
|
||||
resolution: {integrity: sha512-Sz1ptcSZ4mvWJ7Rf1aB6Pe1fuEeIkACPILg2tmXDo3wwLTxPqugitMOePjbBZyvacBDirtDZlMb2A6LQDPVFOg==}
|
||||
hasBin: true
|
||||
|
||||
expo-modules-core@3.0.15:
|
||||
resolution: {integrity: sha512-vGI7osd0/IjprldD08k4bckWSu7ID4HhZNP68l/UtilONQ8XZig8mWJd/Fm7i7KGvE3HyuF+HOXE9l671no42Q==}
|
||||
expo-modules-core@3.0.16:
|
||||
resolution: {integrity: sha512-rCxzJiTdeSdqLVmDYYnogxqHS3NB65YTd76tAtSACujN2TQco08/toxCCov+9uULq1NGPxDJnfTkrtGaGWfatQ==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
react-native: '*'
|
||||
|
||||
expo-router@6.0.5:
|
||||
resolution: {integrity: sha512-FK5y/55ppv54WjW7W7X4g5J3r+hiMKHukRYjyS6KI4i92qOWtVF42yssD/Ty90EpjKuZ8N1F72FJGdx9A1UQNA==}
|
||||
expo-router@6.0.6:
|
||||
resolution: {integrity: sha512-uSuKQanivBI9RtwmAznLI7It5aPwQLVL2tVBPAOJ70tv6BzP62SpVCf0I8o0j9PmEzORPRLrU2LbQOL962yBHg==}
|
||||
peerDependencies:
|
||||
'@expo/metro-runtime': ^6.1.2
|
||||
'@react-navigation/drawer': ^7.5.0
|
||||
'@testing-library/react-native': '>= 12.0.0'
|
||||
expo: '*'
|
||||
expo-constants: ^18.0.8
|
||||
expo-constants: ^18.0.9
|
||||
expo-linking: ^8.0.8
|
||||
react: '*'
|
||||
react-dom: '*'
|
||||
@@ -4877,8 +4885,8 @@ packages:
|
||||
peerDependencies:
|
||||
expo: '*'
|
||||
|
||||
expo@54.0.7:
|
||||
resolution: {integrity: sha512-DftN6nMdpHYUCw5Xnh7+h7wnusjtly4JzQknvuD7MzIvqoyJL9uffQyMQrmZkXrUbgm+cKBm47vtooIz4qj0Qg==}
|
||||
expo@54.0.8:
|
||||
resolution: {integrity: sha512-H4nUVvAczd9ZPWrAR3oXxEr/EkLfPxXg5gBvFgZI4WnGNthehqEYB37urXgj9fvgSBxNaRUkySL4uwr9VB2J8Q==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@expo/dom-webview': '*'
|
||||
@@ -9908,7 +9916,7 @@ snapshots:
|
||||
'@eslint/core': 0.15.2
|
||||
levn: 0.4.1
|
||||
|
||||
'@expo/cli@54.0.5(expo-router@6.0.5)(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))':
|
||||
'@expo/cli@54.0.6(expo-router@6.0.6)(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))':
|
||||
dependencies:
|
||||
'@0no-co/graphql.web': 1.2.0
|
||||
'@expo/code-signing-certificates': 0.0.5
|
||||
@@ -9918,12 +9926,13 @@ snapshots:
|
||||
'@expo/env': 2.0.7
|
||||
'@expo/image-utils': 0.8.7
|
||||
'@expo/json-file': 10.0.7
|
||||
'@expo/mcp-tunnel': 0.0.7
|
||||
'@expo/metro': 0.1.1
|
||||
'@expo/metro-config': 54.0.3(expo@54.0.7)
|
||||
'@expo/metro-config': 54.0.3(expo@54.0.8)
|
||||
'@expo/osascript': 2.3.7
|
||||
'@expo/package-manager': 1.9.7
|
||||
'@expo/package-manager': 1.9.8
|
||||
'@expo/plist': 0.4.7
|
||||
'@expo/prebuild-config': 54.0.3(expo@54.0.7)
|
||||
'@expo/prebuild-config': 54.0.3(expo@54.0.8)
|
||||
'@expo/schema-utils': 0.1.7
|
||||
'@expo/server': 0.7.4
|
||||
'@expo/spawn-async': 1.7.2
|
||||
@@ -9943,7 +9952,7 @@ snapshots:
|
||||
connect: 3.7.0
|
||||
debug: 4.4.1
|
||||
env-editor: 0.4.2
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
freeport-async: 2.0.0
|
||||
getenv: 2.0.0
|
||||
glob: 10.4.5
|
||||
@@ -9975,9 +9984,10 @@ snapshots:
|
||||
wrap-ansi: 7.0.0
|
||||
ws: 8.18.3
|
||||
optionalDependencies:
|
||||
expo-router: 6.0.5(750b4158402c81723fe42a215de7942a)
|
||||
expo-router: 6.0.6(be6ce5c43438e2db372447bf3c6a78fa)
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
transitivePeerDependencies:
|
||||
- '@modelcontextprotocol/sdk'
|
||||
- bufferutil
|
||||
- graphql
|
||||
- supports-color
|
||||
@@ -10091,7 +10101,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@expo/fingerprint@0.15.0':
|
||||
'@expo/fingerprint@0.15.1':
|
||||
dependencies:
|
||||
'@expo/spawn-async': 1.7.2
|
||||
arg: 5.0.2
|
||||
@@ -10130,7 +10140,16 @@ snapshots:
|
||||
'@babel/code-frame': 7.10.4
|
||||
json5: 2.2.3
|
||||
|
||||
'@expo/metro-config@54.0.3(expo@54.0.7)':
|
||||
'@expo/mcp-tunnel@0.0.7':
|
||||
dependencies:
|
||||
ws: 8.18.3
|
||||
zod: 3.25.76
|
||||
zod-to-json-schema: 3.24.6(zod@3.25.76)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
'@expo/metro-config@54.0.3(expo@54.0.8)':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
'@babel/core': 7.28.3
|
||||
@@ -10154,16 +10173,16 @@ snapshots:
|
||||
postcss: 8.4.49
|
||||
resolve-from: 5.0.0
|
||||
optionalDependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@expo/metro-runtime@6.1.1(expo@54.0.7)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
|
||||
'@expo/metro-runtime@6.1.1(expo@54.0.8)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
|
||||
dependencies:
|
||||
anser: 1.4.10
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
pretty-format: 29.7.0
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
@@ -10196,7 +10215,7 @@ snapshots:
|
||||
'@expo/spawn-async': 1.7.2
|
||||
exec-async: 2.2.0
|
||||
|
||||
'@expo/package-manager@1.9.7':
|
||||
'@expo/package-manager@1.9.8':
|
||||
dependencies:
|
||||
'@expo/json-file': 10.0.7
|
||||
'@expo/spawn-async': 1.7.2
|
||||
@@ -10217,7 +10236,7 @@ snapshots:
|
||||
base64-js: 1.5.1
|
||||
xmlbuilder: 15.1.1
|
||||
|
||||
'@expo/prebuild-config@54.0.3(expo@54.0.7)':
|
||||
'@expo/prebuild-config@54.0.3(expo@54.0.8)':
|
||||
dependencies:
|
||||
'@expo/config': 12.0.9
|
||||
'@expo/config-plugins': 54.0.1
|
||||
@@ -10226,7 +10245,7 @@ snapshots:
|
||||
'@expo/json-file': 10.0.7
|
||||
'@react-native/normalize-colors': 0.81.4
|
||||
debug: 4.4.1
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.7.2
|
||||
xml2js: 0.6.0
|
||||
@@ -10250,9 +10269,9 @@ snapshots:
|
||||
|
||||
'@expo/sudo-prompt@9.3.2': {}
|
||||
|
||||
'@expo/vector-icons@15.0.2(expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
|
||||
'@expo/vector-icons@15.0.2(expo-font@14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
|
||||
dependencies:
|
||||
expo-font: 14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-font: 14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
|
||||
@@ -12800,7 +12819,7 @@ snapshots:
|
||||
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.3)
|
||||
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.3)
|
||||
|
||||
babel-preset-expo@54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.7)(react-refresh@0.14.2):
|
||||
babel-preset-expo@54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.8)(react-refresh@0.14.2):
|
||||
dependencies:
|
||||
'@babel/helper-module-imports': 7.27.1
|
||||
'@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.3)
|
||||
@@ -12827,7 +12846,7 @@ snapshots:
|
||||
resolve-from: 5.0.0
|
||||
optionalDependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- supports-color
|
||||
@@ -14161,93 +14180,93 @@ snapshots:
|
||||
jest-mock: 30.0.5
|
||||
jest-util: 30.0.5
|
||||
|
||||
expo-asset@12.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
expo-asset@12.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
'@expo/image-utils': 0.8.7
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-constants: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
expo-clipboard@8.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
expo-clipboard@8.0.7(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
|
||||
expo-constants@18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)):
|
||||
expo-constants@18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)):
|
||||
dependencies:
|
||||
'@expo/config': 12.0.8
|
||||
'@expo/config': 12.0.9
|
||||
'@expo/env': 2.0.7
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
expo-crypto@15.0.7(expo@54.0.7):
|
||||
expo-crypto@15.0.7(expo@54.0.8):
|
||||
dependencies:
|
||||
base64-js: 1.5.1
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
|
||||
expo-dev-client@6.0.12(expo@54.0.7):
|
||||
expo-dev-client@6.0.12(expo@54.0.8):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-dev-launcher: 6.0.11(expo@54.0.7)
|
||||
expo-dev-menu: 7.0.11(expo@54.0.7)
|
||||
expo-dev-menu-interface: 2.0.0(expo@54.0.7)
|
||||
expo-manifests: 1.0.8(expo@54.0.7)
|
||||
expo-updates-interface: 2.0.0(expo@54.0.7)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-dev-launcher: 6.0.11(expo@54.0.8)
|
||||
expo-dev-menu: 7.0.11(expo@54.0.8)
|
||||
expo-dev-menu-interface: 2.0.0(expo@54.0.8)
|
||||
expo-manifests: 1.0.8(expo@54.0.8)
|
||||
expo-updates-interface: 2.0.0(expo@54.0.8)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
expo-dev-launcher@6.0.11(expo@54.0.7):
|
||||
expo-dev-launcher@6.0.11(expo@54.0.8):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-dev-menu: 7.0.11(expo@54.0.7)
|
||||
expo-manifests: 1.0.8(expo@54.0.7)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-dev-menu: 7.0.11(expo@54.0.8)
|
||||
expo-manifests: 1.0.8(expo@54.0.8)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
expo-dev-menu-interface@2.0.0(expo@54.0.7):
|
||||
expo-dev-menu-interface@2.0.0(expo@54.0.8):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
|
||||
expo-dev-menu@7.0.11(expo@54.0.7):
|
||||
expo-dev-menu@7.0.11(expo@54.0.8):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-dev-menu-interface: 2.0.0(expo@54.0.7)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-dev-menu-interface: 2.0.0(expo@54.0.8)
|
||||
|
||||
expo-document-picker@14.0.7(expo@54.0.7):
|
||||
expo-document-picker@14.0.7(expo@54.0.8):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
|
||||
expo-file-system@19.0.14(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)):
|
||||
expo-file-system@19.0.14(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
|
||||
expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
expo-font@14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
fontfaceobserver: 2.3.0
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
|
||||
expo-glass-effect@0.1.3(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
expo-glass-effect@0.1.3(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
|
||||
expo-haptics@15.0.7(expo@54.0.7):
|
||||
expo-haptics@15.0.7(expo@54.0.8):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
|
||||
expo-image@3.0.8(expo@54.0.7)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
expo-image@3.0.8(expo@54.0.8)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
optionalDependencies:
|
||||
@@ -14255,14 +14274,14 @@ snapshots:
|
||||
|
||||
expo-json-utils@0.15.0: {}
|
||||
|
||||
expo-keep-awake@15.0.7(expo@54.0.7)(react@19.1.0):
|
||||
expo-keep-awake@15.0.7(expo@54.0.8)(react@19.1.0):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react: 19.1.0
|
||||
|
||||
expo-linking@8.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
expo-linking@8.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-constants: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
invariant: 2.2.4
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
@@ -14270,15 +14289,15 @@ snapshots:
|
||||
- expo
|
||||
- supports-color
|
||||
|
||||
expo-manifests@1.0.8(expo@54.0.7):
|
||||
expo-manifests@1.0.8(expo@54.0.8):
|
||||
dependencies:
|
||||
'@expo/config': 12.0.8
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-json-utils: 0.15.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
expo-modules-autolinking@3.0.10:
|
||||
expo-modules-autolinking@3.0.11:
|
||||
dependencies:
|
||||
'@expo/spawn-async': 1.7.2
|
||||
chalk: 4.1.2
|
||||
@@ -14287,15 +14306,15 @@ snapshots:
|
||||
require-from-string: 2.0.2
|
||||
resolve-from: 5.0.0
|
||||
|
||||
expo-modules-core@3.0.15(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
expo-modules-core@3.0.16(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
invariant: 2.2.4
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
|
||||
expo-router@6.0.5(750b4158402c81723fe42a215de7942a):
|
||||
expo-router@6.0.6(be6ce5c43438e2db372447bf3c6a78fa):
|
||||
dependencies:
|
||||
'@expo/metro-runtime': 6.1.1(expo@54.0.7)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
'@expo/metro-runtime': 6.1.1(expo@54.0.8)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
'@expo/schema-utils': 0.1.7
|
||||
'@expo/server': 0.7.4
|
||||
'@radix-ui/react-slot': 1.2.0(@types/react@19.1.12)(react@19.1.0)
|
||||
@@ -14306,9 +14325,9 @@ snapshots:
|
||||
client-only: 0.0.1
|
||||
debug: 4.4.1
|
||||
escape-string-regexp: 4.0.0
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-linking: 8.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-constants: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-linking: 8.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
fast-deep-equal: 3.1.3
|
||||
invariant: 2.2.4
|
||||
nanoid: 3.3.11
|
||||
@@ -14336,14 +14355,14 @@ snapshots:
|
||||
- '@types/react-dom'
|
||||
- supports-color
|
||||
|
||||
expo-secure-store@15.0.7(expo@54.0.7):
|
||||
expo-secure-store@15.0.7(expo@54.0.8):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
|
||||
expo-splash-screen@31.0.10(expo@54.0.7):
|
||||
expo-splash-screen@31.0.10(expo@54.0.8):
|
||||
dependencies:
|
||||
'@expo/prebuild-config': 54.0.3(expo@54.0.7)
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
'@expo/prebuild-config': 54.0.3(expo@54.0.8)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -14353,56 +14372,57 @@ snapshots:
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
react-native-is-edge-to-edge: 1.2.1(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
|
||||
expo-symbols@1.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)):
|
||||
expo-symbols@1.0.7(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
sf-symbols-typescript: 2.1.0
|
||||
|
||||
expo-system-ui@6.0.7(expo@54.0.7)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)):
|
||||
expo-system-ui@6.0.7(expo@54.0.8)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)):
|
||||
dependencies:
|
||||
'@react-native/normalize-colors': 0.81.4
|
||||
debug: 4.4.1
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
optionalDependencies:
|
||||
react-native-web: 0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
expo-updates-interface@2.0.0(expo@54.0.7):
|
||||
expo-updates-interface@2.0.0(expo@54.0.8):
|
||||
dependencies:
|
||||
expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
|
||||
expo@54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
expo@54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@expo/cli': 54.0.5(expo-router@6.0.5)(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
'@expo/cli': 54.0.6(expo-router@6.0.6)(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
'@expo/config': 12.0.9
|
||||
'@expo/config-plugins': 54.0.1
|
||||
'@expo/devtools': 0.1.7(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
'@expo/fingerprint': 0.15.0
|
||||
'@expo/fingerprint': 0.15.1
|
||||
'@expo/metro': 0.1.1
|
||||
'@expo/metro-config': 54.0.3(expo@54.0.7)
|
||||
'@expo/vector-icons': 15.0.2(expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
'@expo/metro-config': 54.0.3(expo@54.0.8)
|
||||
'@expo/vector-icons': 15.0.2(expo-font@14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
'@ungap/structured-clone': 1.3.0
|
||||
babel-preset-expo: 54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.7)(react-refresh@0.14.2)
|
||||
expo-asset: 12.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-file-system: 19.0.14(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-font: 14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-keep-awake: 15.0.7(expo@54.0.7)(react@19.1.0)
|
||||
expo-modules-autolinking: 3.0.10
|
||||
expo-modules-core: 3.0.15(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
babel-preset-expo: 54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.8)(react-refresh@0.14.2)
|
||||
expo-asset: 12.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-constants: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-file-system: 19.0.14(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))
|
||||
expo-font: 14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-keep-awake: 15.0.7(expo@54.0.8)(react@19.1.0)
|
||||
expo-modules-autolinking: 3.0.11
|
||||
expo-modules-core: 3.0.16(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
pretty-format: 29.7.0
|
||||
react: 19.1.0
|
||||
react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)
|
||||
react-refresh: 0.14.2
|
||||
whatwg-url-without-unicode: 8.0.0-3
|
||||
optionalDependencies:
|
||||
'@expo/metro-runtime': 6.1.1(expo@54.0.7)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
'@expo/metro-runtime': 6.1.1(expo@54.0.8)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- '@modelcontextprotocol/sdk'
|
||||
- bufferutil
|
||||
- expo-router
|
||||
- graphql
|
||||
|
||||
Reference in New Issue
Block a user