diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 00000000..ed3e9dde --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,22 @@ +name: Pull Request Trigger Workflow + +on: + pull_request: + branches: + - develop + +jobs: + build-and-test: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '>=18' + - name: Install dependencies + run: npm install + - name: Run tests + run: npm run test -- --ci + diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 00000000..518ea826 --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,19 @@ +name: Push Trigger Workflow + +on: + push: + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '>=18' + - name: Install dependencies + run: npm install + - name: Run tests + run: npm run test -- --ci diff --git a/app.json b/app.json index ec7dd105..152eaa64 100644 --- a/app.json +++ b/app.json @@ -6,13 +6,17 @@ "version": "1.0.0", "orientation": "portrait", "icon": "./assets/images/icon.png", - "userInterfaceStyle": "dark", - - "assetBundlePatterns": [ - "**/*" - ], + "splash": { + "image": "./assets/images/splash.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + }, + "assetBundlePatterns": ["**/*"], "ios": { - "supportsTablet": true + "supportsTablet": true, + "config": { + "usesNonExemptEncryption": false + } }, "android": { "adaptiveIcon": { @@ -25,9 +29,7 @@ "output": "static", "favicon": "./assets/images/favicon.png" }, - "plugins": [ - "expo-router" - ], + "plugins": ["expo-router", "expo-secure-store"], "experiments": { "typedRoutes": true } diff --git a/app/(auth)/SignIn&SignOut/SetYourFingerPrint.tsx b/app/(auth)/SignIn&SignOut/SetYourFingerPrint.tsx index c5993c6f..c25df595 100644 --- a/app/(auth)/SignIn&SignOut/SetYourFingerPrint.tsx +++ b/app/(auth)/SignIn&SignOut/SetYourFingerPrint.tsx @@ -1,8 +1,12 @@ import { Text, View } from "@/components/Themed"; import { LeftArrow } from "@/components/UI/icons"; +import { ThemeContext } from "@/ctx/ThemeContext"; +import { useContext, useEffect } from "react"; import { SvgUri, SvgXml } from "react-native-svg"; export default function SetYourFingerPrint() { + const { theme, changeTheme } = useContext(ThemeContext); + return ( <> Set Your Finger Print diff --git a/app/_layout.tsx b/app/_layout.tsx index 55ca9ce4..ae6f559d 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,16 +1,15 @@ import FontAwesome from "@expo/vector-icons/FontAwesome"; -import { - DarkTheme, - DefaultTheme, - ThemeProvider, -} from "@react-navigation/native"; import { useFonts } from "expo-font"; import { Stack } from "expo-router"; import * as SplashScreen from "expo-splash-screen"; +import * as SecureStore from "expo-secure-store"; -import { useEffect, useState } from "react"; +import { useContext, useEffect, useState } from "react"; -import { useColorScheme } from "@/components/useColorScheme"; +import ThemeProvider, { ThemeContext } from "@/ctx/ThemeContext"; +import { Pressable, View, useColorScheme } from "react-native"; +import { ThemeType } from "@/constants/Types"; +import { Text } from "@/components/Themed"; export { @@ -33,33 +32,60 @@ export default function RootLayout() { ...FontAwesome.font, }); + const systemTheme = useColorScheme() as ThemeType; + + const [favoredTheme, setFavoredTheme] = useState(null); + + useEffect(() => { + async function getCustomTheme() { + try { + let favoredTheme = (await SecureStore.getItemAsync( + "theme" + )) as ThemeType; + + if (!favoredTheme) { + favoredTheme = systemTheme; + } + + setFavoredTheme(favoredTheme); + } catch (e) { + console.log(e); + } + } + + getCustomTheme(); + }, []); + + // Expo Router uses Error Boundaries to catch errors in the navigation tree. useEffect(() => { if (error) throw error; }, [error]); useEffect(() => { - if (loaded) { + if (loaded && favoredTheme) { SplashScreen.hideAsync(); } - }, [loaded]); + }, [loaded, favoredTheme]); if (!loaded) { return null; } - return ; + return ( + + + + ); } function RootLayoutNav() { - const colorScheme = useColorScheme(); - return ( - + <> - + ); } diff --git a/components/__tests__/__snapshots__/StyledText-test.js.snap b/components/__tests__/__snapshots__/StyledText-test.js.snap new file mode 100644 index 00000000..9cb9c69e --- /dev/null +++ b/components/__tests__/__snapshots__/StyledText-test.js.snap @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` + + Snapshot test! + +`; diff --git a/constants/Types.ts b/constants/Types.ts new file mode 100644 index 00000000..b1d4baea --- /dev/null +++ b/constants/Types.ts @@ -0,0 +1 @@ +export type ThemeType = "light" | "dark" | null diff --git a/ctx/ThemeContext.tsx b/ctx/ThemeContext.tsx new file mode 100644 index 00000000..64d60da9 --- /dev/null +++ b/ctx/ThemeContext.tsx @@ -0,0 +1,33 @@ +import { ThemeType } from "@/constants/Types"; +import React, { createContext, useState } from "react"; +import * as SecureStore from "expo-secure-store"; + +interface ContextType { + theme: ThemeType; + changeTheme: (theme: "light" | "dark") => void; +} + +export const ThemeContext = createContext({ + theme: null, + changeTheme: (theme: "light" | "dark") => {}, +}); + +interface Props { + children: React.JSX.Element | React.JSX.Element[]; + theme: ThemeType; +} + +export default function ThemeProvider({ children, theme: value }: Props) { + const [theme, setTheme] = useState(value); + + async function changeTheme(theme: "light" | "dark") { + setTheme(theme); + await SecureStore.setItemAsync("theme", theme!); + } + + return ( + + {children} + + ); +} diff --git a/package-lock.json b/package-lock.json index 9092d08e..c2c245ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "expo-linear-gradient": "~12.7.2", "expo-linking": "~6.2.2", "expo-router": "~3.4.10", + "expo-secure-store": "~12.8.1", "expo-splash-screen": "~0.26.5", "expo-status-bar": "~1.11.1", "expo-system-ui": "~2.9.3", @@ -11204,6 +11205,14 @@ } } }, + "node_modules/expo-secure-store": { + "version": "12.8.1", + "resolved": "https://registry.npmjs.org/expo-secure-store/-/expo-secure-store-12.8.1.tgz", + "integrity": "sha512-Ju3jmkHby4w7rIzdYAt9kQyQ7HhHJ0qRaiQOInknhOLIltftHjEgF4I1UmzKc7P5RCfGNmVbEH729Pncp/sHXQ==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-splash-screen": { "version": "0.26.5", "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.26.5.tgz", diff --git a/package.json b/package.json index a5b271cc..5d8674e6 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,10 @@ "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web", - "test": "jest --watchAll" + "test": "jest", + "test:watch": "jest --watchAll", + "test:update": "jest --updateSnapshot", + "ci-start": "expo build:web" }, "jest": { "preset": "jest-expo" @@ -20,6 +23,7 @@ "expo-linear-gradient": "~12.7.2", "expo-linking": "~6.2.2", "expo-router": "~3.4.10", + "expo-secure-store": "~12.8.1", "expo-splash-screen": "~0.26.5", "expo-status-bar": "~1.11.1", "expo-system-ui": "~2.9.3",