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",