support thread latching

This commit is contained in:
Roland Osborne 2022-10-04 14:00:49 -07:00
parent 8988a63634
commit aaf40cd571
5 changed files with 61 additions and 7 deletions

View File

@ -8,6 +8,7 @@ export function useConversationContext() {
const [state, setState] = useState({ const [state, setState] = useState({
subject: null, subject: null,
logo: null, logo: null,
revision: null,
contacts: [], contacts: [],
topics: new Map(), topics: new Map(),
}); });
@ -152,7 +153,12 @@ export function useConversationContext() {
// update revision // update revision
revision.current = channelItem.revision; revision.current = channelItem.revision;
if (curView == setView.current) { if (curView == setView.current) {
console.log("update:", topics.current.size); if (cardId) {
card.actions.setChannelReadRevision(cardId, channelId, revision.current);
}
else {
channel.actions.setReadRevision(channelId, revision.current);
}
updateState({ topics: topics.current }); updateState({ topics: topics.current });
} }

View File

@ -70,7 +70,9 @@ export function Session() {
}, [selected]); }, [selected]);
return ( return (
<ConversationStack.Navigator screenOptions={({ route }) => ({ headerShown: true, headerTintColor: Colors.primary })}> <ConversationStack.Navigator
screenOptions={({ route }) => ({ headerShown: true, headerTintColor: Colors.primary })}
screenListeners={{ state: (e) => { if (e?.data?.state?.index === 0 && selected) { setSelected(null); }}, }}>
<ConversationStack.Screen name="channels" options={{ <ConversationStack.Screen name="channels" options={{
headerStyle: { backgroundColor: Colors.titleBackground }, headerStyle: { backgroundColor: Colors.titleBackground },
headerBackTitleVisible: false, headerBackTitleVisible: false,

View File

@ -1,6 +1,6 @@
import { TextInput, View, TouchableOpacity, Text, } from 'react-native'; import { TextInput, View, TouchableOpacity, Text, } from 'react-native';
import { FlatList, ScrollView } from '@stream-io/flat-list-mvcp'; import { FlatList, ScrollView } from '@stream-io/flat-list-mvcp';
import { useState, useRef } from 'react'; import { useState, useRef, useEffect } from 'react';
import { useConversation } from './useConversation.hook'; import { useConversation } from './useConversation.hook';
import { styles } from './Conversation.styled'; import { styles } from './Conversation.styled';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
@ -26,25 +26,47 @@ export function ConversationHeader({ closeConversation, openDetails }) {
<Text style={styles.subjectText} numberOfLines={1} ellipsizeMode={'tail'}>{ state.subject }</Text> <Text style={styles.subjectText} numberOfLines={1} ellipsizeMode={'tail'}>{ state.subject }</Text>
</View> </View>
<TouchableOpacity style={styles.action} onPress={setDetails}> <TouchableOpacity style={styles.action} onPress={setDetails}>
<Ionicons name="setting" size={20} color={Colors.primary} /> <Ionicons name="setting" size={26} color={Colors.primary} />
</TouchableOpacity> </TouchableOpacity>
</View> </View>
); );
} }
function show(arg) {
console.log(arg);
}
export function ConversationBody() { export function ConversationBody() {
const { state, actions } = useConversation(); const { state, actions } = useConversation();
const ref = useRef();
const latch = () => {
actions.latch();
ref.current.scrollToIndex({ animated: true, index: 0 });
}
return ( return (
<View style={styles.topics}> <View style={styles.topics}>
<FlatList <FlatList
ref={ref}
data={state.topics} data={state.topics}
maintainVisibleContentPosition={{ minIndexForVisibile: 0, }} onScrollBeginDrag={actions.unlatch}
maintainVisibleContentPosition={ state.latched ? null : { minIndexForVisibile: 2, } }
inverted={true} inverted={true}
renderItem={({item}) => <View><Text>ITEM { item?.detail?.data }</Text></View>} renderItem={({item}) => <View><Text>ITEM { item?.detail?.data }</Text></View>}
keyExtractor={item => item.topicId} keyExtractor={item => item.topicId}
/> />
<View>
<AddTopic /> <AddTopic />
<View style={styles.latchbar}>
{ !state.latched && (
<TouchableOpacity style={styles.latch} onPress={latch}>
<Ionicons name="downcircleo" size={24} color={Colors.primary} />
</TouchableOpacity>
)}
</View>
</View>
</View> </View>
); );
} }
@ -57,7 +79,7 @@ export function Conversation({ closeConversation, openDetails }) {
<SafeAreaView edges={['right']} style={styles.header}> <SafeAreaView edges={['right']} style={styles.header}>
<Text style={styles.subjectText} numberOfLines={1} ellipsizeMode={'tail'}>{ state.subject }</Text> <Text style={styles.subjectText} numberOfLines={1} ellipsizeMode={'tail'}>{ state.subject }</Text>
<TouchableOpacity style={styles.action} onPress={openDetails}> <TouchableOpacity style={styles.action} onPress={openDetails}>
<Ionicons name="setting" size={20} color={Colors.primary} /> <Ionicons name="setting" size={24} color={Colors.primary} />
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity style={styles.close} onPress={closeConversation}> <TouchableOpacity style={styles.close} onPress={closeConversation}>
<Ionicons name="close" size={20} color={Colors.text} /> <Ionicons name="close" size={20} color={Colors.text} />

View File

@ -73,5 +73,22 @@ export const styles = StyleSheet.create({
backgroundColor: Colors.white, backgroundColor: Colors.white,
maxHeight: 64, maxHeight: 64,
}, },
addtopic: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
},
latchbar: {
position: 'absolute',
top: -16,
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
width: '100%',
},
latch: {
backgroundColor: Colors.formBackground,
borderRadius: 8,
},
}) })

View File

@ -7,6 +7,7 @@ export function useConversation() {
topics: [], topics: [],
subject: null, subject: null,
logo: null, logo: null,
latched: true,
}); });
const conversation = useContext(ConversationContext); const conversation = useContext(ConversationContext);
@ -33,6 +34,12 @@ export function useConversation() {
}, [conversation]); }, [conversation]);
const actions = { const actions = {
latch: () => {
updateState({ latched: true });
},
unlatch: () => {
updateState({ latched: false });
},
}; };
return { state, actions }; return { state, actions };