databag/app/mobile/src/session/Session.jsx

379 lines
14 KiB
React
Raw Normal View History

2022-09-16 20:06:52 +00:00
import { View, TouchableOpacity, Text } from 'react-native';
2022-09-29 18:31:55 +00:00
import { useState, useEffect, useContext } from 'react';
2022-09-16 22:00:29 +00:00
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
2022-09-18 06:24:37 +00:00
import { createDrawerNavigator } from '@react-navigation/drawer';
2022-09-17 06:54:57 +00:00
import { createStackNavigator } from '@react-navigation/stack';
2022-09-16 20:06:52 +00:00
import { NavigationContainer } from '@react-navigation/native';
2022-09-16 22:00:29 +00:00
import Ionicons from '@expo/vector-icons/AntDesign';
2022-09-16 20:06:52 +00:00
import { useSession } from './useSession.hook';
2022-09-16 22:00:29 +00:00
import { styles } from './Session.styled';
import Colors from 'constants/Colors';
2022-09-27 19:21:40 +00:00
import { ProfileTitle, Profile } from './profile/Profile';
import { CardsTitle, CardsBody, Cards } from './cards/Cards';
import { useCards } from './cards/useCards.hook';
import { RegistryTitle, RegistryBody, Registry } from './registry/Registry';
import { useRegistry } from './registry/useRegistry.hook';
import { Contact, ContactTitle } from './contact/Contact';
2022-09-28 19:41:00 +00:00
import { Details, DetailsHeader, DetailsBody } from './details/Details';
2022-09-28 17:51:01 +00:00
import { Conversation, ConversationHeader, ConversationBody } from './conversation/Conversation';
2022-09-19 05:42:27 +00:00
import { Welcome } from './welcome/Welcome';
2022-09-28 05:30:47 +00:00
import { ChannelsTitle, ChannelsBody, Channels } from './channels/Channels';
import { useChannels } from './channels/useChannels.hook';
2022-09-28 17:51:01 +00:00
import { CommonActions } from '@react-navigation/native';
2022-09-29 18:31:55 +00:00
import { ConversationContext } from 'context/ConversationContext';
const ConversationStack = createStackNavigator();
const ProfileStack = createStackNavigator();
const ContactStack = createStackNavigator();
const ProfileDrawer = createDrawerNavigator();
const ContactDrawer = createDrawerNavigator();
const DetailDrawer = createDrawerNavigator();
const CardDrawer = createDrawerNavigator();
2022-09-23 22:15:04 +00:00
const RegistryDrawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();
2022-09-07 07:32:06 +00:00
export function Session() {
2022-09-16 20:06:52 +00:00
const { state, actions } = useSession();
2022-09-19 00:04:17 +00:00
// tabbed containers
2022-09-17 06:54:57 +00:00
const ConversationStackScreen = () => {
2022-09-27 06:12:42 +00:00
const [selected, setSelected] = useState(null);
2022-10-04 18:52:22 +00:00
const setConversation = (navigation, cardId, channelId, revision) => {
setSelected({ cardId, channelId, revision });
2022-09-27 06:12:42 +00:00
navigation.navigate('conversation');
}
const clearConversation = (navigation) => {
2022-09-28 17:51:01 +00:00
navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{ name: 'channels' },
],
})
);
2022-09-27 06:12:42 +00:00
}
const setDetail = (navigation) => {
navigation.navigate('details');
}
const clearDetail = (navigation) => {
navigation.goBack();
}
2022-09-28 05:30:47 +00:00
const channels = useChannels();
2022-09-29 18:31:55 +00:00
const conversation = useContext(ConversationContext);
useEffect(() => {
conversation.actions.setChannel(selected);
}, [selected]);
2022-09-28 05:30:47 +00:00
2022-09-17 06:54:57 +00:00
return (
2022-10-04 21:00:49 +00:00
<ConversationStack.Navigator
2022-10-09 04:55:56 +00:00
initialRouteName="channels"
2022-10-04 21:00:49 +00:00
screenOptions={({ route }) => ({ headerShown: true, headerTintColor: Colors.primary })}
screenListeners={{ state: (e) => { if (e?.data?.state?.index === 0 && selected) { setSelected(null); }}, }}>
2022-09-28 05:30:47 +00:00
<ConversationStack.Screen name="channels" options={{
headerStyle: { backgroundColor: Colors.titleBackground },
headerBackTitleVisible: false,
2022-09-28 05:57:30 +00:00
headerTitle: (props) => <ChannelsTitle state={channels.state} actions={channels.actions} />
2022-09-28 05:30:47 +00:00
}}>
2022-10-04 18:52:22 +00:00
{(props) => <ChannelsBody state={channels.state} actions={channels.actions} openConversation={(cardId, channelId, revision) => setConversation(props.navigation, cardId, channelId, revision)} />}
2022-09-27 06:12:42 +00:00
</ConversationStack.Screen>
2022-09-28 17:51:01 +00:00
<ConversationStack.Screen name="conversation" options={{
headerStyle: { backgroundColor: Colors.titleBackground },
headerBackTitleVisible: false,
headerTitle: (props) => <ConversationHeader channel={selected} closeConversation={clearConversation} openDetails={setDetail} />
}}>
{(props) => <ConversationBody channel={selected} />}
2022-09-27 06:12:42 +00:00
</ConversationStack.Screen>
2022-09-28 19:41:00 +00:00
<ConversationStack.Screen name="details" options={{
headerStyle: { backgroundColor: Colors.titleBackground },
headerBackTitleVisible: false,
headerTitle: (props) => <DetailsHeader channel={selected} />
}}>
{(props) => <DetailsBody channel={selected} clearConversation={() => clearConversation(props.navigation)} />}
2022-09-27 06:12:42 +00:00
</ConversationStack.Screen>
2022-09-17 06:54:57 +00:00
</ConversationStack.Navigator>
);
}
const ProfileStackScreen = () => {
return (
2022-09-28 05:57:30 +00:00
<ProfileStack.Navigator screenOptions={({ route }) => ({ headerShown: true, headerTintColor: Colors.primary })}>
2022-09-27 19:21:40 +00:00
<ProfileStack.Screen name="profile" component={Profile} options={{ headerStyle: { backgroundColor: Colors.titleBackground }, headerTitle: (props) => <ProfileTitle {...props} /> }} />
2022-09-17 06:54:57 +00:00
</ProfileStack.Navigator>
);
}
const ContactStackScreen = () => {
2022-09-25 00:44:08 +00:00
const [selected, setSelected] = useState(null);
const setCardStack = (navigation, contact) => {
setSelected(contact);
navigation.navigate('contact')
}
const clearCardStack = (navigation) => {
navigation.goBack();
}
2022-09-24 06:31:46 +00:00
const setRegistryStack = (navigation) => {
navigation.navigate('registry');
}
const clearRegistryStack = (navigation) => {
navigation.goBack();
}
2022-09-27 19:21:40 +00:00
const registry = useRegistry();
const cards = useCards();
2022-09-17 06:54:57 +00:00
return (
2022-10-09 04:55:56 +00:00
<ContactStack.Navigator screenOptions={({ route }) => ({ headerShow: true, headerTintColor: Colors.primary })}
initialRouteName="cards">
2022-09-27 19:21:40 +00:00
<ContactStack.Screen name="cards" options={{
headerStyle: { backgroundColor: Colors.titleBackground },
headerBackTitleVisible: false,
2022-09-28 05:57:30 +00:00
headerTitle: (props) => <CardsTitle state={cards.state} actions={cards.actions} openRegistry={setRegistryStack} />
2022-09-27 19:21:40 +00:00
}}>
{(props) => <CardsBody state={cards.state} actions={cards.actions} openContact={(contact) => setCardStack(props.navigation, contact)} />}
</ContactStack.Screen>
2022-09-27 19:21:40 +00:00
<ContactStack.Screen name="contact" options={{
headerStyle: { backgroundColor: Colors.titleBackground },
headerBackTitleVisible: false,
headerTitle: (props) => <ContactTitle contact={selected} {...props} />
}}>
2022-09-25 00:44:08 +00:00
{(props) => <Contact contact={selected} closeContact={() => clearCardStack(props.navigation)} />}
</ContactStack.Screen>
2022-09-27 19:21:40 +00:00
<ContactStack.Screen name="registry" options={{
headerStyle: { backgroundColor: Colors.titleBackground },
headerBackTitleVisible: false,
headerTitle: (props) => <RegistryTitle state={registry.state} actions={registry.actions} contact={selected} {...props} />
}}>
{(props) => <RegistryBody state={registry.state} actions={registry.actions} openContact={(contact) => setCardStack(props.navigation, contact)} />}
2022-09-24 06:31:46 +00:00
</ContactStack.Screen>
2022-09-17 06:54:57 +00:00
</ContactStack.Navigator>
);
}
2022-09-19 00:04:17 +00:00
2022-09-28 17:51:01 +00:00
const HomeScreen = ({ cardNav, registryNav, detailNav, contactNav, profileNav, setDetails, resetConversation, clearReset }) => {
2022-09-27 06:12:42 +00:00
const [channel, setChannel] = useState(null);
2022-10-04 18:52:22 +00:00
const setConversation = (cardId, channelId, revision) => {
setChannel({ cardId, channelId, revision });
2022-09-27 06:12:42 +00:00
};
2022-09-28 17:51:01 +00:00
const clearConversation = () => {
2022-09-27 06:12:42 +00:00
setChannel(null);
};
2022-09-28 17:51:01 +00:00
const setProfile = () => {
profileNav.openDrawer();
};
const setChannelDetails = (channel) => {
setDetails(channel);
detailNav.openDrawer();
};
const openProfile = () => {
profileNav.openDrawer();
}
const openCards = () => {
cardNav.openDrawer();
}
2022-09-30 21:00:51 +00:00
const conversation = useContext(ConversationContext);
2022-09-28 17:51:01 +00:00
useEffect(() => {
if (resetConversation) {
detailNav.closeDrawer();
setChannel(null);
setDetails(null);
clearReset();
}
}, [resetConversation]);
2022-09-27 06:12:42 +00:00
2022-09-30 21:00:51 +00:00
useEffect(() => {
conversation.actions.setChannel(channel);
}, [channel]);
2022-09-18 06:24:37 +00:00
return (
2022-09-19 05:42:27 +00:00
<View style={styles.home}>
2022-09-23 07:56:31 +00:00
<SafeAreaView edges={['top', 'bottom']} style={styles.sidebar}>
<SafeAreaView edges={['left']} style={styles.options}>
<TouchableOpacity style={styles.option} onPress={openProfile}>
2022-09-19 05:42:27 +00:00
<Ionicons style={styles.icon} name={'user'} size={20} />
<Text>Profile</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.option} onPress={openCards}>
2022-09-19 05:42:27 +00:00
<Ionicons style={styles.icon} name={'contacts'} size={20} />
<Text>Contacts</Text>
</TouchableOpacity>
2022-09-23 07:56:31 +00:00
</SafeAreaView>
2022-09-21 18:12:46 +00:00
<View style={styles.channels}>
2022-09-28 17:51:01 +00:00
<Channels openConversation={setConversation} />
2022-09-21 18:12:46 +00:00
</View>
</SafeAreaView>
2022-09-19 05:42:27 +00:00
<View style={styles.conversation}>
2022-09-27 06:12:42 +00:00
{ channel && (
2022-10-04 14:09:42 +00:00
<Conversation closeConversation={clearConversation} openDetails={setChannelDetails} />
2022-09-19 05:42:27 +00:00
)}
2022-09-27 06:12:42 +00:00
{ !channel && (
2022-09-19 05:42:27 +00:00
<Welcome />
)}
</View>
</View>
2022-09-18 06:24:37 +00:00
)
}
2022-09-28 17:51:01 +00:00
const CardDrawerScreen = ({ registryNav, detailNav, contactNav, profileNav, setContact, setDetails, clearReset, resetConversation }) => {
2022-09-23 22:15:04 +00:00
const openRegistry = () => {
registryNav.openDrawer();
2022-09-28 17:51:01 +00:00
};
setCardContact = (contact) => {
setContact(contact);
contactNav.openDrawer();
};
const params = {
profileNav,
registryNav,
detailNav,
contactNav,
setDetails,
setContact,
clearReset,
resetConversation,
};
2022-09-23 22:15:04 +00:00
2022-09-19 00:04:17 +00:00
return (
<CardDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.baseWidth } }}
2022-09-28 17:51:01 +00:00
drawerContent={(props) => <Cards openContact={setCardContact} openRegistry={openRegistry} />}>
<CardDrawer.Screen name="home">
2022-09-28 17:51:01 +00:00
{(props) => <HomeScreen cardNav={props.navigation} {...params} />}
2022-09-19 00:04:17 +00:00
</CardDrawer.Screen>
</CardDrawer.Navigator>
);
};
2022-09-28 17:51:01 +00:00
const RegistryDrawerScreen = ({ detailNav, contactNav, profileNav, setContact, setDetails, clearReset, resetConversation }) => {
const setRegistryContact = (contact) => {
setContact(contact);
contactNav.openDrawer();
};
const params = {
profileNav,
detailNav,
contactNav,
setDetails,
setContact,
clearReset,
resetConversation,
};
2022-09-23 22:15:04 +00:00
return (
<RegistryDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.baseWidth } }}
2022-09-28 17:51:01 +00:00
drawerContent={(props) => <Registry openContact={setRegistryContact} />}>
2022-09-23 22:15:04 +00:00
<RegistryDrawer.Screen name="card">
2022-09-28 17:51:01 +00:00
{(props) => <CardDrawerScreen registryNav={props.navigation} {...params} />}
2022-09-23 22:15:04 +00:00
</RegistryDrawer.Screen>
</RegistryDrawer.Navigator>
);
};
2022-09-28 17:51:01 +00:00
const ContactDrawerScreen = ({ detailNav, profileNav, setDetails, resetConversation, clearReset }) => {
2022-09-25 00:44:08 +00:00
const [selected, setSelected] = useState(null);
2022-09-28 17:51:01 +00:00
const setContact = (contact) => {
2022-09-25 00:44:08 +00:00
setSelected(contact);
}
2022-09-28 17:51:01 +00:00
const params = {
profileNav,
detailNav,
setDetails,
setContact,
clearReset,
resetConversation,
};
return (
<ContactDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.subWidth } }}
2022-09-28 17:51:01 +00:00
drawerContent={(props) => <Contact contact={selected} />}>
2022-09-23 22:15:04 +00:00
<ContactDrawer.Screen name="registry">
2022-09-28 17:51:01 +00:00
{(props) => <RegistryDrawerScreen {...params} contactNav={props.navigation} setContact={setContact} />}
</ContactDrawer.Screen>
</ContactDrawer.Navigator>
);
}
2022-09-27 06:12:42 +00:00
const DetailDrawerScreen = ({ profileNav }) => {
const [selected, setSelected] = useState(null);
2022-09-28 17:51:01 +00:00
const [resetConversation, setResetConversation] = useState(false);
const setDetails = (channel) => {
2022-09-27 06:12:42 +00:00
setSelected(channel);
2022-09-28 17:51:01 +00:00
};
const clearConversation = () => {
setResetConversation(true);
}
const clearReset = () => {
setResetConversation(false);
}
const params = {
profileNav,
setDetails,
clearReset,
resetConversation,
2022-09-27 06:12:42 +00:00
};
return (
2022-09-27 06:12:42 +00:00
<DetailDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.subWidth } }}
2022-09-28 17:51:01 +00:00
drawerContent={(props) => <Details channel={selected} clearConversation={clearConversation} />}
>
2022-09-27 06:12:42 +00:00
<DetailDrawer.Screen name="contact">
2022-09-28 17:51:01 +00:00
{(props) => <ContactDrawerScreen {...params} detailNav={props.navigation} />}
2022-09-27 06:12:42 +00:00
</DetailDrawer.Screen>
</DetailDrawer.Navigator>
);
}
return (
2022-09-21 18:12:46 +00:00
<View style={styles.container}>
{ state.tabbed === false && (
2022-09-27 06:12:42 +00:00
<ProfileDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.subWidth } }}
2022-09-28 17:51:01 +00:00
drawerContent={(props) => <Profile />}>
2022-09-27 06:12:42 +00:00
<ProfileDrawer.Screen name="detail">
{(props) => <DetailDrawerScreen profileNav={props.navigation}/>}
</ProfileDrawer.Screen>
</ProfileDrawer.Navigator>
)}
{ state.tabbed === true && (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarStyle: styles.tabBar,
headerShown: false,
tabBarIcon: ({ focused, color, size }) => {
if (route.name === 'Profile') {
return <Ionicons name={'user'} size={size} color={color} />;
}
if (route.name === 'Conversation') {
return <Ionicons name={'message1'} size={size} color={color} />;
2022-09-19 00:04:17 +00:00
}
if (route.name === 'Contacts') {
return <Ionicons name={'contacts'} size={size} color={color} />;
}
},
tabBarShowLabel: false,
tabBarActiveTintColor: Colors.white,
tabBarInactiveTintColor: Colors.disabled,
})}>
2022-09-28 05:30:47 +00:00
<Tab.Screen name="Conversation" component={ConversationStackScreen} />
2022-09-27 19:21:40 +00:00
<Tab.Screen name="Profile" component={ProfileStackScreen} />
<Tab.Screen name="Contacts" component={ContactStackScreen} />
</Tab.Navigator>
)}
2022-09-21 18:12:46 +00:00
</View>
);
2022-09-07 07:32:06 +00:00
}
2022-09-16 20:06:52 +00:00