navigation
parent
7fd1ce9596
commit
10ac84df72
|
@ -1,13 +1,16 @@
|
|||
module.exports = {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
plugins: [
|
||||
[
|
||||
'module-resolver',
|
||||
{
|
||||
alias: {
|
||||
'@caj': './src/caj',
|
||||
module.exports = function (api) {
|
||||
api.cache(true);
|
||||
return {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
plugins: [
|
||||
[
|
||||
'module-resolver',
|
||||
{
|
||||
alias: {
|
||||
'@caj': './src/caj',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
],
|
||||
};
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
|
@ -12,23 +12,35 @@
|
|||
"lint": "eslint ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-navigation/native": "^6.1.0",
|
||||
"@react-navigation/native-stack": "^6.9.5",
|
||||
"@react-navigation/bottom-tabs": "^6.5.2",
|
||||
"@react-navigation/native": "^6.1.1",
|
||||
"@react-navigation/native-stack": "^6.9.7",
|
||||
"@react-spring/native": "^9.6.1",
|
||||
"@react-spring/web": "^9.6.1",
|
||||
"@reduxjs/toolkit": "^1.9.1",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-esnext": "^1.1.3",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"native-base": "^3.4.23",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "18.1.0",
|
||||
"react-native": "0.70.6",
|
||||
"react-native-encrypted-storage": "^4.0.3",
|
||||
"react-native-gesture-handler": "^2.8.0",
|
||||
"react-native-reanimated": "^2.13.0",
|
||||
"react-native-safe-area-context": "^4.4.1",
|
||||
"react-native-screens": "^3.18.2",
|
||||
"react-native-web": "^0.18.10"
|
||||
"react-native-web": "^0.18.10",
|
||||
"react-redux": "^8.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.9",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/runtime": "^7.20.6",
|
||||
"@react-native-community/eslint-config": "^2.0.0",
|
||||
"@types/node": "^18.11.10",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react-dom": "^18.0.9",
|
||||
"@types/webpack": "^5.28.0",
|
||||
"babel-jest": "^26.6.3",
|
||||
"babel-loader": "^9.1.0",
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
import React, {useState, useEffect} from 'react';
|
||||
|
||||
import {StyleSheet, Appearance} from 'react-native';
|
||||
import {
|
||||
NativeBaseProvider,
|
||||
Box,
|
||||
Input,
|
||||
Text,
|
||||
Button,
|
||||
useColorMode,
|
||||
useColorModeValue,
|
||||
StatusBar,
|
||||
VStack,
|
||||
Center,
|
||||
Avatar,
|
||||
} from 'native-base';
|
||||
import {NavigationContainer} from '@react-navigation/native';
|
||||
import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import {theme} from '@caj/configs/colors';
|
||||
|
||||
import imgSrc from '@caj/img/maimg.png';
|
||||
|
||||
interface User {
|
||||
name: string;
|
||||
id: number;
|
||||
}
|
||||
|
||||
const user: User = {
|
||||
name: 'Hayes',
|
||||
id: 0,
|
||||
};
|
||||
|
||||
function TestContent() {
|
||||
const {colorMode, toggleColorMode, setColorMode} = useColorMode();
|
||||
|
||||
//var bg = useColorModeValue('dark', 'coolGray.800');
|
||||
|
||||
const [curTheme, setTheme] = useState(1);
|
||||
var bg = '#222';
|
||||
|
||||
if (curTheme !== 1) bg = curTheme === 0 ? '#000' : '#fff';
|
||||
|
||||
console.log(colorMode);
|
||||
const toggleSwitch = () => {
|
||||
console.log('switch');
|
||||
toggleColorMode();
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.container, {backgroundColor: bg}]}>
|
||||
<VStack space={4} alignItems="center">
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
<Box>
|
||||
<Text style={{}}>ma boyy :--)))</Text>
|
||||
</Box>
|
||||
<Avatar bg="green.500" size="xl" source={imgSrc}>
|
||||
EM
|
||||
</Avatar>
|
||||
<Box>
|
||||
<Input w="90%" shadow={10} placeholder="Enter your name" />
|
||||
</Box>
|
||||
<Button
|
||||
w="64"
|
||||
onPress={() => {
|
||||
let theme = curTheme + 1;
|
||||
if (theme > 2) theme = 0;
|
||||
setTheme(theme);
|
||||
|
||||
setColorMode(theme === 0 || theme === 1 ? 'dark' : 'light');
|
||||
}}
|
||||
h={10}>
|
||||
Change theme
|
||||
</Button>
|
||||
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
</VStack>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const Bar = () => {
|
||||
const {colorMode, toggleColorMode} = useColorMode();
|
||||
|
||||
return (
|
||||
<StatusBar
|
||||
barStyle={colorMode === 'dark' ? 'light-content' : 'dark-content'}
|
||||
backgroundColor="transparent"
|
||||
translucent={true}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const App = () => {
|
||||
useEffect(() => {
|
||||
// this code will run once
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<NavigationContainer>
|
||||
<NativeBaseProvider theme={theme}>
|
||||
<Bar />
|
||||
<TestContent />
|
||||
</NativeBaseProvider>
|
||||
</NavigationContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
height: '100%',
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
/*
|
||||
const styles = StyleSheet.create({
|
||||
baseText: {
|
||||
fontFamily: 'Cochin',
|
||||
},
|
||||
titleText: {
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
image: {
|
||||
width: 500,
|
||||
height: 500,
|
||||
borderWidth: 1,
|
||||
},
|
||||
});*/
|
||||
|
||||
export default App;
|
176
src/App.tsx
176
src/App.tsx
|
@ -1,143 +1,69 @@
|
|||
import React, {useState} from 'react';
|
||||
import React, {useState, useEffect, Fragment} from 'react';
|
||||
|
||||
import {StyleSheet, Appearance} from 'react-native';
|
||||
import {
|
||||
NativeBaseProvider,
|
||||
Box,
|
||||
Input,
|
||||
Text,
|
||||
Button,
|
||||
useColorMode,
|
||||
useColorModeValue,
|
||||
StatusBar,
|
||||
VStack,
|
||||
Center,
|
||||
Avatar,
|
||||
} from 'native-base';
|
||||
import {NativeBaseProvider} from 'native-base';
|
||||
import {NavigationContainer} from '@react-navigation/native';
|
||||
import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import {theme} from '@caj/configs/colors';
|
||||
import {getBackgroundColor, theme, ThemeSwitcher} from '@caj/configs/colors';
|
||||
|
||||
import imgSrc from '@caj/img/maimg.png';
|
||||
import StatusBar from './StatusBar';
|
||||
import Navigation, {linking} from './Navigation';
|
||||
|
||||
interface User {
|
||||
name: string;
|
||||
id: number;
|
||||
}
|
||||
|
||||
const user: User = {
|
||||
name: 'Hayes',
|
||||
id: 0,
|
||||
};
|
||||
|
||||
function TestContent() {
|
||||
const {colorMode, toggleColorMode, setColorMode} = useColorMode();
|
||||
|
||||
//var bg = useColorModeValue('dark', 'coolGray.800');
|
||||
|
||||
const [curTheme, setTheme] = useState(1);
|
||||
var bg = '#222';
|
||||
|
||||
if (curTheme !== 1) bg = curTheme === 0 ? '#000' : '#fff';
|
||||
|
||||
console.log(colorMode);
|
||||
const toggleSwitch = () => {
|
||||
console.log('switch');
|
||||
toggleColorMode();
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.container, {backgroundColor: bg}]}>
|
||||
<VStack space={4} alignItems="center">
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
<Box>
|
||||
<Text style={{}}>ma boyy :--)))</Text>
|
||||
</Box>
|
||||
<Avatar bg="green.500" size="xl" source={imgSrc}>
|
||||
EM
|
||||
</Avatar>
|
||||
<Box>
|
||||
<Input w="90%" shadow={10} placeholder="Enter your name" />
|
||||
</Box>
|
||||
<Button
|
||||
w="64"
|
||||
onPress={() => {
|
||||
let theme = curTheme + 1;
|
||||
if (theme > 2) theme = 0;
|
||||
setTheme(theme);
|
||||
|
||||
setColorMode(theme === 0 || theme === 1 ? 'dark' : 'light');
|
||||
}}
|
||||
h={10}>
|
||||
Change theme
|
||||
</Button>
|
||||
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
</VStack>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const Bar = () => {
|
||||
const {colorMode, toggleColorMode} = useColorMode();
|
||||
|
||||
return (
|
||||
<StatusBar
|
||||
barStyle={colorMode === 'dark' ? 'light-content' : 'dark-content'}
|
||||
backgroundColor="transparent"
|
||||
translucent={true}
|
||||
/>
|
||||
);
|
||||
};
|
||||
import {Provider, useSelector} from 'react-redux';
|
||||
import {RootState, store} from '@caj/redux/store';
|
||||
import StartHelper from './appStart/StartHelper';
|
||||
import {appStatus} from '@caj/configs/appNonSaveVar';
|
||||
import {ThemeMode} from '@caj/configs/appVar';
|
||||
|
||||
const App = () => {
|
||||
useEffect(() => {
|
||||
// this code will run once
|
||||
}, [])
|
||||
console.log('App opened.');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<NavigationContainer>
|
||||
<Provider store={store}>
|
||||
<OtherProviders />
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const OtherProviders = () => {
|
||||
const globalTheme = useSelector(
|
||||
(state: RootState) => state.appVariables.preferences.theme,
|
||||
);
|
||||
|
||||
const navigationTheme = {
|
||||
dark: globalTheme !== ThemeMode.Light,
|
||||
colors: {
|
||||
primary: '#ff7d4f',
|
||||
background: getBackgroundColor(globalTheme),
|
||||
card: '#222',
|
||||
text: '#fff',
|
||||
border: '#ff7d4f',
|
||||
notification: '#fff',
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<NavigationContainer theme={navigationTheme} linking={linking}>
|
||||
<NativeBaseProvider theme={theme}>
|
||||
<Bar />
|
||||
<TestContent />
|
||||
<MainComponent />
|
||||
</NativeBaseProvider>
|
||||
</NavigationContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
height: '100%',
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
/*
|
||||
const styles = StyleSheet.create({
|
||||
baseText: {
|
||||
fontFamily: 'Cochin',
|
||||
},
|
||||
titleText: {
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
image: {
|
||||
width: 500,
|
||||
height: 500,
|
||||
borderWidth: 1,
|
||||
},
|
||||
});*/
|
||||
const MainComponent = () => {
|
||||
const currentAppStatus = useSelector(
|
||||
(state: RootState) => state.nonSaveVariables.appStatus,
|
||||
);
|
||||
return (
|
||||
<Fragment>
|
||||
<StartHelper />
|
||||
<ThemeSwitcher />
|
||||
<StatusBar />
|
||||
{currentAppStatus === appStatus.APP_RUNNING ? <Navigation /> : null}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
import React, {useState, useEffect} from 'react';
|
||||
|
||||
import {StyleSheet, Appearance} from 'react-native';
|
||||
import {Box, Input, Text, Button, VStack, Center, Avatar} from 'native-base';
|
||||
import {NavigationContainer} from '@react-navigation/native';
|
||||
import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import {useSelector, useDispatch} from 'react-redux';
|
||||
import {RootState} from '@caj/redux/store';
|
||||
import {appVarActions} from '@caj/configs/appVarReducer';
|
||||
|
||||
import imgSrc from '@caj/img/maimg.png';
|
||||
import {placeholder} from '@caj/lang/default';
|
||||
import {getBackgroundColor} from '@caj/configs/colors';
|
||||
import {saveVarChanges} from '@caj/helper/appData';
|
||||
|
||||
function CounterNum() {
|
||||
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||
const version = useSelector(
|
||||
(state: RootState) => state.appVariables.preferences.version,
|
||||
);
|
||||
|
||||
return <Text>{placeholder(lang.curVersion, {version})}</Text>;
|
||||
}
|
||||
|
||||
export default function Navigation() {
|
||||
const theme = useSelector(
|
||||
(state: RootState) => state.appVariables.preferences.theme,
|
||||
);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
//const {colorMode, toggleColorMode, setColorMode} = useColorMode();
|
||||
|
||||
//var bg = useColorModeValue('dark', 'coolGray.800');
|
||||
|
||||
//const [curTheme, setTheme] = useState(1);
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={[styles.container, {backgroundColor: getBackgroundColor(theme)}]}>
|
||||
<VStack space={4} alignItems="center">
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
<Box>
|
||||
<CounterNum />
|
||||
</Box>
|
||||
<Avatar bg="green.500" size="xl" source={imgSrc}>
|
||||
EM
|
||||
</Avatar>
|
||||
<Box>
|
||||
<Input w="90%" shadow={10} placeholder="Enter your name" />
|
||||
</Box>
|
||||
<Button
|
||||
w="64"
|
||||
onPress={() => {
|
||||
let _theme = theme + 1;
|
||||
if (_theme > 2) _theme = 0;
|
||||
dispatch(appVarActions.setTheme(_theme));
|
||||
saveVarChanges();
|
||||
}}
|
||||
h={10}>
|
||||
Change theme
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
w="48"
|
||||
onPress={() => {
|
||||
//dispatch(appVarActions.setVersion(3));
|
||||
}}
|
||||
h={10}>
|
||||
version +1
|
||||
</Button>
|
||||
<Button
|
||||
w="48"
|
||||
onPress={() => {
|
||||
//dispatch(appVarActions.setVersion(2));
|
||||
}}
|
||||
h={10}>
|
||||
version -1
|
||||
</Button>
|
||||
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
|
||||
<Center w="64" h="20" bg="indigo.300" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.500" rounded="md" shadow={3} />
|
||||
<Center w="64" h="20" bg="indigo.700" rounded="md" shadow={3} />
|
||||
</VStack>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
height: '100%',
|
||||
flex: 1,
|
||||
},
|
||||
});
|
|
@ -0,0 +1,139 @@
|
|||
import React, {useState, useEffect} from 'react';
|
||||
|
||||
import {StyleSheet, Appearance} from 'react-native';
|
||||
import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import {useSelector, useDispatch} from 'react-redux';
|
||||
import {RootState} from '@caj/redux/store';
|
||||
import {appVarActions} from '@caj/configs/appVarReducer';
|
||||
|
||||
import imgSrc from '@caj/img/maimg.png';
|
||||
import {placeholder} from '@caj/lang/default';
|
||||
import {getBackgroundColor} from '@caj/configs/colors';
|
||||
import {saveVarChanges} from '@caj/helper/appData';
|
||||
|
||||
import {Box, Input, VStack, Center, Avatar, Text, Button} from 'native-base';
|
||||
import {View} from 'react-native';
|
||||
|
||||
import {
|
||||
LinkingOptions,
|
||||
NavigationContainer,
|
||||
useNavigation,
|
||||
} from '@react-navigation/native';
|
||||
import {
|
||||
createNativeStackNavigator,
|
||||
NativeStackNavigationProp,
|
||||
} from '@react-navigation/native-stack';
|
||||
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
height: '100%',
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export const linking: LinkingOptions<{
|
||||
Auth: string;
|
||||
Home: string;
|
||||
Table: string;
|
||||
Loading: string;
|
||||
}> = {
|
||||
prefixes: ['http://'],
|
||||
config: {
|
||||
initialRouteName: 'Loading',
|
||||
screens: {
|
||||
Auth: 'auth',
|
||||
Home: 'home',
|
||||
Table: 'table',
|
||||
Loading: 'loading',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export type HomeStackNavigatorParamList = {
|
||||
Home: undefined;
|
||||
Maps: undefined;
|
||||
Chat: undefined;
|
||||
Test: undefined;
|
||||
Settings: undefined;
|
||||
};
|
||||
|
||||
export type HomeScreenNavigationProp =
|
||||
NativeStackNavigationProp<HomeStackNavigatorParamList>;
|
||||
|
||||
export default function Navigation() {
|
||||
const theme = useSelector(
|
||||
(state: RootState) => state.appVariables.preferences.theme,
|
||||
);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (
|
||||
<Tab.Navigator screenOptions={{headerShown: false}}>
|
||||
<Tab.Screen name="Home" component={HomeStackScreen} />
|
||||
<Tab.Screen name="Settings" component={SettingsScreen} />
|
||||
<Tab.Screen
|
||||
name="Chat"
|
||||
options={{headerShown: true, tabBarStyle: {display: 'none'}}}
|
||||
component={ChatScreen}
|
||||
/>
|
||||
</Tab.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
function ChatScreen() {
|
||||
return (
|
||||
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
|
||||
<Text>Chat!</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
function HomeScreen() {
|
||||
const navigation = useNavigation<HomeScreenNavigationProp>();
|
||||
return (
|
||||
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
|
||||
<Text>Home screen</Text>
|
||||
<Button onPress={() => navigation.navigate('Test')}>Go to Test</Button>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
function SettingsScreen() {
|
||||
const navigation = useNavigation<HomeScreenNavigationProp>();
|
||||
return (
|
||||
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
|
||||
<Text>Settings screen</Text>
|
||||
<Button onPress={() => navigation.navigate('Chat')}>Go to Chat</Button>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const HomeStack = createNativeStackNavigator<HomeStackNavigatorParamList>();
|
||||
|
||||
function HomeStackScreen() {
|
||||
return (
|
||||
<HomeStack.Navigator>
|
||||
<HomeStack.Screen
|
||||
name="Maps"
|
||||
options={{headerShown: false}}
|
||||
component={HomeScreen}
|
||||
/>
|
||||
<HomeStack.Screen name="Test" component={ChatScreen} />
|
||||
</HomeStack.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
const SettingsStack = createNativeStackNavigator<HomeStackNavigatorParamList>();
|
||||
|
||||
function SettingsStackScreen() {
|
||||
return (
|
||||
<SettingsStack.Navigator>
|
||||
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
|
||||
<SettingsStack.Screen name="Chat" component={ChatScreen} />
|
||||
</SettingsStack.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
const Tab = createBottomTabNavigator();
|
|
@ -0,0 +1,15 @@
|
|||
import {useColorMode} from 'native-base';
|
||||
|
||||
import {StatusBar as NBStatusBar} from 'native-base';
|
||||
|
||||
export default function StatusBar() {
|
||||
const {colorMode} = useColorMode();
|
||||
|
||||
return (
|
||||
<NBStatusBar
|
||||
barStyle={colorMode === 'dark' ? 'light-content' : 'dark-content'}
|
||||
backgroundColor="transparent"
|
||||
translucent={true}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
import {Platform, StyleSheet, View, ScrollView} from 'react-native';
|
||||
|
||||
import {Center, Heading, Text, Spinner, HStack} from 'native-base';
|
||||
import {animated, useSpring} from '@react-spring/native';
|
||||
|
||||
import {SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import {useSelector, useDispatch} from 'react-redux';
|
||||
import {RootState, store} from '@caj/redux/store';
|
||||
|
||||
import imgSrc from '@caj/img/maimg.png';
|
||||
import {placeholder} from '@caj/lang/default';
|
||||
import {getBackgroundColor} from '@caj/configs/colors';
|
||||
import {useEffect} from 'react';
|
||||
import {initAppData} from '@caj/helper/appData';
|
||||
import {appStatus} from '@caj/configs/appNonSaveVar';
|
||||
import {appNonSaveVarActions} from '@caj/configs/appNonSaveVarReducer';
|
||||
|
||||
const AnimationView = animated(View);
|
||||
|
||||
function onAppStart() {
|
||||
initAppData().then(() => {
|
||||
console.log('finish');
|
||||
setTimeout(() => {
|
||||
store.dispatch(appNonSaveVarActions.setAppStatus(appStatus.APP_RUNNING));
|
||||
}, 500);
|
||||
//store.dispatch(actions.loadPreferences(appVar));
|
||||
});
|
||||
}
|
||||
|
||||
function StartHelper() {
|
||||
const currentAppStatus = useSelector(
|
||||
(state: RootState) => state.nonSaveVariables.appStatus,
|
||||
);
|
||||
|
||||
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||
const theme = useSelector(
|
||||
(state: RootState) => state.appVariables.preferences.theme,
|
||||
);
|
||||
|
||||
const [motionProps, api] = useSpring(
|
||||
() => ({
|
||||
from: {
|
||||
translateX: -150,
|
||||
width: 4,
|
||||
opacity: 1,
|
||||
},
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
api.start({
|
||||
to: [
|
||||
{
|
||||
translateX: 150,
|
||||
width: 4,
|
||||
opacity: 1,
|
||||
},
|
||||
{
|
||||
translateX: -150,
|
||||
width: 4,
|
||||
opacity: 1,
|
||||
},
|
||||
],
|
||||
loop: true,
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(onAppStart, []);
|
||||
|
||||
if (currentAppStatus === appStatus.APP_RUNNING) return null;
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={[{flex: 1, backgroundColor: getBackgroundColor(theme)}]}>
|
||||
<Center height={'100%'}>
|
||||
<AnimationView
|
||||
style={{
|
||||
height: 100,
|
||||
position: 'absolute',
|
||||
|
||||
backgroundColor: '#f22',
|
||||
borderRadius: 8,
|
||||
|
||||
width: motionProps.width,
|
||||
opacity: motionProps.opacity,
|
||||
transform: [{translateX: motionProps.translateX}, {translateY: 5}],
|
||||
}}
|
||||
/>
|
||||
<Heading>{lang.appName}</Heading>
|
||||
|
||||
<HStack mt="5" space={2} justifyContent="center">
|
||||
<Spinner color="#ff7d4f" accessibilityLabel="Loading posts" />
|
||||
<Heading color="#ff7d4f" fontSize="md">
|
||||
{lang.startHelper1}
|
||||
</Heading>
|
||||
</HStack>
|
||||
</Center>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
export default StartHelper;
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
|
||||
export function initAppData() {
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
//these variables should not changed by the user and will not be saved in storage
|
||||
|
||||
import {getVersionByNum, VersionType} from '@caj/helper/version';
|
||||
|
||||
export const APP_VERSION = getVersionByNum(2);
|
||||
export const AppVarMaxBackups: number = 10;
|
||||
|
||||
export enum appStatus {
|
||||
IS_LOADING,
|
||||
APP_RUNNING,
|
||||
}
|
||||
|
||||
export enum connectionStatus {
|
||||
UNKNOWN,
|
||||
OFFLINE,
|
||||
ONLINE,
|
||||
RECONNECTING,
|
||||
}
|
||||
|
||||
export interface NON_SAVE_VARS {
|
||||
currentAppVersion: VersionType;
|
||||
appStatus: appStatus;
|
||||
connectionStatus: connectionStatus;
|
||||
}
|
||||
|
||||
export const non_save_vars: NON_SAVE_VARS = {
|
||||
currentAppVersion: APP_VERSION,
|
||||
appStatus: appStatus.IS_LOADING,
|
||||
connectionStatus: connectionStatus.UNKNOWN,
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
import {createSlice} from '@reduxjs/toolkit';
|
||||
import type {PayloadAction} from '@reduxjs/toolkit';
|
||||
|
||||
import {appStatus, non_save_vars} from './appNonSaveVar';
|
||||
|
||||
export const appNonSaveVariablesSlice = createSlice({
|
||||
name: 'non_save_vars',
|
||||
initialState: non_save_vars,
|
||||
reducers: {
|
||||
setAppStatus: (state, action: PayloadAction<appStatus>) => {
|
||||
state.appStatus = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Action creators are generated for each case reducer function
|
||||
const {actions} = appNonSaveVariablesSlice;
|
||||
export const appNonSaveVarActions = actions;
|
||||
|
||||
export default appNonSaveVariablesSlice.reducer;
|
|
@ -0,0 +1,55 @@
|
|||
import {VersionType} from '@caj/helper/version';
|
||||
import {APP_VERSION} from './appNonSaveVar';
|
||||
|
||||
export enum ThemeMode {
|
||||
Darkest = 0,
|
||||
Dark = 1,
|
||||
Light = 2,
|
||||
}
|
||||
|
||||
export function applyUpdateChanges(appVar: any): Promise<void> {
|
||||
return new Promise<void>(function (resolve, reject) {
|
||||
appVar.version += 1;
|
||||
|
||||
console.log(appVar.version);
|
||||
|
||||
function finish() {
|
||||
resolve();
|
||||
}
|
||||
|
||||
switch (appVar.version) {
|
||||
case 3: {
|
||||
let appVarF = appVar as PREFERENCES_VARS;
|
||||
|
||||
appVar = appVarF;
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
let appVarF = appVar;
|
||||
|
||||
appVar = appVarF;
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//these variables may be changed by the user and will be saved in storage
|
||||
|
||||
export interface PREFERENCES_VARS {
|
||||
version: VersionType;
|
||||
theme: ThemeMode;
|
||||
}
|
||||
|
||||
export const preferences_vars_default: PREFERENCES_VARS = {
|
||||
version: APP_VERSION, //version of datatypes in storage
|
||||
theme: ThemeMode.Dark,
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
import {createSlice} from '@reduxjs/toolkit';
|
||||
import type {PayloadAction} from '@reduxjs/toolkit';
|
||||
|
||||
import {PREFERENCES_VARS, preferences_vars_default, ThemeMode} from './appVar';
|
||||
import {non_save_vars, NON_SAVE_VARS} from './appNonSaveVar';
|
||||
import LangFormat from '@caj/lang/default';
|
||||
import {lang as defaultLang} from '@caj/lang/en';
|
||||
|
||||
export interface appVariablesState {
|
||||
preferences: PREFERENCES_VARS;
|
||||
lang: LangFormat;
|
||||
}
|
||||
|
||||
const initialState: appVariablesState = {
|
||||
preferences: preferences_vars_default,
|
||||
lang: defaultLang,
|
||||
};
|
||||
|
||||
export const appVariablesSlice = createSlice({
|
||||
name: 'appVariables',
|
||||
initialState,
|
||||
reducers: {
|
||||
setTheme: (state, action: PayloadAction<ThemeMode>) => {
|
||||
state.preferences.theme = action.payload;
|
||||
},
|
||||
setLang: (state, action: PayloadAction<LangFormat>) => {
|
||||
state.lang = action.payload;
|
||||
},
|
||||
loadPreferences: (state, action: PayloadAction<PREFERENCES_VARS>) => {
|
||||
state.preferences = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Action creators are generated for each case reducer function
|
||||
const {actions} = appVariablesSlice;
|
||||
export const appVarActions = actions;
|
||||
|
||||
export default appVariablesSlice.reducer;
|
|
@ -1,4 +1,10 @@
|
|||
import { extendTheme } from 'native-base';
|
||||
import {Platform} from 'react-native';
|
||||
import {extendTheme, useColorMode} from 'native-base';
|
||||
import {ThemeMode} from './appVar';
|
||||
|
||||
import {useSelector} from 'react-redux';
|
||||
import {RootState} from '@caj/redux/store';
|
||||
import {useEffect} from 'react';
|
||||
|
||||
export const theme = extendTheme({
|
||||
config: {
|
||||
|
@ -18,23 +24,18 @@ export const theme = extendTheme({
|
|||
300: '#292929',
|
||||
800: '#181725',
|
||||
},
|
||||
green: {
|
||||
300: '#53B175',
|
||||
},
|
||||
|
||||
primary: {
|
||||
50: '#E3F2F9',
|
||||
100: '#C5E4F3',
|
||||
200: '#A2D4EC',
|
||||
300: '#7AC1E4',
|
||||
400: '#47A9DA',
|
||||
500: '#0088CC',
|
||||
600: '#007AB8',
|
||||
700: '#006BA1',
|
||||
800: '#005885',
|
||||
900: '#003F5E',
|
||||
},
|
||||
amber: {
|
||||
400: '#d97706',
|
||||
50: '#fff4f1',
|
||||
100: '#ffd6c9',
|
||||
200: '#ffb9a1',
|
||||
300: '#ff9b79',
|
||||
400: '#ff7d50',
|
||||
500: '#f96e40',
|
||||
600: '#f26030',
|
||||
700: '#e95321',
|
||||
800: '#d54b1d',
|
||||
900: '#ba4721',
|
||||
},
|
||||
},
|
||||
components: {
|
||||
|
@ -76,4 +77,43 @@ export const theme = extendTheme({
|
|||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
export function getBackgroundColor(tm: ThemeMode): string {
|
||||
switch (tm) {
|
||||
case ThemeMode.Light:
|
||||
return '#fff';
|
||||
case ThemeMode.Darkest:
|
||||
return '#000';
|
||||
default:
|
||||
return '#282f34';
|
||||
}
|
||||
}
|
||||
|
||||
export function isThemeDark(tm: ThemeMode): boolean {
|
||||
return tm <= 1;
|
||||
}
|
||||
|
||||
export function ThemeSwitcher() {
|
||||
const myTheme = useSelector(
|
||||
(state: RootState) => state.appVariables.preferences.theme,
|
||||
);
|
||||
const {setColorMode} = useColorMode();
|
||||
|
||||
useEffect(() => {
|
||||
if (myTheme === ThemeMode.Darkest || myTheme === ThemeMode.Dark)
|
||||
setColorMode('dark');
|
||||
else setColorMode('light');
|
||||
|
||||
if (Platform.OS === 'web') {
|
||||
document.body.setAttribute(
|
||||
'style',
|
||||
'background: ' + getBackgroundColor(myTheme) + ';',
|
||||
);
|
||||
}
|
||||
|
||||
console.log('refreshed');
|
||||
}, [myTheme]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
|
||||
export const testt = { data: "hellow :33 liebe diese Android"};
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
|
||||
export const testt = { data: "hellow :33 liebe diese ios"};
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
|
||||
export const testt = { data: "hellow :33 liebe diese WEB"};
|
|
@ -0,0 +1 @@
|
|||
export {animated, useSpring} from '@react-spring/native';
|
|
@ -0,0 +1 @@
|
|||
export {animated, useSpring} from '@react-spring/web';
|
|
@ -0,0 +1,198 @@
|
|||
import {
|
||||
applyUpdateChanges,
|
||||
PREFERENCES_VARS,
|
||||
preferences_vars_default,
|
||||
} from '@caj/configs/appVar';
|
||||
import {AppVarMaxBackups, APP_VERSION} from '@caj/configs/appNonSaveVar';
|
||||
import {appVarActions} from '@caj/configs/appVarReducer';
|
||||
import {store} from '@caj/redux/store';
|
||||
import {getData, setData} from './storage/appData';
|
||||
import {getVersionByType, stepUpVersionCalc} from './version';
|
||||
|
||||
const APP_CHANGE_BACKUP = 'appVerChangeBackup';
|
||||
|
||||
function setAppVar(appVar: PREFERENCES_VARS) {
|
||||
store.dispatch(appVarActions.loadPreferences(appVar));
|
||||
}
|
||||
|
||||
function makeBackup(key: string, version: number): Promise<void> {
|
||||
return new Promise<void>(function (resolve, reject) {
|
||||
getData('appVar').then(value => {
|
||||
if (value !== null) {
|
||||
setData(key + '#' + version, value).then(() => {
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function refreshVersion(from: number, to: number): Promise<void> {
|
||||
return new Promise<void>(function (resolve, reject) {
|
||||
if (from < to) {
|
||||
// app upgrade
|
||||
console.log('app upgrade detected!');
|
||||
finish();
|
||||
} else if (from > to) {
|
||||
// app downgrade
|
||||
console.log('app downgrade detected!');
|
||||
finish();
|
||||
} else {
|
||||
// app version not changed
|
||||
finish();
|
||||
}
|
||||
|
||||
function finish() {
|
||||
setData('appVersion', APP_VERSION.toString()).then(() => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function initAppData(): Promise<void> {
|
||||
return new Promise<void>(function (resolve, reject) {
|
||||
let appVer: number = -1;
|
||||
|
||||
getData('appVersion').then(_ver => {
|
||||
appVer = typeof _ver === 'string' ? Number.parseInt(_ver) : -1;
|
||||
|
||||
if (appVer === -1) {
|
||||
// no version found in storage
|
||||
setData('appVersion', APP_VERSION.toString()).then(() => {
|
||||
appVer = APP_VERSION;
|
||||
preferencesPull();
|
||||
});
|
||||
|
||||
return;
|
||||
} else if (appVer < APP_VERSION) {
|
||||
// found outdated version: make backup; and upgrade
|
||||
makeBackup(APP_CHANGE_BACKUP, appVer).then(() => {
|
||||
refreshVersion(appVer, APP_VERSION).then(() => {
|
||||
preferencesPull();
|
||||
});
|
||||
});
|
||||
} else if (appVer > APP_VERSION) {
|
||||
// version is too high: make backup; and "downgrade"
|
||||
makeBackup(APP_CHANGE_BACKUP, appVer).then(() => {
|
||||
refreshVersion(appVer, APP_VERSION).then(() => {
|
||||
preferencesPull();
|
||||
});
|
||||
});
|
||||
}
|
||||
preferencesPull();
|
||||
});
|
||||
|
||||
function resetPreferences() {
|
||||
let appVar = preferences_vars_default;
|
||||
|
||||
setData('appVar', JSON.stringify(appVar)).then(() => {
|
||||
setAppVar(appVar);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
function tryToApplyPreferences(
|
||||
appVar: PREFERENCES_VARS,
|
||||
didUpdate = false,
|
||||
) {
|
||||
if (appVar.version < APP_VERSION) {
|
||||
{
|
||||
console.log('ver', appVar.version);
|
||||
console.log('config update needed until', APP_VERSION, appVar);
|
||||
applyUpdateChanges(appVar).then(() => {
|
||||
tryToApplyPreferences(appVar, true);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const changed = checkForUndefined(preferences_vars_default, appVar);
|
||||
|
||||
if (didUpdate === true || changed === true) {
|
||||
setData('appVar', JSON.stringify(appVar)).then(() => {
|
||||
setAppVar(appVar);
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
setAppVar(appVar);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
function preferencesPull() {
|
||||
getData('appVar').then(value => {
|
||||
if (value === null) {
|
||||
resetPreferences();
|
||||
} else {
|
||||
let appVarRaw = null;
|
||||
let isNoJSON = false;
|
||||
try {
|
||||
appVarRaw = JSON.parse(value);
|
||||
} catch (error) {
|
||||
console.error('corrupt appVar! :(');
|
||||
isNoJSON = true;
|
||||
}
|
||||
|
||||
if (isNoJSON) {
|
||||
getData('appVarBackupIndex').then(_index => {
|
||||
let index: number =
|
||||
typeof _index === 'string'
|
||||
? Number.parseInt(_index)
|
||||
: AppVarMaxBackups;
|
||||
index--;
|
||||
if (index < 0) index = AppVarMaxBackups - 1;
|
||||
|
||||
setData('appVarBackup' + index, value).then(() => {
|
||||
setData('appVarBackupIndex', index.toString()).then(() => {
|
||||
resetPreferences();
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
let appVar: PREFERENCES_VARS = appVarRaw;
|
||||
|
||||
tryToApplyPreferences(appVar);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function saveVarChanges() {
|
||||
let appVar = store.getState().appVariables.preferences;
|
||||
setData('appVar', JSON.stringify(appVar)).then(() => {
|
||||
console.log('saved!');
|
||||
});
|
||||
}
|
||||
|
||||
export function checkForUndefined(objDef: any, objReal: any): boolean {
|
||||
let changed = false;
|
||||
|
||||
function checkObj(objDef: any, objReal: any) {
|
||||
for (const key in objDef) {
|
||||
const defValue = objDef[key];
|
||||
let realValue = objReal[key];
|
||||
|
||||
if (typeof defValue === 'undefined') continue;
|
||||
|
||||
if (typeof realValue === 'undefined' || realValue === null) {
|
||||
objReal[key] = defValue;
|
||||
|
||||
changed = true;
|
||||
console.log(key);
|
||||
} else if (
|
||||
typeof defValue === 'object' &&
|
||||
typeof realValue === 'object'
|
||||
) {
|
||||
checkObj(defValue, realValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkObj(objDef, objReal);
|
||||
return changed;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import EncryptedStorage from 'react-native-encrypted-storage';
|
||||
|
||||
export async function getData(key: string): Promise<string | null> {
|
||||
return EncryptedStorage.getItem(key);
|
||||
}
|
||||
|
||||
export async function setData(key: string, value: string): Promise<void> {
|
||||
return EncryptedStorage.setItem(key, value);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
export async function getData(key: string): Promise<string | null> {
|
||||
return new Promise(resolve => {
|
||||
const data = localStorage.getItem(key);
|
||||
resolve(data);
|
||||
});
|
||||
}
|
||||
|
||||
export async function setData(key: string, value: string): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
localStorage.setItem(key, value);
|
||||
resolve();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
export enum VersionType {}
|
||||
|
||||
export function getVersionByNum(ver: number): VersionType {
|
||||
return ver;
|
||||
}
|
||||
|
||||
export function getVersionByType(ver: VersionType): number {
|
||||
return ver;
|
||||
}
|
||||
|
||||
export function stepUpVersionCalc(
|
||||
ver: VersionType,
|
||||
steps: number,
|
||||
): VersionType {
|
||||
return ver + steps;
|
||||
}
|
||||
|
||||
/*const VersionFactor = 1;
|
||||
|
||||
export function getVersionByNum(ver: number): VersionType {
|
||||
let verObj: VersionType;
|
||||
verObj = ver * VersionFactor;
|
||||
|
||||
return verObj;
|
||||
}
|
||||
|
||||
export function getVersionByType(ver: VersionType): number {
|
||||
let verObj: number;
|
||||
verObj = Math.floor(ver / VersionFactor);
|
||||
|
||||
return verObj;
|
||||
}
|
||||
|
||||
export function stepUpVersionCalc(
|
||||
ver: VersionType,
|
||||
steps: number,
|
||||
): VersionType {
|
||||
return ver + steps * VersionFactor;
|
||||
}*/
|
|
@ -0,0 +1,47 @@
|
|||
import {type} from 'os';
|
||||
|
||||
interface LangDetails {
|
||||
langCode: string;
|
||||
langName: string;
|
||||
}
|
||||
|
||||
export default interface LangFormat {
|
||||
details: LangDetails;
|
||||
curVersion: string;
|
||||
appName: string;
|
||||
startHelper1: string;
|
||||
}
|
||||
|
||||
interface LangPlaceholderKeys {
|
||||
version?: number;
|
||||
appName?: string;
|
||||
}
|
||||
|
||||
export function placeholder(text: string, data: LangPlaceholderKeys): string {
|
||||
let out = text;
|
||||
|
||||
for (const key in data) {
|
||||
const rawValue = data[key as keyof LangPlaceholderKeys];
|
||||
|
||||
let _value: any =
|
||||
typeof rawValue === 'number' ? rawValue.toString() : rawValue;
|
||||
|
||||
if (typeof rawValue === 'undefined') _value = 'undefined';
|
||||
let value: string = _value;
|
||||
|
||||
out = out.replaceAll('${' + key + '}', value);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
var str = 'Good ${timeOfTheDay}, ${name}. I am from ${city}, ${age} years old';
|
||||
|
||||
var parts = str.split(/(\$\{\w+?})/g).map(function(v) {
|
||||
var replaced = v.replace(/\$\{(\w+?)}/g, '$1');
|
||||
return content[replaced] || v;
|
||||
});
|
||||
|
||||
console.log(parts.join(''));
|
||||
*/
|
|
@ -0,0 +1,12 @@
|
|||
import StartHelper from 'src/appStart/StartHelper';
|
||||
import LangFormat from './default';
|
||||
|
||||
export const lang: LangFormat = {
|
||||
details: {
|
||||
langCode: 'en',
|
||||
langName: 'English',
|
||||
},
|
||||
curVersion: 'Your current version is v${version}.',
|
||||
appName: 'Click And Join',
|
||||
startHelper1: 'Your data will be loaded :)',
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
import appNonSaveVarReducer from '@caj/configs/appNonSaveVarReducer';
|
||||
import {configureStore} from '@reduxjs/toolkit';
|
||||
|
||||
import appVariablesReducer from '../configs/appVarReducer';
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
appVariables: appVariablesReducer,
|
||||
nonSaveVariables: appNonSaveVarReducer,
|
||||
},
|
||||
});
|
||||
|
||||
// Infer the `RootState` and `AppDispatch` types from the store itself
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
|
||||
export type AppDispatch = typeof store.dispatch;
|
|
@ -7,8 +7,8 @@
|
|||
"target": "ESNext",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"moduleResolution": "node",
|
||||
"jsx": "react-native"
|
||||
|
||||
"jsx": "react-native",
|
||||
"strict": true,
|
||||
},
|
||||
"include": ["**/*.ts", "**/*.tsx", "./src/caj/img/*.png"],
|
||||
"exclude": [
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -6,6 +6,74 @@
|
|||
<meta name="theme-color" content="#222" />
|
||||
<meta name="description" content="Click and Join Web" />
|
||||
<title>Click and Join Web</title>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--doc--height: 100%;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Outfit-Thin';
|
||||
src: url('/fonts/Outfit.ttf');
|
||||
font-weight: 100;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Outfit-ExtraLight';
|
||||
src: url('/fonts/Outfit.ttf');
|
||||
font-weight: 200;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Outfit-Light';
|
||||
src: url('/fonts/Outfit.ttf');
|
||||
font-weight: 300;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Outfit-Regular';
|
||||
src: url('/fonts/Outfit.ttf');
|
||||
font-weight: 400;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Outfit-Medium';
|
||||
src: url('/fonts/Outfit.ttf');
|
||||
font-weight: 500;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Outfit-SemiBold';
|
||||
src: url('/fonts/Outfit.ttf');
|
||||
font-weight: 600;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Outfit-Bold';
|
||||
src: url('/fonts/Outfit.ttf');
|
||||
font-weight: 700;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Outfit-ExtraBold';
|
||||
src: url('/fonts/Outfit.ttf');
|
||||
font-weight: 800;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Outfit-Black';
|
||||
src: url('/fonts/Outfit.ttf');
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
background-color: #282f34;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#root {
|
||||
height: 100vh; /* fallback for Js load */
|
||||
height: var(--doc-height);
|
||||
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
@ -13,6 +81,13 @@
|
|||
|
||||
<script>
|
||||
var exports = {};
|
||||
|
||||
const documentHeight = () => {
|
||||
const doc = document.documentElement;
|
||||
doc.style.setProperty('--doc-height', window.innerHeight + 'px');
|
||||
};
|
||||
window.addEventListener('resize', documentHeight);
|
||||
documentHeight();
|
||||
</script>
|
||||
<script type="module" src="/bundle.web.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -16,10 +16,8 @@ const babelLoaderConfiguration = {
|
|||
include: [
|
||||
path.resolve(appDirectory, 'index.web.tsx'),
|
||||
path.resolve(appDirectory, 'src'),
|
||||
path.resolve(appDirectory, 'node_modules'),
|
||||
path.resolve(appDirectory, 'node_modules/react-native-uncompiled'),
|
||||
path.resolve(appDirectory, 'node_modules/react-native-sdk'),
|
||||
],
|
||||
exclude: [path.resolve(appDirectory, 'node_modules')],
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
|
@ -29,15 +27,15 @@ const babelLoaderConfiguration = {
|
|||
// presets: ['react-native'],
|
||||
presets: [require.resolve('babel-preset-react-native')],
|
||||
// Re-write paths to import only the modules needed by the app
|
||||
plugins: ['react-native-web',],
|
||||
plugins: ['react-native-web'],
|
||||
presets: ['react-native'],
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
// plugins: [
|
||||
// // needed to support async/await
|
||||
// '@babel/plugin-transform-runtime'
|
||||
// ]
|
||||
plugins: [
|
||||
// needed to support async/await
|
||||
'@babel/plugin-transform-runtime',
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// This is needed for webpack to import static images in JavaScript files.
|
||||
|
@ -46,44 +44,42 @@ const imageLoaderConfiguration = {
|
|||
use: {
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
name: '[name].[ext]'
|
||||
}
|
||||
}
|
||||
name: '[name].[ext]',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
target: 'web',
|
||||
entry: [
|
||||
// load any web API polyfills
|
||||
// path.resolve(appDirectory, 'polyfills-web.js'),
|
||||
//'babel-polyfill',
|
||||
// your web-specific entry file
|
||||
path.resolve(appDirectory, 'index.web.tsx')
|
||||
path.resolve(appDirectory, 'index.web.tsx'),
|
||||
],
|
||||
|
||||
// configures where the build ends up
|
||||
output: {
|
||||
filename: 'bundle.web.js',
|
||||
path: path.resolve(appDirectory, 'dist')
|
||||
path: path.resolve(appDirectory, 'dist'),
|
||||
},
|
||||
|
||||
// ...the rest of your config
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
babelLoaderConfiguration,
|
||||
imageLoaderConfiguration
|
||||
]
|
||||
rules: [babelLoaderConfiguration, imageLoaderConfiguration],
|
||||
},
|
||||
|
||||
resolve: {
|
||||
// This will only alias the exact import "react-native"
|
||||
alias: {
|
||||
'react-native$': 'react-native-web',
|
||||
'@caj': path.resolve(appDirectory, 'src/caj')
|
||||
'@caj': path.resolve(appDirectory, 'src/caj'),
|
||||
},
|
||||
// If you're working on a multi-platform React Native app, web-specific
|
||||
// module implementations should be written in files using the extension
|
||||
// `.web.js`.
|
||||
extensions: ['.web.js', '.js','.web.ts', '.ts','.web.tsx', '.tsx']
|
||||
}
|
||||
}
|
||||
extensions: ['.web.js', '.js', '.web.ts', '.ts', '.web.tsx', '.tsx'],
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue