upgrade to v4

This commit is contained in:
Jorrin
2024-01-27 23:20:08 +01:00
parent 4c634abc1e
commit 8977e3ea2c
27 changed files with 1190 additions and 1264 deletions

View File

@@ -4,20 +4,19 @@
"slug": "mw-mobile", "slug": "mw-mobile",
"version": "1.0.0", "version": "1.0.0",
"orientation": "portrait", "orientation": "portrait",
"scheme":"dev.movieweb.app", "scheme": "dev.movieweb.app",
"userInterfaceStyle": "automatic",
"icon": "./assets/images/icon.png", "icon": "./assets/images/icon.png",
"splash": { "splash": {
"image": "./assets/images/splash.png", "image": "./assets/images/splash.png",
"resizeMode": "contain", "resizeMode": "contain",
"backgroundColor": "#ffffff" "backgroundColor": "#ffffff"
}, },
"jsEngine": "jsc", "jsEngine": "jsc",
"updates": { "updates": {
"fallbackToCacheTimeout": 0 "fallbackToCacheTimeout": 0
}, },
"assetBundlePatterns": [ "assetBundlePatterns": ["**/*"],
"**/*"
],
"ios": { "ios": {
"supportsTablet": true, "supportsTablet": true,
"bundleIdentifier": "dev.movieweb.app" "bundleIdentifier": "dev.movieweb.app"
@@ -34,20 +33,17 @@
"bundler": "metro" "bundler": "metro"
}, },
"plugins": [ "plugins": [
"expo-router", "expo-router",
[ [
"@config-plugins/detox", "@config-plugins/detox",
{ {
"skipProguard": false, "skipProguard": false,
"subdomains": [ "subdomains": ["10.0.2.2", "localhost"]
"10.0.2.2",
"localhost"
]
} }
] ]
], ],
"experiments": { "experiments": {
"typedRoutes": true "typedRoutes": true
} }
} }
} }

View File

@@ -1,26 +1,19 @@
import { Tabs } from 'expo-router'; import { Tabs } from 'expo-router';
import { NativeWindStyleSheet } from 'nativewind';
import TabBarIcon from '../../components/TabBarIcon'; import TabBarIcon from '../components/TabBarIcon';
import { globalStyles } from '../../styles/global'; import Colors from '../constants/Colors';
import useTailwind from '../hooks/useTailwind';
NativeWindStyleSheet.setOutput({
default: 'native',
});
export default function TabLayout() { export default function TabLayout() {
const { colors } = useTailwind();
return ( return (
<Tabs <Tabs
sceneContainerStyle={{ sceneContainerStyle={{
backgroundColor: '#000', backgroundColor: Colors.background,
}} }}
screenOptions={{ screenOptions={{
headerShown: false, headerShown: false,
tabBarActiveTintColor: colors.purple[100], tabBarActiveTintColor: Colors.primary[100],
tabBarStyle: { tabBarStyle: {
backgroundColor: colors.shade[700], backgroundColor: Colors.secondary[700],
borderTopColor: 'transparent', borderTopColor: 'transparent',
borderTopRightRadius: 20, borderTopRightRadius: 20,
borderTopLeftRadius: 20, borderTopLeftRadius: 20,
@@ -34,7 +27,6 @@ export default function TabLayout() {
{ {
marginTop: 2, marginTop: 2,
}, },
globalStyles.fOpenSansMedium,
], ],
}} }}
> >
@@ -61,25 +53,9 @@ export default function TabLayout() {
options={{ options={{
title: 'Search', title: 'Search',
tabBarLabel: '', tabBarLabel: '',
tabBarLabelStyle: {
display: 'none',
},
tabBarIconStyle: {},
tabBarIcon: () => ( tabBarIcon: () => (
<TabBarIcon <TabBarIcon
style={{ className=" bg-primary-400 flex aspect-[1/1] h-14 items-center justify-center rounded-full text-center text-2xl text-white"
position: 'relative',
top: -1,
backgroundColor: colors.purple[400],
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
aspectRatio: 1,
borderRadius: 100,
textAlign: 'center',
textAlignVertical: 'center',
height: 56,
}}
name="search" name="search"
color="#FFF" color="#FFF"
/> />

View File

@@ -1,6 +1,6 @@
import { Text } from 'react-native'; import { Text } from 'react-native';
import ScreenLayout from '../../components/layout/ScreenLayout'; import ScreenLayout from '../components/layout/ScreenLayout';
export default function AboutScreen() { export default function AboutScreen() {
return ( return (

View File

@@ -1,6 +1,6 @@
import { Text } from 'react-native'; import { Text } from 'react-native';
import ScreenLayout from '../../components/layout/ScreenLayout'; import ScreenLayout from '../components/layout/ScreenLayout';
export default function AccountScreen() { export default function AccountScreen() {
return ( return (

View File

@@ -1,6 +1,6 @@
import { Text } from 'react-native'; import { Text } from 'react-native';
import ScreenLayout from '../../components/layout/ScreenLayout'; import ScreenLayout from '../components/layout/ScreenLayout';
export default function HomeScreen() { export default function HomeScreen() {
return ( return (

View File

@@ -3,11 +3,9 @@ import { useFocusEffect } from 'expo-router';
import { useCallback, useRef, useState } from 'react'; import { useCallback, useRef, useState } from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import { TextInput } from 'react-native-gesture-handler'; import { TextInput } from 'react-native-gesture-handler';
import Colors from '../../constants/Colors';
import useTailwind from '../../hooks/useTailwind';
export default function Searchbar() { export default function Searchbar() {
const { colors } = useTailwind();
const [keyword, setKeyword] = useState(''); const [keyword, setKeyword] = useState('');
const inputRef = useRef<TextInput>(null); const inputRef = useRef<TextInput>(null);
@@ -25,9 +23,9 @@ export default function Searchbar() {
); );
return ( return (
<View className="mb-6 mt-4 flex-row items-center rounded-full border"> <View className="border-primary-400 focus-within:border-primary-300 mb-6 mt-4 flex-row items-center rounded-full border">
<View className="ml-1 w-12 items-center justify-center"> <View className="ml-1 w-12 items-center justify-center">
<FontAwesome5 name="search" size={18} color={colors.shade[200]} /> <FontAwesome5 name="search" size={18} color={Colors.secondary[200]} />
</View> </View>
<TextInput <TextInput
value={keyword} value={keyword}
@@ -35,8 +33,8 @@ export default function Searchbar() {
onChangeText={(text) => setKeyword(text)} onChangeText={(text) => setKeyword(text)}
ref={inputRef} ref={inputRef}
placeholder="What are you looking for?" placeholder="What are you looking for?"
placeholderTextColor={colors.shade[200]} placeholderTextColor={Colors.secondary[200]}
className="w-full rounded-3xl py-3 pr-5 text-white" className="w-full rounded-3xl py-3 pr-5 text-white focus-visible:outline-none"
/> />
</View> </View>
); );

View File

@@ -1,8 +1,8 @@
import { ScrollView, Text, View } from 'react-native'; import { ScrollView, Text, View } from 'react-native';
import Searchbar from './Searchbar'; import Searchbar from './Searchbar';
import Item from '../../../components/item/item'; import ScreenLayout from '../../components/layout/ScreenLayout';
import ScreenLayout from '../../../components/layout/ScreenLayout'; import Item from '../../components/item/item';
export default function SearchScreen() { export default function SearchScreen() {
return ( return (
@@ -10,7 +10,7 @@ export default function SearchScreen() {
<ScreenLayout <ScreenLayout
title={ title={
<View className="flex-row items-center"> <View className="flex-row items-center">
<Text className="text-2xl font-bold">Search</Text> <Text className="text-2xl font-bold text-white">Search</Text>
</View> </View>
} }
subtitle="Looking for something?" subtitle="Looking for something?"

View File

@@ -1,6 +1,6 @@
import { Text } from 'react-native'; import { Text } from 'react-native';
import ScreenLayout from '../../components/layout/ScreenLayout'; import ScreenLayout from '../components/layout/ScreenLayout';
export default function SettingsScreen() { export default function SettingsScreen() {
return ( return (

View File

@@ -10,8 +10,9 @@ import { SplashScreen, Stack } from 'expo-router';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useColorScheme } from 'react-native'; import { useColorScheme } from 'react-native';
import useTailwind from './hooks/useTailwind'; import Colors from './constants/Colors';
import '../styles/global.css';
import './styles/global.css';
export { export {
// Catch any errors thrown by the Layout component. // Catch any errors thrown by the Layout component.
@@ -58,7 +59,6 @@ export default function RootLayout() {
function RootLayoutNav() { function RootLayoutNav() {
const colorScheme = useColorScheme(); const colorScheme = useColorScheme();
const { colors } = useTailwind();
return ( return (
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}> <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
@@ -67,7 +67,7 @@ function RootLayoutNav() {
gestureEnabled: true, gestureEnabled: true,
headerShown: false, headerShown: false,
contentStyle: { contentStyle: {
backgroundColor: colors.shade[900], backgroundColor: Colors.background,
}, },
}} }}
> >

View File

@@ -1,18 +1,16 @@
import { FontAwesome } from '@expo/vector-icons'; import { FontAwesome } from '@expo/vector-icons';
import Colors from '../constants/Colors';
import useTailwind from '../app/hooks/useTailwind';
type Props = {
type Props = { focused?: boolean;
focused?: boolean; } & React.ComponentProps<typeof FontAwesome>;
} & React.ComponentProps<typeof FontAwesome>;
export default function TabBarIcon({ focused, ...rest }: Props) {
export default function TabBarIcon({ focused, ...rest }: Props) { return (
const { colors } = useTailwind(); <FontAwesome
return ( color={focused ? Colors.primary[300] : Colors.secondary[300]}
<FontAwesome size={24}
color={focused ? colors.purple[300] : colors.shade[300]} {...rest}
size={24} />
{...rest} );
/> }
);
}

View File

@@ -1,25 +1,25 @@
import { Image, Text, View } from 'react-native'; import { Image, Text, View } from 'react-native';
import { TMDB_POSTER_PATH } from '../../constants/General'; import { TMDB_POSTER_PATH } from '../../constants/General';
export default function Item() { export default function Item() {
return ( return (
<View className="w-full"> <View className="w-full">
<View className="mb-2 aspect-[9/14] w-full overflow-hidden rounded-2xl"> <View className="mb-2 aspect-[9/14] w-full overflow-hidden rounded-2xl">
<Image <Image
source={{ source={{
uri: `${TMDB_POSTER_PATH}/w342//gdIrmf2DdY5mgN6ycVP0XlzKzbE.jpg`, uri: `${TMDB_POSTER_PATH}/w342//gdIrmf2DdY5mgN6ycVP0XlzKzbE.jpg`,
width: 200, width: 200,
}} }}
className="h-full w-full object-cover" className="h-full w-full object-cover"
/> />
</View> </View>
<Text className="font-bold text-white">Hamilton</Text> <Text className="font-bold text-white">Hamilton</Text>
<View className="flex-row items-center gap-3"> <View className="flex-row items-center gap-3">
<Text className="text-xs text-gray-600">Movie</Text> <Text className="text-xs text-gray-600">Movie</Text>
<View className="h-1 w-1 rounded-3xl bg-gray-600" /> <View className="h-1 w-1 rounded-3xl bg-gray-600" />
<Text className="text-sm text-gray-600">2023</Text> <Text className="text-sm text-gray-600">2023</Text>
</View> </View>
</View> </View>
); );
} }

View File

@@ -1,20 +1,20 @@
import { Text, View } from 'react-native'; import { Text, View } from 'react-native';
type Props = { type Props = {
title?: React.ReactNode | string; title?: React.ReactNode | string;
subtitle?: string; subtitle?: string;
children?: React.ReactNode; children?: React.ReactNode;
}; };
export default function ScreenLayout({ title, subtitle, children }: Props) { export default function ScreenLayout({ title, subtitle, children }: Props) {
return ( return (
<View tw="bg-shade-900 flex-1 p-12"> <View className="bg-shade-900 flex-1 p-12">
{typeof title === 'string' && ( {typeof title === 'string' && (
<Text className="text-2xl font-bold text-white">{title}</Text> <Text className="text-2xl font-bold text-white">{title}</Text>
)} )}
{typeof title !== 'string' && title} {typeof title !== 'string' && title}
<Text className="mt-1 text-sm font-bold text-white">{subtitle}</Text> <Text className="mt-1 text-sm font-bold text-white">{subtitle}</Text>
<View className="py-3">{children}</View> <View className="py-3">{children}</View>
</View> </View>
); );
} }

View File

@@ -0,0 +1,14 @@
export default {
primary: {
100: '#C082FF',
300: '#8D44D6',
400: '#7831BF',
},
secondary: {
50: '#676790',
200: '#3F3F60',
300: '#32324F',
700: '#131322',
},
background: '#0a0a12',
};

View File

@@ -1 +1 @@
export const TMDB_POSTER_PATH = `https://image.tmdb.org/t/p`; export const TMDB_POSTER_PATH = `https://image.tmdb.org/t/p`;

View File

@@ -1,16 +0,0 @@
import { useMemo } from 'react';
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindConfig from '../../tailwind.config';
const useTailwind = () => {
const tailwind = useMemo(() => resolveConfig(tailwindConfig), []);
console.log(tailwind);
return {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
colors: tailwind.theme.colors as typeof tailwindConfig.theme.extend.colors,
};
};
export default useTailwind;

View File

@@ -42,7 +42,9 @@ const { mergeConfig } = require('metro-config');
const { withNativeWind } = require('nativewind/metro'); const { withNativeWind } = require('nativewind/metro');
const exclusionList = require('metro-config/src/defaults/exclusionList'); const exclusionList = require('metro-config/src/defaults/exclusionList');
const defaultConfig = getDefaultConfig(__dirname); const defaultConfig = getDefaultConfig(__dirname, {
isCSSEnabled: true,
});
const { assetExts, sourceExts } = defaultConfig.resolver; const { assetExts, sourceExts } = defaultConfig.resolver;
/** /**
@@ -67,7 +69,7 @@ const customConfig = {
const nativeWindConfig = withNativeWind( const nativeWindConfig = withNativeWind(
mergeConfig(defaultConfig, customConfig), mergeConfig(defaultConfig, customConfig),
{ {
input: './styles/global.css', input: './app/styles/global.css',
configPath: './tailwind.config.ts', configPath: './tailwind.config.ts',
}, },
); );
@@ -81,5 +83,4 @@ const nxConfig = withNxMetro(nativeWindConfig, {
// Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules) // Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules)
watchFolders: [], watchFolders: [],
}); });
module.exports = nxConfig; module.exports = nxConfig;

View File

@@ -29,6 +29,7 @@
"expo-web-browser": "^12.5.0", "expo-web-browser": "^12.5.0",
"jest": "*", "jest": "*",
"jest-expo": "*", "jest-expo": "*",
"metro": "*",
"metro-config": "*", "metro-config": "*",
"nativewind": "^4.0.23", "nativewind": "^4.0.23",
"pod-install": "*", "pod-install": "*",
@@ -67,11 +68,5 @@
"pod-install": "^0.1.39", "pod-install": "^0.1.39",
"react-test-renderer": "18.2.0", "react-test-renderer": "18.2.0",
"typescript": "~5.2.2" "typescript": "~5.2.2"
},
"overrides": {
"react-refresh": "~0.14.0"
},
"resolutions": {
"react-refresh": "~0.14.0"
} }
} }

View File

@@ -8,7 +8,8 @@
"executor": "@nx/expo:start", "executor": "@nx/expo:start",
"dependsOn": ["ensure-symlink", "sync-deps"], "dependsOn": ["ensure-symlink", "sync-deps"],
"options": { "options": {
"port": 8081 "port": 8081,
"clear": true
} }
}, },
"serve": { "serve": {

View File

@@ -1,22 +0,0 @@
import { StyleSheet } from 'react-native';
export const globalStyles = StyleSheet.create({
fOpenSansLight: {
fontFamily: 'OpenSansLight',
},
fOpenSansBold: {
fontFamily: 'OpenSansBold',
},
fOpenSansSemiBold: {
fontFamily: 'OpenSansSemiBold',
},
fOpenSansMedium: {
fontFamily: 'OpenSansMedium',
},
fOpenSansExtraBold: {
fontFamily: 'OpenSansExtraBold',
},
fOpenSansRegular: {
fontFamily: 'OpenSansRegular',
},
});

View File

@@ -1,56 +1,19 @@
// const colors = require('tailwindcss/colors');
// // https://github.com/marklawlor/nativewind/issues/573
// /** @type {import('tailwindcss').Config} */
// module.exports = {
// content: ['./**/*.{js,jsx,ts,tsx}'],
// theme: {
// extend: {
// colors: {
// ...colors,
// purple: {
// 100: '#C082FF',
// 300: '#8D44D6',
// 400: '#7831BF',
// },
// shade: {
// 50: '#676790',
// 200: '#3F3F60',
// 300: '#32324F',
// 700: '#131322',
// 900: '#0A0A12',
// },
// },
// },
// },
// plugins: [],
// };
// @ts-expect-error - no types // @ts-expect-error - no types
import nativewind from 'nativewind/preset'; import nativewind from 'nativewind/preset';
import type { Config } from 'tailwindcss'; import type { Config } from 'tailwindcss';
import colors from './app/constants/Colors';
export default { export default {
content: ['./src/**/*.{ts,tsx}'], content: ['./app/**/*.{js,jsx,ts,tsx}'],
presets: [ presets: [
nativewind, nativewind,
{ {
theme: { theme: {
extend: { extend: {
colors: { colors,
purple: { fontFamily: {
100: '#C082FF',
300: '#8D44D6', }
400: '#7831BF',
},
shade: {
50: '#676790',
200: '#3F3F60',
300: '#32324F',
700: '#131322',
900: '#0A0A12',
},
},
}, },
}, },
}, },

View File

@@ -12,5 +12,11 @@
"**/*.spec.tsx", "**/*.spec.tsx",
"test-setup.ts" "test-setup.ts"
], ],
"include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "tailwind.config.ts"] "include": [
"**/*.ts",
"**/*.tsx",
"**/*.js",
"**/*.jsx",
"tailwind.config.ts"
]
} }

View File

@@ -3,10 +3,7 @@
"compilerOptions": { "compilerOptions": {
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"jsx": "react-native", "jsx": "react-native",
"lib": [ "lib": ["dom", "esnext"],
"dom",
"esnext"
],
"moduleResolution": "node", "moduleResolution": "node",
"skipLibCheck": true, "skipLibCheck": true,
"resolveJsonModule": true, "resolveJsonModule": true,
@@ -15,16 +12,13 @@
"allowJs": true, "allowJs": true,
}, },
"files": [], "files": [],
"include": [ "include": [".expo/types/**/*.ts", "expo-env.d.ts"],
".expo/types/**/*.ts",
"expo-env.d.ts"
],
"references": [ "references": [
{ {
"path": "./tsconfig.app.json" "path": "./tsconfig.app.json",
}, },
{ {
"path": "./tsconfig.spec.json" "path": "./tsconfig.spec.json",
} },
] ],
} }

View File

@@ -60,5 +60,16 @@
"react-native-svg-transformer": "1.3.0", "react-native-svg-transformer": "1.3.0",
"react-native-web": "~0.19.9", "react-native-web": "~0.19.9",
"tslib": "^2.3.0" "tslib": "^2.3.0"
},
"pnpm": {
"patchedDependencies": {
"nativewind@4.0.23": "patches/nativewind@4.0.23.patch"
}
},
"overrides": {
"react-refresh": "~0.14.0"
},
"resolutions": {
"react-refresh": "~0.14.0"
} }
} }

View File

@@ -0,0 +1,13 @@
diff --git a/dist/metro/transformer.js b/dist/metro/transformer.js
index 1bda43b116d02834db01a42e64dd302e3d3fe785..8ff7f8a324cd9a8531df915a704d604828959e78 100644
--- a/dist/metro/transformer.js
+++ b/dist/metro/transformer.js
@@ -16,7 +16,7 @@ new globalThis.WebSocket(\`\${url}:${config.nativewind.fastRefreshPort}\`).addEv
StyleSheet.registerCompiled(JSON.parse('${config.nativewind.parsedOutput}'));`, "utf8"), options);
}
else if (options.platform === "web") {
- return metro_transform_worker_1.default.transform(config, projectRoot, filename, Buffer.from(`require('${config.nativewind.outputPath}');`, "utf8"), options);
+ return metro_transform_worker_1.default.transform(config, projectRoot, filename, Buffer.from(`require('${config.nativewind.outputPath.replace(/\\/g, '\\\\')}');`, "utf8"), options);
}
else {
data = Buffer.from(config.nativewind.rawOutput, "utf8");

2068
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff