mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
support topic creation
This commit is contained in:
parent
fe850ea2e2
commit
fc6898fe68
@ -1,11 +1,12 @@
|
||||
import { useContext } from 'react';
|
||||
import { FlatList, ScrollView, View, TextInput, TouchableOpacity, Text } from 'react-native';
|
||||
import { FlatList, Modal, KeyboardAvoidingView, ScrollView, View, TextInput, TouchableOpacity, Text } from 'react-native';
|
||||
import { styles } from './Channels.styled';
|
||||
import { useChannels } from './useChannels.hook';
|
||||
import Ionicons from '@expo/vector-icons/AntDesign';
|
||||
import { ChannelItem } from './channelItem/ChannelItem';
|
||||
import Colors from 'constants/Colors';
|
||||
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { AddMember } from './addMember/AddMember';
|
||||
|
||||
export function ChannelsTitle({ state, actions }) {
|
||||
return (
|
||||
@ -16,7 +17,7 @@ export function ChannelsTitle({ state, actions }) {
|
||||
autoCapitalize="none" placeholderTextColor={Colors.disabled} placeholder="Topics" />
|
||||
<View style={styles.space} />
|
||||
</View>
|
||||
<TouchableOpacity style={styles.add}>
|
||||
<TouchableOpacity style={styles.add} onPress={actions.showAdding}>
|
||||
<Ionicons name={'message1'} size={16} color={Colors.white} style={[styles.box, { transform: [ { rotateY: "180deg" }, ]} ]}/>
|
||||
<Text style={styles.newtext}>New</Text>
|
||||
</TouchableOpacity>
|
||||
@ -26,13 +27,52 @@ export function ChannelsTitle({ state, actions }) {
|
||||
|
||||
export function ChannelsBody({ state, actions, openConversation }) {
|
||||
return (
|
||||
<FlatList style={styles.channels}
|
||||
data={state.channels}
|
||||
renderItem={({ item }) => <ChannelItem item={item} openConversation={openConversation} />}
|
||||
keyExtractor={item => (`${item.cardId}:${item.channelId}`)}
|
||||
/>
|
||||
<>
|
||||
<FlatList style={styles.channels}
|
||||
data={state.channels}
|
||||
renderItem={({ item }) => <ChannelItem item={item} openConversation={openConversation} />}
|
||||
keyExtractor={item => (`${item.cardId}:${item.channelId}`)}
|
||||
/>
|
||||
<Modal
|
||||
animationType="fade"
|
||||
transparent={true}
|
||||
visible={state.adding}
|
||||
supportedOrientations={['portrait', 'landscape']}
|
||||
onRequestClose={actions.hideAdding}
|
||||
>
|
||||
<KeyboardAvoidingView behavior="height" style={styles.addWrapper}>
|
||||
<View style={styles.addContainer}>
|
||||
<Text style={styles.addHeader}>New Topic:</Text>
|
||||
<View style={styles.inputField}>
|
||||
<TextInput style={styles.input} value={state.subjectUpdate} onChangeText={actions.setSubjectUpdate}
|
||||
autoCapitalize="words" placeholder="Subject" />
|
||||
</View>
|
||||
<Text style={styles.label}>Members:</Text>
|
||||
{ state.connected.length == 0 && (
|
||||
<View style={styles.emptyMembers}>
|
||||
<Text style={styles.empty}>No Connected Contacts</Text>
|
||||
</View>
|
||||
)}
|
||||
{ state.connected.length > 0 && (
|
||||
<FlatList style={styles.addMembers}
|
||||
data={state.connected}
|
||||
renderItem={({ item }) => <AddMember members={[]} item={item} />}
|
||||
keyExtractor={item => item.cardId}
|
||||
/>
|
||||
)}
|
||||
<View style={styles.addControls}>
|
||||
<TouchableOpacity style={styles.cancel} onPress={actions.hideAdding}>
|
||||
<Text>Cancel</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.save} onPress={actions.hideAdding}>
|
||||
<Text style={styles.saveText}>Save</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export function Channels({ openConversation }) {
|
||||
|
@ -91,5 +91,92 @@ export const styles = StyleSheet.create({
|
||||
borderTopWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
},
|
||||
cancel: {
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.lightgrey,
|
||||
borderRadius: 4,
|
||||
padding: 4,
|
||||
marginRight: 8,
|
||||
width: 72,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
save: {
|
||||
backgroundColor: Colors.primary,
|
||||
borderRadius: 4,
|
||||
padding: 4,
|
||||
marginRight: 8,
|
||||
width: 72,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
saveText: {
|
||||
color: Colors.white,
|
||||
},
|
||||
addControls: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
addWrapper: {
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: 'rgba(52, 52, 52, 0.8)'
|
||||
},
|
||||
addContainer: {
|
||||
backgroundColor: Colors.formBackground,
|
||||
padding: 16,
|
||||
width: '80%',
|
||||
maxWidth: 400,
|
||||
},
|
||||
addHeader: {
|
||||
fontSize: 18,
|
||||
paddingBottom: 16,
|
||||
},
|
||||
addMembers: {
|
||||
width: '100%',
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.lightgrey,
|
||||
borderRadius: 4,
|
||||
marginBottom: 8,
|
||||
height: 200,
|
||||
},
|
||||
emptyMembers: {
|
||||
width: '100%',
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.lightgrey,
|
||||
borderRadius: 4,
|
||||
marginBottom: 8,
|
||||
height: 200,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
inputField: {
|
||||
width: '100%',
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.lightgrey,
|
||||
borderRadius: 4,
|
||||
padding: 8,
|
||||
marginBottom: 8,
|
||||
maxHeight: 92,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
input: {
|
||||
fontSize: 14,
|
||||
flexGrow: 1,
|
||||
},
|
||||
empty: {
|
||||
fontSize: 14,
|
||||
color: Colors.grey,
|
||||
},
|
||||
label: {
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
},
|
||||
})
|
||||
|
||||
|
26
app/mobile/src/session/channels/addMember/AddMember.jsx
Normal file
26
app/mobile/src/session/channels/addMember/AddMember.jsx
Normal file
@ -0,0 +1,26 @@
|
||||
import { Alert, Text, Switch, TouchableOpacity, View } from 'react-native';
|
||||
import { Logo } from 'utils/Logo';
|
||||
import { styles } from './AddMember.styled';
|
||||
import { useAddMember } from './useAddMember.hook';
|
||||
import Colors from 'constants/Colors';
|
||||
|
||||
export function AddMember({ members, item }) {
|
||||
|
||||
const { state, actions } = useAddMember(item, members);
|
||||
|
||||
const setMember = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Logo src={state.logo} width={32} height={32} radius={6} />
|
||||
<View style={styles.detail}>
|
||||
<Text style={styles.name} numberOfLines={1} ellipsizeMode={'tail'}>{ state.name }</Text>
|
||||
<Text style={styles.handle} numberOfLines={1} ellipsizeMode={'tail'}>{ state.handle }</Text>
|
||||
</View>
|
||||
<Switch style={styles.switch} trackColor={styles.track}
|
||||
value={state.member} onValueChange={setMember} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
container: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: 48,
|
||||
alignItems: 'center',
|
||||
borderBottomWidth: 1,
|
||||
borderColor: Colors.itemDivider,
|
||||
paddingLeft: 8,
|
||||
paddingRight: 8,
|
||||
},
|
||||
detail: {
|
||||
paddingLeft: 12,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
},
|
||||
space: {
|
||||
height: 64,
|
||||
},
|
||||
name: {
|
||||
color: Colors.text,
|
||||
fontSize: 14,
|
||||
},
|
||||
handle: {
|
||||
color: Colors.text,
|
||||
fontSize: 12,
|
||||
},
|
||||
connected: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.connected,
|
||||
},
|
||||
requested: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.requested,
|
||||
},
|
||||
connecting: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.connecting,
|
||||
},
|
||||
pending: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.pending,
|
||||
},
|
||||
confirmed: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.confirmed,
|
||||
},
|
||||
track: {
|
||||
false: Colors.grey,
|
||||
true: Colors.background,
|
||||
},
|
||||
switch: {
|
||||
transform: [{ scaleX: .7 }, { scaleY: .7 }],
|
||||
},
|
||||
|
||||
})
|
||||
|
@ -0,0 +1,37 @@
|
||||
import { useState, useEffect, useRef, useContext } from 'react';
|
||||
import { CardContext } from 'context/CardContext';
|
||||
|
||||
export function useAddMember(item, members) {
|
||||
|
||||
const [state, setState] = useState({
|
||||
name: null,
|
||||
handle: null,
|
||||
logo: null,
|
||||
cardId: null,
|
||||
member: false,
|
||||
});
|
||||
|
||||
const card = useContext(CardContext);
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const member = members.filter(contact => item.cardId === contact.cardId);
|
||||
updateState({ member: member.length > 0 });
|
||||
}, [members]);
|
||||
|
||||
useEffect(() => {
|
||||
const { cardId, revision, profile } = item;
|
||||
const { name, handle, node } = profile;
|
||||
updateState({ cardId, name, handle: `${handle}@${node}`,
|
||||
logo: profile.imageSet ? card.actions.getCardLogo(cardId, revision) : 'avatar' });
|
||||
}, [card]);
|
||||
|
||||
const actions = {
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ export function useChannels() {
|
||||
channels: [],
|
||||
tabbed: null,
|
||||
filter: null,
|
||||
adding: false,
|
||||
connected: [],
|
||||
});
|
||||
|
||||
const items = useRef([]);
|
||||
@ -27,6 +29,11 @@ export function useChannels() {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const contacts = Array.from(card.state.cards.values());
|
||||
updateState({ connected: contacts.filter(contact => contact.detail.status === 'connected') });
|
||||
}, [card]);
|
||||
|
||||
useEffect(() => {
|
||||
if (dimensions.width > config.tabbedWidth) {
|
||||
updateState({ tabbed: false });
|
||||
@ -179,6 +186,12 @@ export function useChannels() {
|
||||
setFilter: (filter) => {
|
||||
updateState({ filter });
|
||||
},
|
||||
showAdding: () => {
|
||||
updateState({ adding: true });
|
||||
},
|
||||
hideAdding: () => {
|
||||
updateState({ adding: false });
|
||||
},
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
|
Loading…
Reference in New Issue
Block a user