diff --git a/.env.example b/.env.example deleted file mode 100644 index d881b2b..0000000 --- a/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -EXPO_PUBLIC_API_URL=https://api.openai.com/v1/chat/completions -EXPO_PUBLIC_API_KEY=put-open-ai-key-here -EXPO_PUBLIC_MODEL_NAME=gpt-4o-mini -#EXPO_PUBLIC_MODEL_NAME=gpt-4-turbo # More expensive model, use sparingly \ No newline at end of file diff --git a/.gitignore b/.gitignore index 55c8749..c9d575d 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,3 @@ yarn-error.* *.tsbuildinfo app-example -android -.env -coverage \ No newline at end of file diff --git a/README.md b/README.md index eff77e9..4ca5146 100644 --- a/README.md +++ b/README.md @@ -14,24 +14,6 @@ This applications uses the React Native + Expo framework and by extension is pri This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app). -### Setting Up Environment Variables - -To set up your environment variables: - -1. Copy the example environment variable file to create your own `.env` file: - -```bash -cp .env.example .env -``` - -2. Open the `.env` file and add your OpenAI API key: - -`EXPO_PUBLIC_API_KEY=put-open-ai-key-here` - -3. Save the .env file. - -This setup allows you to run the application with your own API credentials, and you can switch models if needed. - ### VSCode plugins - [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) diff --git a/app.json b/app.json index 501d4f3..a619d4b 100644 --- a/app.json +++ b/app.json @@ -1,10 +1,10 @@ { "expo": { - "name": "Poker Chips Helper", + "name": "poker-chips-helper", "slug": "poker-chips-helper", "version": "1.0.0", "orientation": "portrait", - "icon": "./assets/images/icon1.png", + "icon": "./assets/images/icon.png", "scheme": "myapp", "userInterfaceStyle": "automatic", "newArchEnabled": true, @@ -15,8 +15,7 @@ "adaptiveIcon": { "foregroundImage": "./assets/images/adaptive-icon.png", "backgroundColor": "#ffffff" - }, - "package": "com.anonymous.pokerchipshelper" + } }, "web": { "bundler": "metro", diff --git a/app/_layout.tsx b/app/_layout.tsx index c3648ac..d2a8b0b 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,7 +1,5 @@ import { Stack } from "expo-router"; -import React from "react"; -const RootLayout: React.FC = () => ( - -); -export default RootLayout; +export default function RootLayout() { + return ; +} diff --git a/app/index.tsx b/app/index.tsx index e80c05c..faf3557 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -4,7 +4,6 @@ import PlayerSelector from "@/components/PlayerSelector"; import BuyInSelector from "@/components/BuyInSelector"; import ChipsSelector from "@/components/ChipsSelector"; import ChipDistributionSummary from "@/components/ChipDistributionSummary"; -import ChipDetection from "@/components/ChipDetection"; export enum COLORS { "white", @@ -14,12 +13,11 @@ export enum COLORS { "black", } -const IndexScreen: React.FC = () => { +const IndexScreen = () => { const [playerCount, setPlayerCount] = useState(2); const [buyInAmount, setBuyInAmount] = useState(20); const [numberOfChips, setNumberOfChips] = useState(5); const [totalChipsCount, setTotalChipsCount] = useState([]); - const handleSave = () => { if (buyInAmount === null) { Alert.alert("Error", "Please select a valid buy-in amount"); @@ -30,24 +28,16 @@ const IndexScreen: React.FC = () => { ); } }; - - // Update chip count based on detection or manual edit - const updateChipCount = (chipData: { [color: string]: number }) => { - // Convert the chip data from the API response or manual edit to a count array - const chipCountArray = Object.entries(chipData).map( - ([color, count]) => count - ); - setTotalChipsCount(chipCountArray); // Update the parent component's state - }; - return ( + + Poker Chip Helper + - { ); }; - export default IndexScreen; diff --git a/assets/images/icon1.png b/assets/images/icon1.png deleted file mode 100644 index b01e897..0000000 Binary files a/assets/images/icon1.png and /dev/null differ diff --git a/components/ChipDetection.tsx b/components/ChipDetection.tsx deleted file mode 100644 index 0a51c46..0000000 --- a/components/ChipDetection.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import React, { useState } from "react"; -import { - View, - Button, - Image, - ActivityIndicator, - Text, - ScrollView, -} from "react-native"; -import * as ImagePicker from "expo-image-picker"; - -const ChipDetection = ({ updateChipCount }) => { - const [imageUri, setImageUri] = useState(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const [lastDetectedChips, setLastDetectedChips] = useState({}); - - const requestCameraPermissions = async () => { - const cameraPermission = await ImagePicker.requestCameraPermissionsAsync(); - return cameraPermission.granted; - }; - - const pickImage = async () => { - const result = await ImagePicker.launchImageLibraryAsync({ - mediaTypes: ImagePicker.MediaTypeOptions.Images, - base64: true, - quality: 1, - }); - - if (!result.canceled) { - setImageUri(result.assets[0].uri); - await processImage(result.assets[0].base64); - } - }; - - const takePhoto = async () => { - const hasPermission = await requestCameraPermissions(); - if (!hasPermission) { - setError("Camera permission is required to take a photo."); - return; - } - - const result = await ImagePicker.launchCameraAsync({ - base64: true, - quality: 1, - }); - - if (!result.canceled) { - setImageUri(result.assets[0].uri); - await processImage(result.assets[0].base64); - } - }; - - const processImage = async (base64Image) => { - setLoading(true); - setError(null); - - try { - const response = await fetch(process.env.EXPO_PUBLIC_API_URL, { - method: "POST", - headers: { - Authorization: `Bearer ${process.env.EXPO_PUBLIC_API_KEY}`, // Use environment variable for API key - "Content-Type": "application/json", - }, - body: JSON.stringify({ - model: process.env.EXPO_PUBLIC_MODEL_NAME, // Use environment variable for model name - messages: [ - { - role: "system", - content: - "Identify and count poker chips by color. Return only the count for each color in JSON format.", - }, - { - role: "user", - content: [ - { - type: "text", - text: "How many poker chips are there for each color? Return structured JSON.", - }, - { - type: "image_url", - image_url: { url: `data:image/png;base64,${base64Image}` }, - }, - ], - }, - ], - max_tokens: 1000, - }), - }); - - const result = await response.json(); - - if (!response.ok || !result.choices || !result.choices[0].message) { - throw new Error("Invalid response from API."); - } - - const rawContent = result.choices[0].message.content.trim(); - const cleanJSON = rawContent.replace(/```json|```/g, "").trim(); - - const parsedData = JSON.parse(cleanJSON); - - const filteredData = Object.fromEntries( - Object.entries(parsedData).filter(([_, count]) => count > 0) - ); - - setLastDetectedChips(filteredData); - updateChipCount(filteredData); - } catch (error) { - setError("Failed to analyze the image."); - } finally { - setLoading(false); - } - }; - - return ( - -