-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Clipclops] Add screen to view and send clip clops #3754
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
8191304
add new routes with placeholder screens
mozzius 672d2aa
add clops list
haileyok 65528ae
add a clop input
haileyok c528962
add some better padding to the clops
haileyok 95dcced
some more adjustments
haileyok dab6df3
add rnkc
haileyok 6d25ef8
implement rnkc
haileyok 667663f
implement rnkc
haileyok 5d8cedf
be a little less weird about it
haileyok d70c3ee
Merge branch 'main' into hailey/clipclops
haileyok c0054fb
rename clop stuff
haileyok 828aecb
rename more clop
haileyok da81b49
one more
haileyok 09ba885
[Clipclops] Temp codegenerated lexicon (#3749)
mozzius 01d1b5e
add clop service URL hook
haileyok d499546
add dm service url storage
haileyok dfaf605
use context
haileyok af86254
use context for service url (temp)
haileyok 1dcd9ca
remove log
haileyok 4745009
nits
haileyok File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import React from 'react' | ||
import {Pressable, TextInput, View} from 'react-native' | ||
|
||
import {atoms as a, useTheme} from '#/alf' | ||
import {Text} from '#/components/Typography' | ||
|
||
export function MessageInput({ | ||
onSendMessage, | ||
onFocus, | ||
onBlur, | ||
}: { | ||
onSendMessage: (message: string) => void | ||
onFocus: () => void | ||
onBlur: () => void | ||
}) { | ||
const t = useTheme() | ||
const [message, setMessage] = React.useState('') | ||
|
||
const inputRef = React.useRef<TextInput>(null) | ||
|
||
const onSubmit = React.useCallback(() => { | ||
onSendMessage(message) | ||
setMessage('') | ||
setTimeout(() => { | ||
inputRef.current?.focus() | ||
}, 100) | ||
}, [message, onSendMessage]) | ||
|
||
return ( | ||
<View | ||
style={[ | ||
a.flex_row, | ||
a.py_sm, | ||
a.px_sm, | ||
a.rounded_full, | ||
a.mt_sm, | ||
t.atoms.bg_contrast_25, | ||
]}> | ||
<TextInput | ||
accessibilityLabel="Text input field" | ||
accessibilityHint="Write a message" | ||
value={message} | ||
onChangeText={setMessage} | ||
placeholder="Write a message" | ||
style={[a.flex_1, a.text_sm, a.px_sm]} | ||
onSubmitEditing={onSubmit} | ||
onFocus={onFocus} | ||
onBlur={onBlur} | ||
placeholderTextColor={t.palette.contrast_500} | ||
ref={inputRef} | ||
/> | ||
<Pressable | ||
accessibilityRole="button" | ||
style={[ | ||
a.rounded_full, | ||
a.align_center, | ||
a.justify_center, | ||
{height: 30, width: 30, backgroundColor: t.palette.primary_500}, | ||
]} | ||
onPress={onSubmit}> | ||
<Text style={a.text_md}>🐴</Text> | ||
</Pressable> | ||
</View> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import React from 'react' | ||
import {View} from 'react-native' | ||
|
||
import {atoms as a, useTheme} from '#/alf' | ||
import {Text} from '#/components/Typography' | ||
import * as TempDmChatDefs from '#/temp/dm/defs' | ||
|
||
export function MessageItem({item}: {item: TempDmChatDefs.MessageView}) { | ||
const t = useTheme() | ||
|
||
return ( | ||
<View | ||
style={[ | ||
a.py_sm, | ||
a.px_md, | ||
a.my_xs, | ||
a.rounded_md, | ||
{ | ||
backgroundColor: t.palette.primary_500, | ||
maxWidth: '65%', | ||
borderRadius: 17, | ||
}, | ||
]}> | ||
<Text style={[a.text_md, {lineHeight: 1.2, color: 'white'}]}> | ||
{item.text} | ||
</Text> | ||
</View> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
import React, {useCallback, useMemo, useRef, useState} from 'react' | ||
import {Alert, FlatList, View, ViewToken} from 'react-native' | ||
import {KeyboardAvoidingView} from 'react-native-keyboard-controller' | ||
|
||
import {isWeb} from 'platform/detection' | ||
import {MessageInput} from '#/screens/Messages/Conversation/MessageInput' | ||
import {MessageItem} from '#/screens/Messages/Conversation/MessageItem' | ||
import { | ||
useChat, | ||
useChatLogQuery, | ||
useSendMessageMutation, | ||
} from '#/screens/Messages/Temp/query/query' | ||
import {Loader} from '#/components/Loader' | ||
import {Text} from '#/components/Typography' | ||
import * as TempDmChatDefs from '#/temp/dm/defs' | ||
|
||
function MaybeLoader({isLoading}: {isLoading: boolean}) { | ||
return ( | ||
<View | ||
style={{ | ||
height: 50, | ||
width: '100%', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
}}> | ||
{isLoading && <Loader size="xl" />} | ||
</View> | ||
) | ||
} | ||
|
||
function renderItem({ | ||
item, | ||
}: { | ||
item: TempDmChatDefs.MessageView | TempDmChatDefs.DeletedMessage | ||
}) { | ||
if (TempDmChatDefs.isMessageView(item)) return <MessageItem item={item} /> | ||
|
||
if (TempDmChatDefs.isDeletedMessage(item)) return <Text>Deleted message</Text> | ||
|
||
return null | ||
} | ||
|
||
// TODO rm | ||
// TEMP: This is a temporary function to generate unique keys for mutation placeholders | ||
const generateUniqueKey = () => `_${Math.random().toString(36).substr(2, 9)}` | ||
|
||
function onScrollToEndFailed() { | ||
// Placeholder function. You have to give FlatList something or else it will error. | ||
} | ||
|
||
export function MessagesList({chatId}: {chatId: string}) { | ||
const flatListRef = useRef<FlatList>(null) | ||
|
||
// Whenever we reach the end (visually the top), we don't want to keep calling it. We will set `isFetching` to true | ||
// once the request for new posts starts. Then, we will change it back to false after the content size changes. | ||
const isFetching = useRef(false) | ||
|
||
// We use this to know if we should scroll after a new clop is added to the list | ||
const isAtBottom = useRef(false) | ||
|
||
// Because the viewableItemsChanged callback won't have access to the updated state, we use a ref to store the | ||
// total number of clops | ||
// TODO this needs to be set to whatever the initial number of messages is | ||
const totalMessages = useRef(10) | ||
|
||
// TODO later | ||
const [_, setShowSpinner] = useState(false) | ||
Comment on lines
+66
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This works - has been tested against fake data - but the hacked state doesn't make it great to work with. Once we have some paginated results though it will be straight forward. |
||
|
||
// Query Data | ||
const {data: chat} = useChat(chatId) | ||
const {mutate: sendMessage} = useSendMessageMutation(chatId) | ||
useChatLogQuery() | ||
|
||
const [onViewableItemsChanged, viewabilityConfig] = useMemo(() => { | ||
return [ | ||
(info: {viewableItems: Array<ViewToken>; changed: Array<ViewToken>}) => { | ||
const firstVisibleIndex = info.viewableItems[0]?.index | ||
|
||
isAtBottom.current = Number(firstVisibleIndex) < 2 | ||
}, | ||
{ | ||
itemVisiblePercentThreshold: 50, | ||
minimumViewTime: 10, | ||
}, | ||
] | ||
}, []) | ||
|
||
const onContentSizeChange = useCallback(() => { | ||
if (isAtBottom.current) { | ||
flatListRef.current?.scrollToOffset({offset: 0, animated: true}) | ||
} | ||
|
||
isFetching.current = false | ||
setShowSpinner(false) | ||
}, []) | ||
|
||
const onEndReached = useCallback(() => { | ||
if (isFetching.current) return | ||
isFetching.current = true | ||
setShowSpinner(true) | ||
|
||
// Eventually we will add more here when we hit the top through RQuery | ||
// We wouldn't actually use a timeout, but there would be a delay while loading | ||
setTimeout(() => { | ||
// Do something | ||
setShowSpinner(false) | ||
}, 1000) | ||
}, []) | ||
|
||
const onInputFocus = useCallback(() => { | ||
if (!isAtBottom.current) { | ||
flatListRef.current?.scrollToOffset({offset: 0, animated: true}) | ||
} | ||
}, []) | ||
|
||
const onSendMessage = useCallback( | ||
async (message: string) => { | ||
if (!message) return | ||
|
||
try { | ||
sendMessage({ | ||
message, | ||
tempId: generateUniqueKey(), | ||
}) | ||
} catch (e: any) { | ||
Alert.alert(e.toString()) | ||
} | ||
}, | ||
[sendMessage], | ||
) | ||
|
||
const onInputBlur = useCallback(() => {}, []) | ||
|
||
const messages = useMemo(() => { | ||
if (!chat) return [] | ||
|
||
const filtered = chat.messages.filter( | ||
( | ||
message, | ||
): message is | ||
| TempDmChatDefs.MessageView | ||
| TempDmChatDefs.DeletedMessage => { | ||
return ( | ||
TempDmChatDefs.isMessageView(message) || | ||
TempDmChatDefs.isDeletedMessage(message) | ||
) | ||
}, | ||
) | ||
totalMessages.current = filtered.length | ||
}, [chat]) | ||
|
||
return ( | ||
<KeyboardAvoidingView | ||
style={{flex: 1, marginBottom: isWeb ? 20 : 85}} | ||
behavior="padding" | ||
keyboardVerticalOffset={70} | ||
contentContainerStyle={{flex: 1}}> | ||
<FlatList | ||
data={messages} | ||
keyExtractor={item => item.id} | ||
renderItem={renderItem} | ||
contentContainerStyle={{paddingHorizontal: 10}} | ||
// In the future, we might want to adjust this value. Not very concerning right now as long as we are only | ||
// dealing with text. But whenever we have images or other media and things are taller, we will want to lower | ||
// this...probably | ||
initialNumToRender={20} | ||
// Same with the max to render per batch. Let's be safe for now though. | ||
maxToRenderPerBatch={25} | ||
inverted={true} | ||
onEndReached={onEndReached} | ||
onScrollToIndexFailed={onScrollToEndFailed} | ||
onContentSizeChange={onContentSizeChange} | ||
onViewableItemsChanged={onViewableItemsChanged} | ||
viewabilityConfig={viewabilityConfig} | ||
maintainVisibleContentPosition={{ | ||
minIndexForVisible: 0, | ||
}} | ||
// This is actually a header since we are inverted! | ||
ListFooterComponent={<MaybeLoader isLoading={false} />} | ||
removeClippedSubviews={true} | ||
ref={flatListRef} | ||
keyboardDismissMode="none" | ||
/> | ||
<View style={{paddingHorizontal: 10}}> | ||
<MessageInput | ||
onSendMessage={onSendMessage} | ||
onFocus={onInputFocus} | ||
onBlur={onInputBlur} | ||
/> | ||
</View> | ||
</KeyboardAvoidingView> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to self: maybe we don't need this timeout