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