feat(companion): initial rn port scaffold
This commit is contained in:
81
aris/app/(tabs)/_layout.tsx
Normal file
81
aris/app/(tabs)/_layout.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { Tabs } from "expo-router";
|
||||
|
||||
const iconSize = 22;
|
||||
|
||||
export default function TabLayout() {
|
||||
return (
|
||||
<Tabs screenOptions={{ headerShown: false }}>
|
||||
<Tabs.Screen
|
||||
name="index"
|
||||
options={{
|
||||
title: "BLE",
|
||||
tabBarLabel: "BLE",
|
||||
tabBarIcon: ({ color, focused }) => (
|
||||
<Ionicons
|
||||
color={color}
|
||||
name={focused ? "bluetooth" : "bluetooth-outline"}
|
||||
size={iconSize}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="orchestrator"
|
||||
options={{
|
||||
title: "Orchestrator",
|
||||
tabBarLabel: "Orchestrator",
|
||||
tabBarIcon: ({ color, focused }) => (
|
||||
<Ionicons
|
||||
color={color}
|
||||
name={focused ? "flash" : "flash-outline"}
|
||||
size={iconSize}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="todos"
|
||||
options={{
|
||||
title: "Todos",
|
||||
tabBarLabel: "Todos",
|
||||
tabBarIcon: ({ color, focused }) => (
|
||||
<Ionicons
|
||||
color={color}
|
||||
name={focused ? "checkmark-done" : "checkmark-done-outline"}
|
||||
size={iconSize}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="stocks"
|
||||
options={{
|
||||
title: "Stocks",
|
||||
tabBarLabel: "Stocks",
|
||||
tabBarIcon: ({ color, focused }) => (
|
||||
<Ionicons
|
||||
color={color}
|
||||
name={focused ? "stats-chart" : "stats-chart-outline"}
|
||||
size={iconSize}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="settings"
|
||||
options={{
|
||||
title: "Settings",
|
||||
tabBarLabel: "Settings",
|
||||
tabBarIcon: ({ color, focused }) => (
|
||||
<Ionicons
|
||||
color={color}
|
||||
name={focused ? "settings" : "settings-outline"}
|
||||
size={iconSize}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
22
aris/app/(tabs)/index.tsx
Normal file
22
aris/app/(tabs)/index.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { View } from "react-native";
|
||||
|
||||
import { Container } from "@/components/Container";
|
||||
import { Text } from "@/components/ui/text";
|
||||
|
||||
export default function BleScreen() {
|
||||
return (
|
||||
<View className={styles.container}>
|
||||
<Container>
|
||||
<Text variant="h3">BLE</Text>
|
||||
<Text className={styles.subtitle}>
|
||||
Port of SwiftUI BleStatusView will live here.
|
||||
</Text>
|
||||
</Container>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: "flex flex-1 bg-white",
|
||||
subtitle: "mt-2 text-sm text-muted-foreground",
|
||||
};
|
||||
22
aris/app/(tabs)/orchestrator.tsx
Normal file
22
aris/app/(tabs)/orchestrator.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { View } from "react-native";
|
||||
|
||||
import { Container } from "@/components/Container";
|
||||
import { Text } from "@/components/ui/text";
|
||||
|
||||
export default function OrchestratorScreen() {
|
||||
return (
|
||||
<View className={styles.container}>
|
||||
<Container>
|
||||
<Text variant="h3">Orchestrator</Text>
|
||||
<Text className={styles.subtitle}>
|
||||
Port of SwiftUI OrchestratorView will live here.
|
||||
</Text>
|
||||
</Container>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: "flex flex-1 bg-white",
|
||||
subtitle: "mt-2 text-sm text-muted-foreground",
|
||||
};
|
||||
22
aris/app/(tabs)/settings.tsx
Normal file
22
aris/app/(tabs)/settings.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { View } from "react-native";
|
||||
|
||||
import { Container } from "@/components/Container";
|
||||
import { Text } from "@/components/ui/text";
|
||||
|
||||
export default function SettingsScreen() {
|
||||
return (
|
||||
<View className={styles.container}>
|
||||
<Container>
|
||||
<Text variant="h3">Settings</Text>
|
||||
<Text className={styles.subtitle}>
|
||||
Port of SwiftUI SettingsView will live here.
|
||||
</Text>
|
||||
</Container>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: "flex flex-1 bg-white",
|
||||
subtitle: "mt-2 text-sm text-muted-foreground",
|
||||
};
|
||||
22
aris/app/(tabs)/stocks.tsx
Normal file
22
aris/app/(tabs)/stocks.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { View } from "react-native";
|
||||
|
||||
import { Container } from "@/components/Container";
|
||||
import { Text } from "@/components/ui/text";
|
||||
|
||||
export default function StocksScreen() {
|
||||
return (
|
||||
<View className={styles.container}>
|
||||
<Container>
|
||||
<Text variant="h3">Stocks</Text>
|
||||
<Text className={styles.subtitle}>
|
||||
Port of SwiftUI StockSettingsView will live here.
|
||||
</Text>
|
||||
</Container>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: "flex flex-1 bg-white",
|
||||
subtitle: "mt-2 text-sm text-muted-foreground",
|
||||
};
|
||||
22
aris/app/(tabs)/todos.tsx
Normal file
22
aris/app/(tabs)/todos.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { View } from "react-native";
|
||||
|
||||
import { Container } from "@/components/Container";
|
||||
import { Text } from "@/components/ui/text";
|
||||
|
||||
export default function TodosScreen() {
|
||||
return (
|
||||
<View className={styles.container}>
|
||||
<Container>
|
||||
<Text variant="h3">Todos</Text>
|
||||
<Text className={styles.subtitle}>
|
||||
Port of SwiftUI TodosView will live here.
|
||||
</Text>
|
||||
</Container>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: "flex flex-1 bg-white",
|
||||
subtitle: "mt-2 text-sm text-muted-foreground",
|
||||
};
|
||||
46
aris/app/+html.tsx
Normal file
46
aris/app/+html.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { ScrollViewStyleReset } from 'expo-router/html';
|
||||
|
||||
// This file is web-only and used to configure the root HTML for every
|
||||
// web page during static rendering.
|
||||
// The contents of this function only run in Node.js environments and
|
||||
// do not have access to the DOM or browser APIs.
|
||||
export default function Root({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
{/*
|
||||
This viewport disables scaling which makes the mobile website act more like a native app.
|
||||
However this does reduce built-in accessibility. If you want to enable scaling, use this instead:
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
*/}
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1.00001,viewport-fit=cover"
|
||||
/>
|
||||
{/*
|
||||
Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
|
||||
However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
|
||||
*/}
|
||||
<ScrollViewStyleReset />
|
||||
|
||||
{/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */}
|
||||
<style dangerouslySetInnerHTML={{ __html: responsiveBackground }} />
|
||||
{/* Add any additional <head> elements that you want globally available on web... */}
|
||||
</head>
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
const responsiveBackground = `
|
||||
body {
|
||||
background-color: #fff;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #000;
|
||||
}
|
||||
}`;
|
||||
26
aris/app/+not-found.tsx
Normal file
26
aris/app/+not-found.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Link, Stack } from 'expo-router';
|
||||
|
||||
import { Text, View } from 'react-native';
|
||||
|
||||
import { Container } from '@/components/Container';
|
||||
|
||||
export default function NotFoundScreen() {
|
||||
return (
|
||||
<View className={styles.container}>
|
||||
<Stack.Screen options={{ title: 'Oops!' }} />
|
||||
<Container>
|
||||
<Text className={styles.title}>{"This screen doesn't exist."}</Text>
|
||||
<Link href="/" className={styles.link}>
|
||||
<Text className={styles.linkText}>Go to home screen!</Text>
|
||||
</Link>
|
||||
</Container>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: `flex flex-1 bg-white`,
|
||||
title: `text-xl font-bold`,
|
||||
link: `mt-4 pt-4`,
|
||||
linkText: `text-base text-[#2e78b7]`,
|
||||
};
|
||||
15
aris/app/_layout.tsx
Normal file
15
aris/app/_layout.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import "../global.css";
|
||||
|
||||
import { Stack } from "expo-router";
|
||||
import { PortalHost } from "@rn-primitives/portal";
|
||||
|
||||
export default function Layout() {
|
||||
return (
|
||||
<>
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
</Stack>
|
||||
<PortalHost />
|
||||
</>
|
||||
);
|
||||
}
|
||||
23
aris/app/details.tsx
Normal file
23
aris/app/details.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import { View } from 'react-native';
|
||||
|
||||
import { Stack, useLocalSearchParams } from 'expo-router';
|
||||
|
||||
import { Container } from '@/components/Container';
|
||||
import { ScreenContent } from '@/components/ScreenContent';
|
||||
|
||||
export default function Details() {
|
||||
const { name } = useLocalSearchParams();
|
||||
|
||||
return (
|
||||
<View className={styles.container}>
|
||||
<Stack.Screen options={{ title: 'Details' }} />
|
||||
<Container>
|
||||
<ScreenContent path="screens/details.tsx" title={`Showing details for user ${name}`} />
|
||||
</Container>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: 'flex flex-1 bg-white',
|
||||
};
|
||||
Reference in New Issue
Block a user