From 332aab134e42c5d9571481693cf5607695c7f08d Mon Sep 17 00:00:00 2001 From: Christopher Poile Date: Fri, 3 Nov 2023 17:51:32 -0400 Subject: [PATCH] MM-55010 - Calls: more messages bar adjustments (#7620) * refactor; tried to clarify more_messages; new design * adjust more_messages text spacing * small fix for height with incoming call on current channel * move calls-specific code in the calls product behind a hook --- .../post_list/more_messages/more_messages.tsx | 55 ++++++++++--------- app/components/post_list/post_list.tsx | 5 -- .../components/floating_call_container.tsx | 9 ++- app/products/calls/hooks.ts | 27 ++++++++- app/screens/channel/channel.tsx | 2 - .../channel_post_list/channel_post_list.tsx | 5 -- 6 files changed, 58 insertions(+), 45 deletions(-) diff --git a/app/components/post_list/more_messages/more_messages.tsx b/app/components/post_list/more_messages/more_messages.tsx index 18b0024dc..bb33275b4 100644 --- a/app/components/post_list/more_messages/more_messages.tsx +++ b/app/components/post_list/more_messages/more_messages.tsx @@ -7,16 +7,15 @@ import Animated, {interpolate, useAnimatedStyle, useSharedValue, withSpring} fro import {useSafeAreaInsets} from 'react-native-safe-area-context'; import {resetMessageCount} from '@actions/local/channel'; +import {useCallsAdjustment} from '@app/products/calls/hooks'; import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; import TouchableWithFeedback from '@components/touchable_with_feedback'; import {Events} from '@constants'; -import {CURRENT_CALL_BAR_HEIGHT, JOIN_CALL_BAR_HEIGHT} from '@constants/view'; import {useServerUrl} from '@context/server'; -import {useIsTablet} from '@hooks/device'; import useDidUpdate from '@hooks/did_update'; import EphemeralStore from '@store/ephemeral_store'; -import {makeStyleSheetFromTheme, hexToHue} from '@utils/theme'; +import {makeStyleSheetFromTheme, hexToHue, changeOpacity} from '@utils/theme'; import {typography} from '@utils/typography'; import type {PostList} from '@typings/components/post_list'; @@ -34,8 +33,6 @@ type Props = { unreadCount: number; theme: Theme; testID: string; - currentCallBarVisible: boolean; - joinCallBannerVisible: boolean; } const HIDDEN_TOP = -60; @@ -60,9 +57,13 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { flexDirection: 'row', justifyContent: 'space-evenly', alignItems: 'center', - paddingLeft: 12, width: '100%', - height: 42, + height: 40, + borderRadius: 8, + paddingTop: 4, + paddingRight: 4, + paddingBottom: 4, + paddingLeft: 8, shadowColor: theme.centerChannelColor, shadowOffset: { width: 0, @@ -70,29 +71,30 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { }, shadowOpacity: 0.12, shadowRadius: 4, + elevation: 4, }, - roundBorder: { - borderRadius: 8, + iconContainer: { + top: 1, + width: 32, }, icon: { fontSize: 18, color: theme.buttonColor, alignSelf: 'center', }, - iconContainer: { - top: 2, - width: 22, + closeIcon: { + color: changeOpacity(theme.buttonColor, 0.56), }, pressContainer: { flex: 1, flexDirection: 'row', }, textContainer: { - paddingLeft: 4, + marginLeft: 8, }, text: { color: theme.buttonColor, - ...typography('Body', 200, 'SemiBold'), + ...typography('Body', 100, 'SemiBold'), }, }; }); @@ -110,11 +112,8 @@ const MoreMessages = ({ unreadCount, testID, theme, - currentCallBarVisible, - joinCallBannerVisible, }: Props) => { const serverUrl = useServerUrl(); - const isTablet = useIsTablet(); const insets = useSafeAreaInsets(); const pressed = useRef(false); const resetting = useRef(false); @@ -122,12 +121,14 @@ const MoreMessages = ({ const [loading, setLoading] = useState(EphemeralStore.isLoadingMessagesForChannel(serverUrl, channelId)); const [remaining, setRemaining] = useState(0); const underlayColor = useMemo(() => `hsl(${hexToHue(theme.buttonBg)}, 50%, 38%)`, [theme]); - const top = useSharedValue(0); - const adjustedShownTop = SHOWN_TOP + (currentCallBarVisible ? CURRENT_CALL_BAR_HEIGHT : 0) + (joinCallBannerVisible ? JOIN_CALL_BAR_HEIGHT : 0); - const adjustTop = isTablet || (isCRTEnabled && rootId); - const shownTop = adjustTop ? SHOWN_TOP : adjustedShownTop; - const BARS_FACTOR = Math.abs((1) / (HIDDEN_TOP - SHOWN_TOP)); const styles = getStyleSheet(theme); + const top = useSharedValue(0); + const callsAdjustment = useCallsAdjustment(serverUrl, channelId); + + // The final top: + const adjustedTop = insets.top + callsAdjustment; + + const BARS_FACTOR = Math.abs((1) / (HIDDEN_TOP - SHOWN_TOP)); const animatedStyle = useAnimatedStyle(() => ({ transform: [{ @@ -142,13 +143,13 @@ const MoreMessages = ({ [ HIDDEN_TOP, HIDDEN_TOP, - shownTop + (adjustTop ? 0 : insets.top), - shownTop + (adjustTop ? 0 : insets.top), + adjustedTop, + adjustedTop, ], 'clamp', ), {damping: 15}), }], - }), [shownTop, insets.top, adjustTop]); + }), [adjustedTop]); // Due to the implementation differences "unreadCount" gets updated for a channel on reset but not for a thread. // So we maintain a localUnreadCount to hide the indicator when the count is reset. @@ -254,7 +255,7 @@ const MoreMessages = ({ return ( - + diff --git a/app/components/post_list/post_list.tsx b/app/components/post_list/post_list.tsx index f2ad16fac..7bd89b9a8 100644 --- a/app/components/post_list/post_list.tsx +++ b/app/components/post_list/post_list.tsx @@ -52,7 +52,6 @@ type Props = { header?: ReactElement; testID: string; currentCallBarVisible?: boolean; - joinCallBannerVisible?: boolean; savedPostIds: Set; } @@ -111,8 +110,6 @@ const PostList = ({ showMoreMessages, showNewMessageLine = true, testID, - currentCallBarVisible, - joinCallBannerVisible, savedPostIds, }: Props) => { const listRef = useRef>(null); @@ -377,8 +374,6 @@ const PostList = ({ scrollToIndex={scrollToIndex} theme={theme} testID={`${testID}.more_messages_button`} - currentCallBarVisible={Boolean(currentCallBarVisible)} - joinCallBannerVisible={Boolean(joinCallBannerVisible)} /> } diff --git a/app/products/calls/components/floating_call_container.tsx b/app/products/calls/components/floating_call_container.tsx index bc826b8d0..0a88911f8 100644 --- a/app/products/calls/components/floating_call_container.tsx +++ b/app/products/calls/components/floating_call_container.tsx @@ -8,12 +8,10 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'; import CurrentCallBar from '@calls/components/current_call_bar'; import {IncomingCallsContainer} from '@calls/components/incoming_calls_container'; import JoinCallBanner from '@calls/components/join_call_banner'; -import {DEFAULT_HEADER_HEIGHT} from '@constants/view'; +import {DEFAULT_HEADER_HEIGHT, TABLET_HEADER_HEIGHT} from '@constants/view'; import {useServerUrl} from '@context/server'; import {useIsTablet} from '@hooks/device'; -const topBarHeight = DEFAULT_HEADER_HEIGHT; - const style = StyleSheet.create({ wrapper: { position: 'absolute', @@ -36,9 +34,10 @@ const FloatingCallContainer = ({channelId, showJoinCallBanner, showIncomingCalls const insets = useSafeAreaInsets(); const isTablet = useIsTablet(); - const topBarIsIncludedAlready = Boolean(isTablet || threadScreen); + const topBarForTablet = (isTablet && !threadScreen) ? TABLET_HEADER_HEIGHT : 0; + const topBarChannel = (!isTablet && !threadScreen) ? DEFAULT_HEADER_HEIGHT : 0; const wrapperTop = { - top: insets.top + (topBarIsIncludedAlready ? 0 : topBarHeight), + top: insets.top + topBarForTablet + topBarChannel, }; return ( diff --git a/app/products/calls/hooks.ts b/app/products/calls/hooks.ts index e92426eab..28d0fe35a 100644 --- a/app/products/calls/hooks.ts +++ b/app/products/calls/hooks.ts @@ -8,8 +8,9 @@ import {useIntl} from 'react-intl'; import {Alert, Platform} from 'react-native'; import Permissions from 'react-native-permissions'; +import {CALL_ERROR_BAR_HEIGHT, CALL_NOTIFICATION_BAR_HEIGHT, CURRENT_CALL_BAR_HEIGHT, JOIN_CALL_BAR_HEIGHT} from '@app/constants/view'; import {initializeVoiceTrack} from '@calls/actions/calls'; -import {setMicPermissionsGranted} from '@calls/state'; +import {setMicPermissionsGranted, useCallsState, useChannelsWithCalls, useCurrentCall, useGlobalCallsState, useIncomingCalls} from '@calls/state'; import {errorAlert} from '@calls/utils'; import {useServerUrl} from '@context/server'; import {useAppState} from '@hooks/device'; @@ -108,3 +109,27 @@ export const usePermissionsChecker = (micPermissionsGranted: boolean) => { } }, [appState]); }; + +export const useCallsAdjustment = (serverUrl: string, channelId: string) => { + const incomingCalls = useIncomingCalls().incomingCalls; + const channelsWithCalls = useChannelsWithCalls(serverUrl); + const callsState = useCallsState(serverUrl); + const globalCallsState = useGlobalCallsState(); + const currentCall = useCurrentCall(); + const dismissed = Boolean(callsState.calls[channelId]?.dismissed[callsState.myUserId]); + const inCurrentCall = currentCall?.id === channelId; + const joinCallBannerVisible = Boolean(channelsWithCalls[channelId]) && !dismissed && !inCurrentCall; + + // Do we have calls banners? + const currentCallBarVisible = Boolean(currentCall); + const micPermissionsError = !globalCallsState.micPermissionsGranted && (currentCall && !currentCall.micPermissionsErrorDismissed); + const callQualityAlert = Boolean(currentCall?.callQualityAlert); + const incomingCallsShowing = incomingCalls.filter((ic) => ic.channelID !== channelId); + const callsIncomingAdjustment = (incomingCallsShowing.length * CALL_NOTIFICATION_BAR_HEIGHT) + (incomingCallsShowing.length * 8); + const callsAdjustment = (currentCallBarVisible ? CURRENT_CALL_BAR_HEIGHT + 8 : 0) + + (micPermissionsError ? CALL_ERROR_BAR_HEIGHT + 8 : 0) + + (callQualityAlert ? CALL_ERROR_BAR_HEIGHT + 8 : 0) + + (joinCallBannerVisible ? JOIN_CALL_BAR_HEIGHT + 8 : 0) + + callsIncomingAdjustment; + return callsAdjustment; +}; diff --git a/app/screens/channel/channel.tsx b/app/screens/channel/channel.tsx index ecf133c22..f7f524df5 100644 --- a/app/screens/channel/channel.tsx +++ b/app/screens/channel/channel.tsx @@ -131,8 +131,6 @@ const Channel = ({ { const appState = useAppState(); const isTablet = useIsTablet(); @@ -110,8 +107,6 @@ const ChannelPostList = ({ shouldShowJoinLeaveMessages={shouldShowJoinLeaveMessages} showMoreMessages={true} testID='channel.post_list' - currentCallBarVisible={currentCallBarVisible} - joinCallBannerVisible={joinCallBannerVisible} /> );