From 567791df7e1257233b6ca121fdd89aef3668e908 Mon Sep 17 00:00:00 2001 From: Joshua Higgins Date: Thu, 17 Apr 2025 22:45:32 -0400 Subject: [PATCH] Data model complete --- .expo/prebuild/cached-packages.json | 2 +- app.json | 3 +- app/index.tsx | 291 ++++++++++++++-------- ios/Podfile.lock | 6 + ios/selfstarter.xcodeproj/project.pbxproj | 6 +- package-lock.json | 12 + package.json | 3 +- 7 files changed, 214 insertions(+), 109 deletions(-) diff --git a/.expo/prebuild/cached-packages.json b/.expo/prebuild/cached-packages.json index 481a562..6aa9238 100644 --- a/.expo/prebuild/cached-packages.json +++ b/.expo/prebuild/cached-packages.json @@ -1,4 +1,4 @@ { - "dependencies": "f0b7a67330b4373657842464b944fe650bdb1e9d", + "dependencies": "4f452fcb9971e44e33c7d2865818197f89d6f9d3", "devDependencies": "33c61dd051763bf66d49625d5b8ab12f6e1b331b" } diff --git a/app.json b/app.json index a3daf76..d8ef789 100644 --- a/app.json +++ b/app.json @@ -34,7 +34,8 @@ "resizeMode": "contain", "backgroundColor": "#ffffff" } - ] + ], + "expo-sqlite" ], "experiments": { "typedRoutes": true diff --git a/app/index.tsx b/app/index.tsx index c280f33..28d15ac 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -2,122 +2,194 @@ import { Stack } from "expo-router"; import {StyleSheet, Text, View, ColorValue, ListRenderItemInfo, TouchableOpacity, Platform} from "react-native"; import {RowMap, SwipeListView} from "react-native-swipe-list-view"; import {ChevronDown, Plus} from "lucide-react-native"; -import {useRef} from "react"; -import {MenuComponentRef, MenuView} from "@react-native-menu/menu"; +import {useEffect, useState} from "react"; +import {MenuAction, MenuView, NativeActionEvent} from "@react-native-menu/menu"; +import {SQLiteDatabase, SQLiteProvider, useSQLiteContext} from "expo-sqlite"; const servers: Server[] = [ { + key: 0, name: "Test Data Server", domain: "localhost", - computers: [ - { - key: 0, - name: "Test PC", - emoji: "💻", - background_color: '#D9D9D9', - mac_address: "00:1A:2B:3C:4D:5E", - }, - { - key: 1, - name: "Another PC in the basement", - emoji: "💻", - background_color: '#D9D9D9', - mac_address: "00:1A:2B:3C:4D:5E", - } - ] + }, + { + key: 1, + name: "The Other Server", + domain: "192.168.86.252", + } +]; +const computers: Computer[] = [ + { + key: 0, + server_key: 0, + name: "Test PC", + emoji: "💻", + background_color: '#D9D9D9', + mac_address: "00:1A:2B:3C:4D:5E", + }, + { + key: 1, + server_key: 0, + name: "Another PC in the basement", + emoji: "💻", + background_color: '#D9D9D9', + mac_address: "00:1A:2B:3C:4D:5E", + }, + { + key: 2, + server_key: 1, + name: "Mom's PC", + emoji: "🌹", + background_color: '#D9D9D9', + mac_address: "00:1A:2B:3C:4D:5E", + }, + { + key: 3, + server_key: 1, + name: "Jordan's PC", + emoji: "💪", + background_color: '#D9D9D9', + mac_address: "00:1A:2B:3C:4D:5E", } ]; +async function migrateDbIfNeeded(db: SQLiteDatabase) { + await db.execAsync(` + PRAGMA journal_mode = WAL; + CREATE TABLE IF NOT EXISTS servers (key INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, domain TEXT NOT NULL); + CREATE TABLE IF NOT EXISTS computers (key INTEGER PRIMARY KEY NOT NULL, server_key INTEGER NOT NULL, name, emoji, background_color, mac_address TEXT NOT NULL); + `); +} + export default function Index() { + const [ currentServerName, setCurrentServerName ] = useState("None"); + const [ servers, setServers ] = useState([]); + const [ computers, setComputers ] = useState([]); + return ( - - - {servers[0].name} - - { - console.warn(JSON.stringify(nativeEvent)); - //TODO: Handle adding computers/servers - }} - actions={[ - { - id: 'server0', - title: servers[0].name, - titleColor: '#2367A2', - imageColor: '#2367A2', - }, - { - id: 'deleteServer', - title: 'Delete Current Server', - attributes: { - destructive: true, - }, - image: Platform.select({ - ios: 'trash', - android: 'ic_menu_delete', - }), - imageColor: "red", - }, - ]} - shouldOpenOnLongPress={false} - > - - - - , - headerRight: props => - - { - console.warn(JSON.stringify(nativeEvent)); - //TODO: Handle adding computers/servers - }} - actions={[ - { - id: 'addComputer', - title: 'Add Computer', - titleColor: '#000000', - image: 'desktopcomputer', - imageColor: '#000000', - }, - { - id: 'addServer', - title: 'Add Server', - titleColor: '#000000', - image: 'globe', - imageColor: '#000000', - }, - ]} - shouldOpenOnLongPress={false} - > - - - - }} - /> - + +
+ + ); } +function Header(props: { servers: Server[], setServers: (value: (((prevState: Server[]) => Server[]) | Server[])) => void, currentServerName: string, setCurrentServerName: (value: (((prevState: string) => string) | string)) => void }) { + const db = useSQLiteContext(); + + useEffect(() => { + async function setup() { + const result = await db.getFirstAsync(`SELECT * FROM servers`); + props.setCurrentServerName(result?.name || "None"); + } + + if (props.currentServerName === "None") { + setup(); + } + }, []); + + useEffect(() => { + async function setup() { + const result = await db.getAllAsync(`SELECT * FROM servers`); + props.setServers(result); + } + setup(); + }, []); + + const selectActions: MenuAction[] = []; + for (const server of props.servers) { + if (server.name !== props.currentServerName) { + selectActions.push({ + id: server.domain, + title: server.name, + titleColor: '#2367A2', + imageColor: '#2367A2', + }) + } + } + selectActions.push({ + id: 'deleteServer', + title: 'Delete Current Server', + attributes: { + destructive: true, + }, + image: Platform.select({ + ios: 'trash', + android: 'ic_menu_delete', + }), + imageColor: "red", + }) + + + const handleServerSelect = ({nativeEvent}: NativeActionEvent) => { + const newName = props.servers.find((server) => { + return server.name === nativeEvent.event; + }) + props.setCurrentServerName(newName?.name ?? "None"); + }; + + return + + {props.currentServerName} + {selectActions.length > 1 && + + + + + + } + , + headerRight: props => + + { + console.log(JSON.stringify(nativeEvent)); + //TODO: Handle adding computers/servers + }} + actions={[ + { + id: 'addComputer', + title: 'Add Computer', + titleColor: '#000000', + image: 'desktopcomputer', + imageColor: '#000000', + }, + { + id: 'addServer', + title: 'Add Server', + titleColor: '#000000', + image: 'globe', + imageColor: '#000000', + }, + ]} + shouldOpenOnLongPress={false} + > + + + + }} + /> +} + const styles = StyleSheet.create({ computerElement: { display: "flex", @@ -161,7 +233,17 @@ const styles = StyleSheet.create({ }, }); -function ComputerList(computers: { computers: Computer[] }) { +function ComputerList(props: {computers: Computer[], setComputers: (value: (((prevState: Computer[]) => Computer[]) | Computer[])) => void }) { + const db = useSQLiteContext(); + + useEffect(() => { + async function setup() { + const result = await db.getAllAsync(`SELECT * FROM computers`); + props.setComputers(result); + } + setup(); + }, []); + const renderHiddenItem = (data: ListRenderItemInfo, rowMap: RowMap) => ( ) =>