diff --git a/app/products/calls/components/floating_call_container.tsx b/app/products/calls/components/floating_call_container.tsx index 0a88911f8..d5c264efa 100644 --- a/app/products/calls/components/floating_call_container.tsx +++ b/app/products/calls/components/floating_call_container.tsx @@ -22,14 +22,22 @@ const style = StyleSheet.create({ }); type Props = { - channelId: string; - showJoinCallBanner: boolean; - showIncomingCalls: boolean; - isInACall: boolean; + channelId?: string; + showJoinCallBanner?: boolean; + showIncomingCalls?: boolean; + isInACall?: boolean; threadScreen?: boolean; + channelsScreen?: boolean; } -const FloatingCallContainer = ({channelId, showJoinCallBanner, showIncomingCalls, isInACall, threadScreen}: Props) => { +const FloatingCallContainer = ({ + channelId, + showJoinCallBanner, + showIncomingCalls, + isInACall, + threadScreen, + channelsScreen, +}: Props) => { const serverUrl = useServerUrl(); const insets = useSafeAreaInsets(); const isTablet = useIsTablet(); @@ -39,10 +47,13 @@ const FloatingCallContainer = ({channelId, showJoinCallBanner, showIncomingCalls const wrapperTop = { top: insets.top + topBarForTablet + topBarChannel, }; + const wrapperBottom = { + bottom: 8, + }; return ( - - {showJoinCallBanner && + + {showJoinCallBanner && channelId && { )), ) as Observable>; }; + +export const observeCallStateInChannel = (serverUrl: string, database: Database, channelId: Observable) => { + const isCallInCurrentChannel = combineLatest([channelId, observeChannelsWithCalls(serverUrl)]).pipe( + switchMap(([id, calls]) => of$(Boolean(calls[id]))), + distinctUntilChanged(), + ); + const currentCall = observeCurrentCall(); + const ccChannelId = currentCall.pipe( + switchMap((call) => of$(call?.channelId)), + distinctUntilChanged(), + ); + const isInACall = currentCall.pipe( + switchMap((call) => of$(Boolean(call?.connected))), + distinctUntilChanged(), + ); + const dismissed = combineLatest([channelId, observeCallsState(serverUrl)]).pipe( + switchMap(([id, state]) => of$(Boolean(state.calls[id]?.dismissed[state.myUserId]))), + distinctUntilChanged(), + ); + const isInCurrentChannelCall = combineLatest([channelId, ccChannelId]).pipe( + switchMap(([id, ccId]) => of$(id === ccId)), + distinctUntilChanged(), + ); + const showJoinCallBanner = combineLatest([isCallInCurrentChannel, dismissed, isInCurrentChannelCall]).pipe( + switchMap(([isCall, dism, inCurrCall]) => of$(Boolean(isCall && !dism && !inCurrCall))), + distinctUntilChanged(), + ); + const showIncomingCalls = observeIncomingCalls().pipe( + switchMap((ics) => of$(ics.incomingCalls.length > 0)), + distinctUntilChanged(), + ); + + return { + showJoinCallBanner, + isInACall, + showIncomingCalls, + }; +}; diff --git a/app/screens/channel/index.tsx b/app/screens/channel/index.tsx index 8c7c20419..4974635e0 100644 --- a/app/screens/channel/index.tsx +++ b/app/screens/channel/index.tsx @@ -3,15 +3,9 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; import withObservables from '@nozbe/with-observables'; -import {combineLatest, distinctUntilChanged, of as of$, switchMap} from 'rxjs'; +import {of as of$, switchMap} from 'rxjs'; -import {observeIsCallsEnabledInChannel} from '@calls/observers'; -import { - observeCallsState, - observeChannelsWithCalls, - observeCurrentCall, - observeIncomingCalls, -} from '@calls/state'; +import {observeCallStateInChannel, observeIsCallsEnabledInChannel} from '@calls/observers'; import {Preferences} from '@constants'; import {withServerUrl} from '@context/server'; import {observeCurrentChannel} from '@queries/servers/channel'; @@ -29,37 +23,6 @@ type EnhanceProps = WithDatabaseArgs & { const enhanced = withObservables([], ({database, serverUrl}: EnhanceProps) => { const channelId = observeCurrentChannelId(database); - - const isCallInCurrentChannel = combineLatest([channelId, observeChannelsWithCalls(serverUrl)]).pipe( - switchMap(([id, calls]) => of$(Boolean(calls[id]))), - distinctUntilChanged(), - ); - const currentCall = observeCurrentCall(); - const ccChannelId = currentCall.pipe( - switchMap((call) => of$(call?.channelId)), - distinctUntilChanged(), - ); - const isInACall = currentCall.pipe( - switchMap((call) => of$(Boolean(call?.connected))), - distinctUntilChanged(), - ); - const dismissed = combineLatest([channelId, observeCallsState(serverUrl)]).pipe( - switchMap(([id, state]) => of$(Boolean(state.calls[id]?.dismissed[state.myUserId]))), - distinctUntilChanged(), - ); - const isInCurrentChannelCall = combineLatest([channelId, ccChannelId]).pipe( - switchMap(([id, ccId]) => of$(id === ccId)), - distinctUntilChanged(), - ); - const showJoinCallBanner = combineLatest([isCallInCurrentChannel, dismissed, isInCurrentChannelCall]).pipe( - switchMap(([isCall, dism, inCurrCall]) => of$(Boolean(isCall && !dism && !inCurrCall))), - distinctUntilChanged(), - ); - const showIncomingCalls = observeIncomingCalls().pipe( - switchMap((ics) => of$(ics.incomingCalls.length > 0)), - distinctUntilChanged(), - ); - const dismissedGMasDMNotice = queryPreferencesByCategoryAndName(database, Preferences.CATEGORIES.SYSTEM_NOTICE, Preferences.NOTICES.GM_AS_DM).observe(); const channelType = observeCurrentChannel(database).pipe(switchMap((c) => of$(c?.type))); const currentUserId = observeCurrentUserId(database); @@ -67,9 +30,7 @@ const enhanced = withObservables([], ({database, serverUrl}: EnhanceProps) => { return { channelId, - showJoinCallBanner, - isInACall, - showIncomingCalls, + ...observeCallStateInChannel(serverUrl, database, channelId), isCallsEnabledInChannel: observeIsCallsEnabledInChannel(database, serverUrl, channelId), dismissedGMasDMNotice, channelType, diff --git a/app/screens/home/channel_list/channel_list.tsx b/app/screens/home/channel_list/channel_list.tsx index 6a6248d4f..9baec4ae1 100644 --- a/app/screens/home/channel_list/channel_list.tsx +++ b/app/screens/home/channel_list/channel_list.tsx @@ -10,6 +10,7 @@ import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated'; import {type Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'; import {refetchCurrentUser} from '@actions/remote/user'; +import FloatingCallContainer from '@calls/components/floating_call_container'; import AnnouncementBanner from '@components/announcement_banner'; import ConnectionBanner from '@components/connection_banner'; import TeamSidebar from '@components/team_sidebar'; @@ -40,6 +41,7 @@ type ChannelProps = { coldStart?: boolean; currentUserId?: string; hasCurrentUser: boolean; + showIncomingCalls: boolean; }; const edges: Edge[] = ['bottom', 'left', 'right']; @@ -197,6 +199,12 @@ const ChannelListScreen = (props: ChannelProps) => { {isTablet && } + {props.showIncomingCalls && !isTablet && + + } diff --git a/app/screens/home/channel_list/index.ts b/app/screens/home/channel_list/index.ts index d8cfa54e3..9fd0bb259 100644 --- a/app/screens/home/channel_list/index.ts +++ b/app/screens/home/channel_list/index.ts @@ -6,6 +6,7 @@ import withObservables from '@nozbe/with-observables'; import {of as of$} from 'rxjs'; import {distinctUntilChanged, switchMap} from 'rxjs/operators'; +import {observeIncomingCalls} from '@calls/state'; import {queryAllMyChannelsForTeam} from '@queries/servers/channel'; import {observeCurrentTeamId, observeCurrentUserId, observeLicense} from '@queries/servers/system'; import {queryMyTeams} from '@queries/servers/team'; @@ -24,6 +25,11 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => { const teamsCount = queryMyTeams(database).observeCount(false); + const showIncomingCalls = observeIncomingCalls().pipe( + switchMap((ics) => of$(ics.incomingCalls.length > 0)), + distinctUntilChanged(), + ); + return { isCRTEnabled: observeIsCRTEnabled(database), hasTeams: teamsCount.pipe( @@ -46,6 +52,7 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => { switchMap((u) => of$(Boolean(u))), distinctUntilChanged(), ), + showIncomingCalls, }; }); diff --git a/app/screens/thread/index.tsx b/app/screens/thread/index.tsx index f2c6a4231..1c22a9cb0 100644 --- a/app/screens/thread/index.tsx +++ b/app/screens/thread/index.tsx @@ -3,9 +3,9 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; import withObservables from '@nozbe/with-observables'; -import {distinctUntilChanged, switchMap, combineLatest, of as of$} from 'rxjs'; +import {distinctUntilChanged, switchMap, of as of$} from 'rxjs'; -import {observeCallsState, observeChannelsWithCalls, observeCurrentCall, observeIncomingCalls} from '@calls/state'; +import {observeCallStateInChannel} from '@calls/observers'; import {withServerUrl} from '@context/server'; import {observePost} from '@queries/servers/post'; import {observeIsCRTEnabled} from '@queries/servers/thread'; @@ -28,41 +28,10 @@ const enhanced = withObservables(['rootId'], ({database, serverUrl, rootId}: Enh switchMap((r) => of$(r?.channelId || '')), distinctUntilChanged(), ); - const isCallInCurrentChannel = combineLatest([channelId, observeChannelsWithCalls(serverUrl)]).pipe( - switchMap(([id, calls]) => of$(Boolean(calls[id]))), - distinctUntilChanged(), - ); - const currentCall = observeCurrentCall(); - const ccChannelId = currentCall.pipe( - switchMap((call) => of$(call?.channelId)), - distinctUntilChanged(), - ); - const isInACall = currentCall.pipe( - switchMap((call) => of$(Boolean(call?.connected))), - distinctUntilChanged(), - ); - const dismissed = combineLatest([channelId, observeCallsState(serverUrl)]).pipe( - switchMap(([id, state]) => of$(Boolean(state.calls[id]?.dismissed[state.myUserId]))), - distinctUntilChanged(), - ); - const isInCurrentChannelCall = combineLatest([channelId, ccChannelId]).pipe( - switchMap(([id, ccId]) => of$(id === ccId)), - distinctUntilChanged(), - ); - const showJoinCallBanner = combineLatest([isCallInCurrentChannel, dismissed, isInCurrentChannelCall]).pipe( - switchMap(([isCall, dism, inCurrCall]) => of$(Boolean(isCall && !dism && !inCurrCall))), - distinctUntilChanged(), - ); - const showIncomingCalls = observeIncomingCalls().pipe( - switchMap((ics) => of$(ics.incomingCalls.length > 0)), - distinctUntilChanged(), - ); return { isCRTEnabled: observeIsCRTEnabled(database), - showJoinCallBanner, - isInACall, - showIncomingCalls, + ...observeCallStateInChannel(serverUrl, database, channelId), rootId: of$(rId), rootPost, };