get android working
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
import React, {useCallback, useRef} from 'react'
|
import {useCallback, useEffect, useRef, useState} from 'react'
|
||||||
import {LayoutChangeEvent, View} from 'react-native'
|
import {LayoutChangeEvent, Platform, View} from 'react-native'
|
||||||
import {useKeyboardHandler} from 'react-native-keyboard-controller'
|
import {
|
||||||
|
KeyboardGestureArea,
|
||||||
|
useKeyboardHandler,
|
||||||
|
} from 'react-native-keyboard-controller'
|
||||||
import Animated, {
|
import Animated, {
|
||||||
runOnJS,
|
runOnJS,
|
||||||
scrollTo,
|
scrollTo,
|
||||||
@@ -34,6 +37,7 @@ import {List, ListMethods} from '#/view/com/util/List'
|
|||||||
import {ChatDisabled} from '#/screens/Messages/components/ChatDisabled'
|
import {ChatDisabled} from '#/screens/Messages/components/ChatDisabled'
|
||||||
import {MessageInput} from '#/screens/Messages/components/MessageInput'
|
import {MessageInput} from '#/screens/Messages/components/MessageInput'
|
||||||
import {MessageListError} from '#/screens/Messages/components/MessageListError'
|
import {MessageListError} from '#/screens/Messages/components/MessageListError'
|
||||||
|
import {atoms as a, platform} from '#/alf'
|
||||||
import {ChatEmptyPill} from '#/components/dms/ChatEmptyPill'
|
import {ChatEmptyPill} from '#/components/dms/ChatEmptyPill'
|
||||||
import {MessageItem} from '#/components/dms/MessageItem'
|
import {MessageItem} from '#/components/dms/MessageItem'
|
||||||
import {NewMessagesPill} from '#/components/dms/NewMessagesPill'
|
import {NewMessagesPill} from '#/components/dms/NewMessagesPill'
|
||||||
@@ -41,6 +45,10 @@ import {Loader} from '#/components/Loader'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {MessageInputEmbed, useMessageEmbed} from './MessageInputEmbed'
|
import {MessageInputEmbed, useMessageEmbed} from './MessageInputEmbed'
|
||||||
|
|
||||||
|
// Interactive keyboard on Android only works for Android 11+
|
||||||
|
const ANDROID_INTERACTIVE_KEYBOARD =
|
||||||
|
Platform.OS === 'android' && Platform.Version >= 30
|
||||||
|
|
||||||
function MaybeLoader({isLoading}: {isLoading: boolean}) {
|
function MaybeLoader({isLoading}: {isLoading: boolean}) {
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
@@ -93,16 +101,15 @@ export function MessagesList({
|
|||||||
|
|
||||||
const flatListRef = useAnimatedRef<ListMethods>()
|
const flatListRef = useAnimatedRef<ListMethods>()
|
||||||
|
|
||||||
const [newMessagesPill, setNewMessagesPill] = React.useState({
|
const [newMessagesPill, setNewMessagesPill] = useState({
|
||||||
show: false,
|
show: false,
|
||||||
startContentOffset: 0,
|
startContentOffset: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
const [emojiPickerState, setEmojiPickerState] =
|
const [emojiPickerState, setEmojiPickerState] = useState<EmojiPickerState>({
|
||||||
React.useState<EmojiPickerState>({
|
isOpen: false,
|
||||||
isOpen: false,
|
pos: {top: 0, left: 0, right: 0, bottom: 0},
|
||||||
pos: {top: 0, left: 0, right: 0, bottom: 0},
|
})
|
||||||
})
|
|
||||||
|
|
||||||
// We need to keep track of when the scroll offset is at the bottom of the list to know when to scroll as new items
|
// We need to keep track of when the scroll offset is at the bottom of the list to know when to scroll as new items
|
||||||
// are added to the list. For example, if the user is scrolled up to 1iew older messages, we don't want to scroll to
|
// are added to the list. For example, if the user is scrolled up to 1iew older messages, we don't want to scroll to
|
||||||
@@ -119,8 +126,8 @@ export function MessagesList({
|
|||||||
|
|
||||||
// -- Keep track of background state and positioning for new pill
|
// -- Keep track of background state and positioning for new pill
|
||||||
const layoutHeight = useSharedValue(0)
|
const layoutHeight = useSharedValue(0)
|
||||||
const didBackground = React.useRef(false)
|
const didBackground = useRef(false)
|
||||||
React.useEffect(() => {
|
useEffect(() => {
|
||||||
if (convoState.status === ConvoStatus.Backgrounded) {
|
if (convoState.status === ConvoStatus.Backgrounded) {
|
||||||
didBackground.current = true
|
didBackground.current = true
|
||||||
}
|
}
|
||||||
@@ -211,7 +218,7 @@ export function MessagesList({
|
|||||||
}
|
}
|
||||||
}, [convoState, hasScrolled, layoutHeight])
|
}, [convoState, hasScrolled, layoutHeight])
|
||||||
|
|
||||||
const onScroll = React.useCallback(
|
const onScroll = useCallback(
|
||||||
(e: ReanimatedScrollEvent) => {
|
(e: ReanimatedScrollEvent) => {
|
||||||
'worklet'
|
'worklet'
|
||||||
layoutHeight.set(e.layoutMeasurement.height)
|
layoutHeight.set(e.layoutMeasurement.height)
|
||||||
@@ -247,6 +254,8 @@ export function MessagesList({
|
|||||||
// We use this value to keep track of when we want to disable the animation.
|
// We use this value to keep track of when we want to disable the animation.
|
||||||
const layoutScrollWithoutAnimation = useSharedValue(false)
|
const layoutScrollWithoutAnimation = useSharedValue(false)
|
||||||
|
|
||||||
|
const [inputAreaHeight, setInputAreaHeight] = useState(0)
|
||||||
|
|
||||||
useKeyboardHandler(
|
useKeyboardHandler(
|
||||||
{
|
{
|
||||||
onStart: e => {
|
onStart: e => {
|
||||||
@@ -270,6 +279,7 @@ export function MessagesList({
|
|||||||
onInteractive: e => {
|
onInteractive: e => {
|
||||||
'worklet'
|
'worklet'
|
||||||
keyboardHeight.set(e.height)
|
keyboardHeight.set(e.height)
|
||||||
|
console.log(e.height, bottomOffset)
|
||||||
if (e.height > bottomOffset) {
|
if (e.height > bottomOffset) {
|
||||||
scrollTo(flatListRef, 0, 1e7, false)
|
scrollTo(flatListRef, 0, 1e7, false)
|
||||||
}
|
}
|
||||||
@@ -375,7 +385,7 @@ export function MessagesList({
|
|||||||
)
|
)
|
||||||
|
|
||||||
// -- List layout changes (opening emoji keyboard, etc.)
|
// -- List layout changes (opening emoji keyboard, etc.)
|
||||||
const onListLayout = React.useCallback(
|
const onListLayout = useCallback(
|
||||||
(e: LayoutChangeEvent) => {
|
(e: LayoutChangeEvent) => {
|
||||||
layoutHeight.set(e.nativeEvent.layout.height)
|
layoutHeight.set(e.nativeEvent.layout.height)
|
||||||
|
|
||||||
@@ -394,7 +404,7 @@ export function MessagesList({
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
const scrollToEndOnPress = React.useCallback(() => {
|
const scrollToEndOnPress = useCallback(() => {
|
||||||
flatListRef.current?.scrollToOffset({
|
flatListRef.current?.scrollToOffset({
|
||||||
offset: prevContentHeight.current,
|
offset: prevContentHeight.current,
|
||||||
animated: true,
|
animated: true,
|
||||||
@@ -405,35 +415,44 @@ export function MessagesList({
|
|||||||
<>
|
<>
|
||||||
{/* Custom scroll provider so that we can use the `onScroll` event in our custom List implementation */}
|
{/* Custom scroll provider so that we can use the `onScroll` event in our custom List implementation */}
|
||||||
<ScrollProvider onScroll={onScroll}>
|
<ScrollProvider onScroll={onScroll}>
|
||||||
<List
|
<KeyboardGestureArea
|
||||||
ref={flatListRef}
|
interpolator="ios"
|
||||||
data={convoState.items}
|
offset={inputAreaHeight}
|
||||||
renderItem={renderItem}
|
style={[a.flex_1]}>
|
||||||
keyExtractor={keyExtractor}
|
<List
|
||||||
disableFullWindowScroll={true}
|
ref={flatListRef}
|
||||||
disableVirtualization={true}
|
data={convoState.items}
|
||||||
style={animatedListStyle}
|
renderItem={renderItem}
|
||||||
// The extra two items account for the header and the footer components
|
keyExtractor={keyExtractor}
|
||||||
initialNumToRender={isNative ? 32 : 62}
|
disableFullWindowScroll={true}
|
||||||
maxToRenderPerBatch={isWeb ? 32 : 62}
|
disableVirtualization={true}
|
||||||
keyboardDismissMode="interactive"
|
style={animatedListStyle}
|
||||||
keyboardShouldPersistTaps="handled"
|
// The extra two items account for the header and the footer components
|
||||||
maintainVisibleContentPosition={{
|
initialNumToRender={isNative ? 32 : 62}
|
||||||
minIndexForVisible: 0,
|
maxToRenderPerBatch={isWeb ? 32 : 62}
|
||||||
}}
|
keyboardDismissMode={platform({
|
||||||
removeClippedSubviews={false}
|
android: ANDROID_INTERACTIVE_KEYBOARD ? 'interactive' : 'on-drag',
|
||||||
sideBorders={false}
|
ios: 'interactive',
|
||||||
onContentSizeChange={onContentSizeChange}
|
default: 'on-drag',
|
||||||
onLayout={onListLayout}
|
})}
|
||||||
onStartReached={onStartReached}
|
keyboardShouldPersistTaps="handled"
|
||||||
onScrollToIndexFailed={onScrollToIndexFailed}
|
maintainVisibleContentPosition={{minIndexForVisible: 0}}
|
||||||
scrollEventThrottle={100}
|
removeClippedSubviews={false}
|
||||||
ListHeaderComponent={
|
sideBorders={false}
|
||||||
<MaybeLoader isLoading={convoState.isFetchingHistory} />
|
onContentSizeChange={onContentSizeChange}
|
||||||
}
|
onLayout={onListLayout}
|
||||||
/>
|
onStartReached={onStartReached}
|
||||||
|
onScrollToIndexFailed={onScrollToIndexFailed}
|
||||||
|
scrollEventThrottle={100}
|
||||||
|
ListHeaderComponent={
|
||||||
|
<MaybeLoader isLoading={convoState.isFetchingHistory} />
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</KeyboardGestureArea>
|
||||||
</ScrollProvider>
|
</ScrollProvider>
|
||||||
<Animated.View style={animatedStickyViewStyle}>
|
<Animated.View
|
||||||
|
style={animatedStickyViewStyle}
|
||||||
|
onLayout={evt => setInputAreaHeight(evt.nativeEvent.layout.height)}>
|
||||||
{convoState.status === ConvoStatus.Disabled ? (
|
{convoState.status === ConvoStatus.Disabled ? (
|
||||||
<ChatDisabled />
|
<ChatDisabled />
|
||||||
) : blocked ? (
|
) : blocked ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user