From 0a51fb36a264b425f31635712fd15cce29e033cd Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Fri, 9 Jun 2023 11:45:48 -0400 Subject: [PATCH] video fixes (#25720) --- .../chat/conversation/fwd-msg/team-picker.tsx | 2 +- .../conversation/list-area/index.native.tsx | 98 +------------------ .../conversation/messages/wrapper/sent.tsx | 83 ++++++++++++++++ .../conversation/messages/wrapper/wrapper.tsx | 14 ++- 4 files changed, 97 insertions(+), 100 deletions(-) create mode 100644 shared/chat/conversation/messages/wrapper/sent.tsx diff --git a/shared/chat/conversation/fwd-msg/team-picker.tsx b/shared/chat/conversation/fwd-msg/team-picker.tsx index 3120ab6afb90..4fb03c3052b4 100644 --- a/shared/chat/conversation/fwd-msg/team-picker.tsx +++ b/shared/chat/conversation/fwd-msg/team-picker.tsx @@ -63,7 +63,7 @@ const TeamPicker = (props: Props) => { { if (message.inlineVideoPlayable) { const url = `${message.fileURL}&contentforce=true` - preview = url ? : null + preview = url ? : null } else { const src = message.fileURL ?? message.previewURL preview = src ? : null diff --git a/shared/chat/conversation/list-area/index.native.tsx b/shared/chat/conversation/list-area/index.native.tsx index 679aef2fbfb9..504dd698911a 100644 --- a/shared/chat/conversation/list-area/index.native.tsx +++ b/shared/chat/conversation/list-area/index.native.tsx @@ -10,7 +10,7 @@ import SpecialBottomMessage from '../messages/special-bottom-message' import SpecialTopMessage from '../messages/special-top-message' import type * as Types from '../../../constants/types/chat2' import type {ItemType} from '.' -import {Animated, FlatList} from 'react-native' +import {FlatList} from 'react-native' import {ConvoIDContext, SeparatorMapContext} from '../messages/ids-context' import {FlashList, type ListRenderItemInfo} from '@shopify/flash-list' import {getMessageRender} from '../messages/wrapper' @@ -23,97 +23,6 @@ import {usingFlashList} from './flashlist-config' const List = usingFlashList ? FlashList : FlatList -// Bookkeep whats animating so it finishes and isn't replaced, if we've animated it we keep the key and use null -const animatingMap = new Map() - -type AnimatedChildProps = { - animatingKey: string - children: React.ReactNode -} -const AnimatedChild = React.memo(function AnimatedChild({children, animatingKey}: AnimatedChildProps) { - const translateY = new Animated.Value(999) - const opacity = new Animated.Value(0) - React.useEffect(() => { - // on unmount, mark it null - return () => { - animatingMap.set(animatingKey, null) - } - }, [animatingKey]) - - // only animate up once - const onceRef = React.useRef(false) - - React.useEffect(() => { - onceRef.current = false - }, [animatingKey]) - - return ( - { - const {height} = e.nativeEvent.layout - if (onceRef.current) { - return - } - onceRef.current = true - translateY.setValue(height + 10) - Animated.parallel([ - Animated.timing(opacity, { - duration: 200, - toValue: 1, - useNativeDriver: true, - }), - Animated.timing(translateY, { - duration: 200, - toValue: 0, - useNativeDriver: true, - }), - ]).start(() => { - animatingMap.set(animatingKey, null) - }) - }} - > - {children} - - ) -}) - -type SentProps = { - children?: React.ReactElement - ordinal: Types.Ordinal -} -const Sent = React.memo(function Sent({ordinal}: SentProps) { - const conversationIDKey = React.useContext(ConvoIDContext) - const {subType, youSent} = Container.useSelector(state => { - const you = state.config.username - const message = state.chat2.messageMap.get(conversationIDKey)?.get(ordinal) - const youSent = message && message.author === you && message.ordinal !== message.id - const subType = message ? Constants.getMessageRenderType(message) : undefined - return {subType, youSent} - }, shallowEqual) - const key = `${conversationIDKey}:${ordinal}` - const state = animatingMap.get(key) - - if (!subType) return null - - // if its animating always show it - if (state) { - return state - } - - const Clazz = getMessageRender(subType) - if (!Clazz) return null - const children = - // if state is null we already animated it - if (youSent && state === undefined) { - const c = {children} - animatingMap.set(key, c) - return c - } else { - return children || null - } -}) - // We load the first thread automatically so in order to mark it read // we send an action on the first mount once let markedInitiallyLoaded = false @@ -238,11 +147,6 @@ const ConversationList = React.memo(function ConversationList(p: { if (!ordinal) { return null } - - if (!index) { - return - } - const type = messageTypeMap?.get(ordinal) ?? 'text' if (!type) return null const Clazz = getMessageRender(type) diff --git a/shared/chat/conversation/messages/wrapper/sent.tsx b/shared/chat/conversation/messages/wrapper/sent.tsx new file mode 100644 index 000000000000..d8b193f1fbe1 --- /dev/null +++ b/shared/chat/conversation/messages/wrapper/sent.tsx @@ -0,0 +1,83 @@ +import * as React from 'react' +import {Animated} from 'react-native' +// Bookkeep whats animating so it finishes and isn't replaced, if we've animated it we keep the key and use null +const animatingMap = new Map() + +type AnimatedChildProps = { + animatingKey: string + children: React.ReactNode +} +const AnimatedChild = React.memo(function AnimatedChild({children, animatingKey}: AnimatedChildProps) { + const [done, setDone] = React.useState(false) + const translateY = React.useRef(new Animated.Value(999)).current + const opacity = React.useRef(new Animated.Value(0)).current + React.useEffect(() => { + // on unmount, mark it null + return () => { + animatingMap.set(animatingKey, null) + } + }, [animatingKey]) + + // only animate up once + const onceRef = React.useRef(false) + + React.useEffect(() => { + onceRef.current = false + }, [animatingKey]) + + return done ? ( + <>{children} + ) : ( + { + if (onceRef.current) { + return + } + const {height} = e.nativeEvent.layout + onceRef.current = true + translateY.setValue(height + 10) + Animated.parallel([ + Animated.timing(opacity, { + duration: 200, + toValue: 1, + useNativeDriver: true, + }), + Animated.timing(translateY, { + duration: 200, + toValue: 0, + useNativeDriver: true, + }), + ]).start(() => { + animatingMap.set(animatingKey, null) + setDone(true) + }) + }} + > + {children} + + ) +}) + +type SentProps = { + children: React.ReactNode + sentKey: string +} +export const Sent = function Sent(p: SentProps) { + const {children, sentKey} = p + const state = animatingMap.get(sentKey) + + // if its animating always show it + if (state) { + return state + } + + // if state is null we already animated it + if (state === undefined) { + const c = {children} + animatingMap.set(sentKey, c) + return c + } else { + return <>{children} + } +} diff --git a/shared/chat/conversation/messages/wrapper/wrapper.tsx b/shared/chat/conversation/messages/wrapper/wrapper.tsx index dd43e4e89970..77acbfb71eb5 100644 --- a/shared/chat/conversation/messages/wrapper/wrapper.tsx +++ b/shared/chat/conversation/messages/wrapper/wrapper.tsx @@ -18,6 +18,7 @@ import SendIndicator from './send-indicator' import type * as Types from '../../../../constants/types/chat2' import capitalize from 'lodash/capitalize' import {useEdited} from './edited' +import {Sent} from './sent' // import {useDebugLayout} from '../../../../util/debug' export type Props = { @@ -128,6 +129,7 @@ const useRedux = (conversationIDKey: Types.ConversationIDKey, ordinal: Types.Ord const you = state.config.username const m = Constants.getMessage(state, conversationIDKey, ordinal) ?? missingMessage const {exploded, submitState, author, id, botUsername} = m + const youSent = m.author === you && m.ordinal !== m.id const exploding = !!m.exploding const isPendingPayment = Constants.isPendingPaymentMessage(state, m) const decorate = !exploded && !m.errorReason @@ -159,6 +161,7 @@ const useRedux = (conversationIDKey: Types.ConversationIDKey, ordinal: Types.Ord showSendIndicator, type, you, + youSent, } }, shallowEqual) } @@ -483,14 +486,21 @@ export const WrapperMessage = React.memo(function WrapperMessage(p: WMProps) { const {isPendingPayment, decorate, type, hasReactions, isEditing} = mdata const {ecrType, showSendIndicator, showRevoked, showExplodingCountdown, exploding} = mdata - const {reactionsPopupPosition, showCoinsIcon, botname, you} = mdata + const {reactionsPopupPosition, showCoinsIcon, botname, you, youSent} = mdata const canFixOverdraw = !isPendingPayment && !showCenteredHighlight && !isEditing + const maybeSentChildren = + Container.isMobile && youSent ? ( + {children} + ) : ( + children + ) + const tsprops = { botname, bottomChildren, - children, + children: maybeSentChildren, decorate, ecrType, exploding,