avoid re-render of session to avoid glitchies

This commit is contained in:
Roland Osborne 2022-09-19 12:07:33 -07:00
parent ade5ebb6db
commit 6c4f3b8782
10 changed files with 187 additions and 114 deletions

View File

@ -12,6 +12,8 @@ import { AccountContextProvider } from 'context/AccountContext';
import { ProfileContextProvider } from 'context/ProfileContext'; import { ProfileContextProvider } from 'context/ProfileContext';
import { CardContextProvider } from 'context/CardContext'; import { CardContextProvider } from 'context/CardContext';
import { ChannelContextProvider } from 'context/ChannelContext'; import { ChannelContextProvider } from 'context/ChannelContext';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { NavigationContainer } from '@react-navigation/native';
export default function App() { export default function App() {
@ -22,6 +24,7 @@ export default function App() {
<AccountContextProvider> <AccountContextProvider>
<ProfileContextProvider> <ProfileContextProvider>
<AppContextProvider> <AppContextProvider>
<SafeAreaProvider>
<NativeRouter> <NativeRouter>
<Routes> <Routes>
<Route path="/" element={ <Root /> } /> <Route path="/" element={ <Root /> } />
@ -29,9 +32,10 @@ export default function App() {
<Route path="/login" element={ <Access mode="login" /> } /> <Route path="/login" element={ <Access mode="login" /> } />
<Route path="/reset" element={ <Access mode="reset" /> } /> <Route path="/reset" element={ <Access mode="reset" /> } />
<Route path="/create" element={ <Access mode="create" /> } /> <Route path="/create" element={ <Access mode="create" /> } />
<Route path="/session" element={ <Session/> } /> <Route path="/session" element={ <NavigationContainer><Session/></NavigationContainer> } />
</Routes> </Routes>
</NativeRouter> </NativeRouter>
</SafeAreaProvider>
</AppContextProvider> </AppContextProvider>
</ProfileContextProvider> </ProfileContextProvider>
</AccountContextProvider> </AccountContextProvider>

View File

@ -17,18 +17,24 @@ import { Details } from './details/Details';
import { Conversation } from './conversation/Conversation'; import { Conversation } from './conversation/Conversation';
import { Welcome } from './welcome/Welcome'; import { Welcome } from './welcome/Welcome';
const ConversationStack = createStackNavigator();
const ProfileStack = createStackNavigator();
const ContactStack = createStackNavigator();
const ProfileDrawer = createDrawerNavigator();
const ContactDrawer = createDrawerNavigator();
const DetailDrawer = createDrawerNavigator();
const CardDrawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();
export function Session() { export function Session() {
const { state, actions } = useSession(); const { state, actions } = useSession();
const [ contactDrawer, setContactDrawer ] = useState(null);
const Tab = createBottomTabNavigator();
const openCards = (nav) => { const openCards = (nav) => {
nav.openDrawer(); nav.openDrawer();
} }
const closeCards = (nav) => {} const closeCards = (nav) => {}
const openProfile = (nav) => { const openProfile = (nav) => {
setContactDrawer('profile');
nav.openDrawer(); nav.openDrawer();
} }
const closeProfile = (nav) => {} const closeProfile = (nav) => {}
@ -40,7 +46,6 @@ export function Session() {
const closeDetails = (nav) => {} const closeDetails = (nav) => {}
// tabbed containers // tabbed containers
const ConversationStack = createStackNavigator();
const ConversationStackScreen = () => { const ConversationStackScreen = () => {
return ( return (
<ConversationStack.Navigator screenOptions={({ route }) => ({ headerShown: false })}> <ConversationStack.Navigator screenOptions={({ route }) => ({ headerShown: false })}>
@ -63,7 +68,6 @@ export function Session() {
const DetailsTabScreen = ({ navigation }) => { const DetailsTabScreen = ({ navigation }) => {
return <Details closeDetails={() => closeDetails(navigation)} /> return <Details closeDetails={() => closeDetails(navigation)} />
} }
const ProfileStack = createStackNavigator();
const ProfileStackScreen = () => { const ProfileStackScreen = () => {
return ( return (
<ProfileStack.Navigator screenOptions={({ route }) => ({ headerShown: false })}> <ProfileStack.Navigator screenOptions={({ route }) => ({ headerShown: false })}>
@ -71,58 +75,73 @@ export function Session() {
</ProfileStack.Navigator> </ProfileStack.Navigator>
); );
} }
const ContactStack = createStackNavigator();
const ContactStackScreen = () => { const ContactStackScreen = () => {
const [cardId, setCardId] = useState(null);
const setCardStack = (navigation, id) => {
setCardId(id);
navigation.navigate('card')
}
const clearCardStack = (navigation) => {
navigation.goBack();
}
return ( return (
<ContactStack.Navigator screenOptions={({ route }) => ({ headerShown: false })}> <ContactStack.Navigator screenOptions={({ route }) => ({ headerShown: false })}>
<ContactStack.Screen name="cards" component={ContactsTabScreen} /> <ContactStack.Screen name="cards">
<ContactStack.Screen name="card" component={ContactTabScreen} /> {(props) => <Cards openContact={(cardId) => setCardStack(props.navigation, cardId)} />}
</ContactStack.Screen>
<ContactStack.Screen name="card">
{(props) => <Contact cardId={cardId} closeContact={() => clearCardStack(props.navigation)} />}
</ContactStack.Screen>
</ContactStack.Navigator> </ContactStack.Navigator>
); );
} }
const ContactsTabScreen = ({ navigation }) => {
return <Cards openContact={(cardId) => openContact(navigation, cardId)} />
}
const ContactTabScreen = ({ navigation }) => {
return <Contact closeContact={() => closeContact(navigation)} />
}
// drawered containers // drawered containers
const CardDrawer = createDrawerNavigator(); const CardDrawerContent = ({ navigation, setContact }) => {
const CardDrawerContent = ({ contactNav, navigation }) => {
return ( return (
<SafeAreaView> <SafeAreaView>
<Cards openContact={(cardId) => openContact(contactNav, cardId)} /> <Cards navigation={navigation} openContact={setContact} />
</SafeAreaView> </SafeAreaView>
) )
} }
const ContactDrawer = createDrawerNavigator(); const ProfileDrawerContent = ({ navigation }) => {
const ContactDrawerContent = ({ navigation }) => {
return ( return (
<SafeAreaView> <SafeAreaView>
{ contactDrawer === 'profile' && (
<Profile closeProfile={() => closeProfile(navigation)} /> <Profile closeProfile={() => closeProfile(navigation)} />
)}
{ contactDrawer === 'contacts' && (
<Contact closeContact={() => closeContact(navigation)} />
)}
{ contactDrawer === 'details' && (
<Details closeDetails={() => closeDetails(navigation)} />
)}
</SafeAreaView> </SafeAreaView>
) )
} }
const HomeScreen = ({ contactNav, navigation }) => { const DetailDrawerContent = ({ navigation }) => {
return (
<SafeAreaView>
<Details closeDetails={() => closeDetails(navigation)} />
</SafeAreaView>
)
}
const ContactDrawerContent = ({ navigation }) => {
const clearContact = () => {
navigation.closeDrawer();
}
return (
<SafeAreaView>
<Contact closeContact={clearContact} />
</SafeAreaView>
)
}
const HomeScreen = ({ cardNav, detailNav, contactNav, profileNav }) => {
return ( return (
<View style={styles.home}> <View style={styles.home}>
<View style={styles.sidebar}> <View style={styles.sidebar}>
<SafeAreaView edges={['top', 'left']} style={styles.options}> <SafeAreaView edges={['top', 'left']} style={styles.options}>
<TouchableOpacity style={styles.option} onPress={() => openProfile(contactNav)}> <TouchableOpacity style={styles.option} onPress={() => openProfile(profileNav)}>
<Ionicons style={styles.icon} name={'user'} size={20} /> <Ionicons style={styles.icon} name={'user'} size={20} />
<Text>Profile</Text> <Text>Profile</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity style={styles.option} onPress={() => openCards(navigation)}> <TouchableOpacity style={styles.option} onPress={() => openCards(cardNav)}>
<Ionicons style={styles.icon} name={'contacts'} size={20} /> <Ionicons style={styles.icon} name={'contacts'} size={20} />
<Text>Contacts</Text> <Text>Contacts</Text>
</TouchableOpacity> </TouchableOpacity>
@ -133,7 +152,7 @@ export function Session() {
</View> </View>
<View style={styles.conversation}> <View style={styles.conversation}>
{ state.conversationId && ( { state.conversationId && (
<Conversation closeConversation={() => closeConversation(null)} openDetails={() => openDetails(contactNav)} /> <Conversation closeConversation={() => closeConversation(null)} openDetails={() => openDetails(detailNav)} />
)} )}
{ !state.conversationId && ( { !state.conversationId && (
<Welcome /> <Welcome />
@ -143,42 +162,60 @@ export function Session() {
) )
} }
const CardDrawerScreen = ({ navigation }) => { const CardDrawerScreen = ({ detailNav, contactNav, profileNav, setContact }) => {
const setCardDrawer = (cardId) => {
setContact(cardId);
contactNav.openDrawer();
}
return ( return (
<CardDrawer.Navigator screenOptions={{ <CardDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.baseWidth } }}
drawerPosition: 'right', drawerContent={(props) => <CardDrawerContent setContact={setCardDrawer} {...props} />}>
headerShown: false, <CardDrawer.Screen name="home">
swipeEnabled: false, {(props) => <HomeScreen cardNav={props.navigation} detailNav={detailNav} contactNav={contactNav} profileNav={profileNav} />}
drawerType: 'front',
drawerStyle: {
width: state.cardWidth,
},
}}
drawerContent={(props) => <CardDrawerContent contactNav={navigation} {...props} />}>
<CardDrawer.Screen name="Root">
{(props) => <HomeScreen contactNav={navigation} {...props} />}
</CardDrawer.Screen> </CardDrawer.Screen>
</CardDrawer.Navigator> </CardDrawer.Navigator>
); );
}; };
return ( const ContactDrawerScreen = ({ detailNav, profileNav }) => {
<SafeAreaProvider>
<NavigationContainer> const [cardId, setCardId] = useState(null);
{ state.tabbed === false && ( const setContact = (id) => {
<ContactDrawer.Navigator setCardId(id);
screenOptions={{
headerShown: false,
swipeEnabled: false,
drawerType: 'front',
drawerPosition: 'right',
drawerStyle: {
width: state.profileWidth,
} }
}}
drawerContent={(props) => <ContactDrawerContent {...props} />}> return (
<ContactDrawer.Screen name="Home" component={CardDrawerScreen} /> <ContactDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.subWidth } }}
drawerContent={(props) => <ContactDrawerContent cardId={cardId} {...props} />}>
<ContactDrawer.Screen name="profile">
{(props) => <CardDrawerScreen detailNav={detailNav} profileNav={profileNav} contactNav={props.navigation} setContact={setContact} />}
</ContactDrawer.Screen>
</ContactDrawer.Navigator> </ContactDrawer.Navigator>
);
}
const ProfileDrawerScreen = ({ detailNav }) => {
return (
<ProfileDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.subWidth } }}
drawerContent={(props) => <ProfileDrawerContent {...props} />}>
<ProfileDrawer.Screen name="card">
{(props) => <ContactDrawerScreen detailNav={detailNav} profileNav={props.navigation}/>}
</ProfileDrawer.Screen>
</ProfileDrawer.Navigator>
);
}
return (
<>
{ state.tabbed === false && (
<DetailDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.subWidth } }}
drawerContent={(props) => <DetailDrawerContent {...props} />}>
<DetailDrawer.Screen name="contact">
{(props) => <ProfileDrawerScreen detailNav={props.navigation} />}
</DetailDrawer.Screen>
</DetailDrawer.Navigator>
)} )}
{ state.tabbed === true && ( { state.tabbed === true && (
<Tab.Navigator <Tab.Navigator
@ -202,11 +239,12 @@ export function Session() {
})}> })}>
<Tab.Screen name="Conversation" component={ConversationStackScreen} /> <Tab.Screen name="Conversation" component={ConversationStackScreen} />
<Tab.Screen name="Profile" component={ProfileStackScreen} /> <Tab.Screen name="Profile" component={ProfileStackScreen} />
<Tab.Screen name="Contacts" component={ContactStackScreen} /> <Tab.Screen name="Contacts">
{(props) => (<SafeAreaView style={styles.tabframe}><ContactStackScreen /></SafeAreaView>)}
</Tab.Screen>
</Tab.Navigator> </Tab.Navigator>
)} )}
</NavigationContainer> </>
</SafeAreaProvider>
); );
} }

View File

@ -41,4 +41,8 @@ export const styles = StyleSheet.create({
channels: { channels: {
flexGrow: 1, flexGrow: 1,
}, },
tabframe: {
width: '100%',
height: '100%',
}
}); });

View File

@ -1,12 +1,18 @@
import { useContext } from 'react'; import { useState, useContext } from 'react';
import { View, TouchableOpacity, Text } from 'react-native'; import { View, TouchableOpacity, Text } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaView } from 'react-native-safe-area-context';
import { AppContext } from 'context/AppContext'; import { AppContext } from 'context/AppContext';
export function Cards() { export function Cards({ navigation, openContact }) {
const app = useContext(AppContext); const app = useContext(AppContext);
const [cardId, setCardId] = useState(0);
return (<SafeAreaView edges={['top']}><TouchableOpacity style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }} onPress={app.actions.logout}><Text>~ CARDS LOGOUT</Text></TouchableOpacity></SafeAreaView>) const onPressCard = () => {
openContact(cardId);
setCardId(cardId + 1);
}
return <TouchableOpacity onPress={onPressCard}><Text>CARD</Text></TouchableOpacity>
} }

View File

@ -11,7 +11,7 @@ export function Channels() {
return ( return (
<View style={styles.container}> <View style={styles.container}>
<View style={styles.inputwrapper}> <View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="search1" size={18} color={'#ffffff'} /> <Ionicons style={styles.icon} name="search1" size={16} color={'#ffffff'} />
<TextInput style={styles.inputfield} value={state.topic} onChangeText={actions.setTopic} <TextInput style={styles.inputfield} value={state.topic} onChangeText={actions.setTopic}
autoCapitalize="none" placeholderTextColor={'#ffffff'} placeholder="Topic" /> autoCapitalize="none" placeholderTextColor={'#ffffff'} placeholder="Topic" />
<View style={styles.space} /> <View style={styles.space} />

View File

@ -12,7 +12,7 @@ export const styles = StyleSheet.create({
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
borderRadius: 4, borderRadius: 4,
backgroundColor: Colors.lightgrey, backgroundColor: Colors.background,
alignItems: 'center', alignItems: 'center',
marginRight: 8, marginRight: 8,
marginLeft: 8, marginLeft: 8,
@ -20,7 +20,7 @@ export const styles = StyleSheet.create({
inputfield: { inputfield: {
flex: 1, flex: 1,
textAlign: 'center', textAlign: 'center',
padding: 8, padding: 4,
color: Colors.white, color: Colors.white,
fontSize: 16, fontSize: 16,
}, },

View File

@ -1,3 +1,12 @@
export function Contact() { import { useState, useContext } from 'react';
return <></> import { View, TouchableOpacity, Text } from 'react-native';
export function Contact({ navigation, closeContact }) {
const onPressCard = () => {
closeContact();
}
return <TouchableOpacity onPress={onPressCard}><Text>CLOSE</Text></TouchableOpacity>
} }

View File

@ -2,11 +2,18 @@ import { useContext } from 'react';
import { View, TouchableOpacity, Text } from 'react-native'; import { View, TouchableOpacity, Text } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaView } from 'react-native-safe-area-context';
import { AppContext } from 'context/AppContext'; import { AppContext } from 'context/AppContext';
import { useNavigate } from 'react-router-dom';
export function Profile() { export function Profile() {
const app = useContext(AppContext); const app = useContext(AppContext);
const navigate = useNavigate();
return (<SafeAreaView edges={['top']}><TouchableOpacity style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }} onPress={app.actions.logout}><Text>~ PROFILE LOGOUT</Text></TouchableOpacity></SafeAreaView>) const logout = () => {
app.actions.logout();
navigate('/');
}
return (<SafeAreaView edges={['top']}><TouchableOpacity style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }} onPress={logout}><Text>~ PROFILE LOGOUT</Text></TouchableOpacity></SafeAreaView>)
} }

View File

@ -8,11 +8,10 @@ export function useSession() {
const [state, setState] = useState({ const [state, setState] = useState({
tabbled: null, tabbled: null,
profileWidth: '33%', subWidth: '33%',
cardWidth: '33%', baseWidth: '33%',
cardId: null, cardId: null,
converstaionId: null, converstaionId: null,
contactDrawer: 'profile',
}); });
const dimensions = useWindowDimensions(); const dimensions = useWindowDimensions();
const app = useContext(AppContext); const app = useContext(AppContext);
@ -26,10 +25,10 @@ export function useSession() {
if (dimensions.width > config.tabbedWidth) { if (dimensions.width > config.tabbedWidth) {
const width = Math.floor((dimensions.width * 33) / 100); const width = Math.floor((dimensions.width * 33) / 100);
if (width > 500) { if (width > 500) {
updateStatus({ tabbed: false, cardWidth: 550, profileWidth: 500 }); updateStatus({ tabbed: false, baseWidth: 550, subWidth: 500 });
} }
else { else {
updateState({ tabbed: false, cardWidth: width + 50, profileWidth: width }); updateState({ tabbed: false, baseWidth: width + 50, subWidth: width });
} }
} }
else { else {
@ -38,9 +37,9 @@ export function useSession() {
}, [dimensions]); }, [dimensions]);
const actions = { const actions = {
setContactDrawer: (contactDrawer) => { setCardId: (cardId) => {
updateState({ contactDrawer }); updateState({ cardId });
}, }
}; };
return { state, actions }; return { state, actions };

View File

@ -1,3 +1,4 @@
import { useEffect } from 'react';
import { Image, View, TouchableOpacity, Text } from 'react-native'; import { Image, View, TouchableOpacity, Text } from 'react-native';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { styles } from './Welcome.styled'; import { styles } from './Welcome.styled';
@ -5,6 +6,11 @@ import { styles } from './Welcome.styled';
import session from 'images/session.png'; import session from 'images/session.png';
export function Welcome() { export function Welcome() {
useEffect(() => {
console.log("WELCOME");
}, []);
return ( return (
<SafeAreaView style={styles.container}> <SafeAreaView style={styles.container}>
<Text style={styles.header}>Welcome to Databag</Text> <Text style={styles.header}>Welcome to Databag</Text>