making channel screen responsive

This commit is contained in:
Roland Osborne 2022-09-21 11:12:46 -07:00
parent 529dcf9422
commit ed10c5b32e
5 changed files with 104 additions and 25 deletions

View File

@ -57,9 +57,7 @@ export function Session() {
} }
const ChannelsTabScreen = ({ navigation }) => { const ChannelsTabScreen = ({ navigation }) => {
return ( return (
<SafeAreaView style={styles.channels} edges={['top']}>
<Channels openConversation={(cardId, channelId) => openConversation(navigation, cardId, channelId)} /> <Channels openConversation={(cardId, channelId) => openConversation(navigation, cardId, channelId)} />
</SafeAreaView>
) )
} }
const ConversationTabScreen = ({ navigation }) => { const ConversationTabScreen = ({ navigation }) => {
@ -135,8 +133,8 @@ export function Session() {
const HomeScreen = ({ cardNav, detailNav, contactNav, profileNav }) => { const HomeScreen = ({ cardNav, detailNav, contactNav, profileNav }) => {
return ( return (
<View style={styles.home}> <View style={styles.home}>
<View style={styles.sidebar}> <SafeAreaView edges={['top', 'bottom', 'left']} style={styles.sidebar}>
<SafeAreaView edges={['top', 'left']} style={styles.options}> <View style={styles.options}>
<TouchableOpacity style={styles.option} onPress={() => openProfile(profileNav)}> <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>
@ -145,11 +143,11 @@ export function Session() {
<Ionicons style={styles.icon} name={'contacts'} size={20} /> <Ionicons style={styles.icon} name={'contacts'} size={20} />
<Text>Contacts</Text> <Text>Contacts</Text>
</TouchableOpacity> </TouchableOpacity>
</SafeAreaView>
<SafeAreaView edges={['left', 'bottom']} style={styles.channels}>
<Channels openConversation={(cardId, channelId) => openConversation(null, cardId, channelId)} />
</SafeAreaView>
</View> </View>
<View style={styles.channels}>
<Channels openConversation={(cardId, channelId) => openConversation(null, cardId, channelId)} />
</View>
</SafeAreaView>
<View style={styles.conversation}> <View style={styles.conversation}>
{ state.conversationId && ( { state.conversationId && (
<Conversation closeConversation={() => closeConversation(null)} openDetails={() => openDetails(detailNav)} /> <Conversation closeConversation={() => closeConversation(null)} openDetails={() => openDetails(detailNav)} />
@ -208,7 +206,7 @@ export function Session() {
} }
return ( return (
<> <View style={styles.container}>
{ state.tabbed === false && ( { state.tabbed === false && (
<DetailDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.subWidth } }} <DetailDrawer.Navigator screenOptions={{ drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front', drawerStyle: { width: state.subWidth } }}
drawerContent={(props) => <DetailDrawerContent {...props} />}> drawerContent={(props) => <DetailDrawerContent {...props} />}>
@ -237,14 +235,16 @@ export function Session() {
tabBarActiveTintColor: Colors.white, tabBarActiveTintColor: Colors.white,
tabBarInactiveTintColor: Colors.disabled, tabBarInactiveTintColor: Colors.disabled,
})}> })}>
<Tab.Screen name="Conversation" component={ConversationStackScreen} /> <Tab.Screen name="Conversation">
{(props) => (<SafeAreaView style={styles.tabframe} edges={['top']}><ConversationStackScreen /></SafeAreaView>)}
</Tab.Screen>
<Tab.Screen name="Profile" component={ProfileStackScreen} /> <Tab.Screen name="Profile" component={ProfileStackScreen} />
<Tab.Screen name="Contacts"> <Tab.Screen name="Contacts">
{(props) => (<SafeAreaView style={styles.tabframe}><ContactStackScreen /></SafeAreaView>)} {(props) => (<SafeAreaView style={styles.tabframe} edges={['top']}><ContactStackScreen /></SafeAreaView>)}
</Tab.Screen> </Tab.Screen>
</Tab.Navigator> </Tab.Navigator>
)} )}
</> </View>
); );
} }

View File

@ -2,6 +2,10 @@ import { StyleSheet } from 'react-native';
import { Colors } from 'constants/Colors'; import { Colors } from 'constants/Colors';
export const styles = StyleSheet.create({ export const styles = StyleSheet.create({
container: {
width: '100%',
height: '100%',
},
tabBar: { tabBar: {
backgroundColor: Colors.primary, backgroundColor: Colors.primary,
}, },
@ -26,6 +30,7 @@ export const styles = StyleSheet.create({
flexDirection: 'row', flexDirection: 'row',
paddingTop: 8, paddingTop: 8,
paddingBottom: 4, paddingBottom: 4,
paddingRight: 8,
}, },
option: { option: {
width: '50%', width: '50%',
@ -40,6 +45,8 @@ export const styles = StyleSheet.create({
}, },
channels: { channels: {
flexGrow: 1, flexGrow: 1,
flexShrink: 1,
position: 'relative',
}, },
tabframe: { tabframe: {
width: '100%', width: '100%',

View File

@ -4,22 +4,47 @@ import { styles } from './Channels.styled';
import { useChannels } from './useChannels.hook'; import { useChannels } from './useChannels.hook';
import Ionicons from '@expo/vector-icons/AntDesign'; import Ionicons from '@expo/vector-icons/AntDesign';
import { ChannelItem } from './channelItem/ChannelItem'; import { ChannelItem } from './channelItem/ChannelItem';
import Colors from 'constants/Colors';
export function Channels() { export function Channels() {
const { state, actions } = useChannels(); const { state, actions } = useChannels();
return ( return (
<View style={styles.container}> <View style={styles.container}>
{ state.tabbed && (
<View style={styles.topbar}>
<View style={styles.inputwrapper}> <View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="search1" size={16} color={'#ffffff'} /> <Ionicons style={styles.icon} name="search1" size={16} color={Colors.text} />
<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={Colors.text} placeholder="Topic" />
<View style={styles.space} /> <View style={styles.space} />
</View> </View>
<TouchableOpacity style={styles.add}>
<Ionicons name={'message1'} size={16} color={Colors.white} style={[styles.box, { transform: [ { rotate: "180deg" }, ]} ]}/>
<Text style={styles.newtext}>New</Text>
</TouchableOpacity>
</View>
)}
{ !state.tabbed && (
<View style={styles.searchbar}>
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="search1" size={16} color={Colors.text} />
<TextInput style={styles.inputfield} value={state.topic} onChangeText={actions.setTopic}
autoCapitalize="none" placeholderTextColor={Colors.text} placeholder="Topic" />
<View style={styles.space} />
</View>
</View>
)}
<FlatList style={styles.channels} <FlatList style={styles.channels}
data={state.channels} data={state.channels}
renderItem={({ item }) => <ChannelItem item={item} />} renderItem={({ item }) => <ChannelItem item={item} />}
keyExtractor={item => (`${item.cardId}:${item.channelId}`)} keyExtractor={item => (`${item.cardId}:${item.channelId}`)}
/> />
{ !state.tabbed && (
<TouchableOpacity style={styles.addbottom}>
<Ionicons name={'message1'} size={16} color={Colors.white} />
<Text style={styles.newtext}>New Topic</Text>
</TouchableOpacity>
)}
</View> </View>
); );
} }

View File

@ -8,20 +8,33 @@ export const styles = StyleSheet.create({
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
}, },
topbar: {
borderTopWidth: 1,
borderBottomWidth: 1,
borderColor: Colors.divider,
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 16,
paddingRight: 16,
display: 'flex',
flexDirection: 'row',
},
searchbar: {
paddingRight: 8,
},
inputwrapper: { inputwrapper: {
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
borderRadius: 4, borderRadius: 4,
backgroundColor: Colors.background, backgroundColor: Colors.white,
alignItems: 'center', alignItems: 'center',
marginRight: 8, flexGrow: 1,
marginLeft: 8,
}, },
inputfield: { inputfield: {
flex: 1, flex: 1,
textAlign: 'center', textAlign: 'center',
padding: 4, padding: 4,
color: Colors.white, color: Colors.text,
fontSize: 16, fontSize: 16,
}, },
icon: { icon: {
@ -33,5 +46,28 @@ export const styles = StyleSheet.create({
paddingLeft: 16, paddingLeft: 16,
paddingRight: 16, paddingRight: 16,
}, },
addbottom: {
backgroundColor: Colors.primary,
marginRight: 8,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
padding: 8,
borderRadius: 4,
},
add: {
backgroundColor: Colors.primary,
marginLeft: 16,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
padding: 8,
borderRadius: 4,
},
newtext: {
paddingLeft: 8,
color: Colors.white,
}
}) })

View File

@ -11,7 +11,8 @@ export function useChannels() {
const [state, setState] = useState({ const [state, setState] = useState({
topic: null, topic: null,
channels: [] channels: [],
tabbed: null,
}); });
const items = useRef([]); const items = useRef([]);
@ -19,11 +20,21 @@ export function useChannels() {
const card = useContext(CardContext); const card = useContext(CardContext);
const profile = useContext(ProfileContext); const profile = useContext(ProfileContext);
const app = useContext(AppContext); const app = useContext(AppContext);
const dimensions = useWindowDimensions();
const updateState = (value) => { const updateState = (value) => {
setState((s) => ({ ...s, ...value })); setState((s) => ({ ...s, ...value }));
} }
useEffect(() => {
if (dimensions.width > config.tabbedWidth) {
updateState({ tabbed: false });
}
else {
updateState({ tabbed: true });
}
}, [dimensions]);
const getCard = (guid) => { const getCard = (guid) => {
let contact = null let contact = null
card.state.cards.forEach((card, cardId, map) => { card.state.cards.forEach((card, cardId, map) => {