From 734675978d4cc7514ecb8d9ea90e6e9fa4905b39 Mon Sep 17 00:00:00 2001 From: Christopher Poile Date: Tue, 29 Mar 2022 10:54:29 -0400 Subject: [PATCH] MM-42623 - Calls: remove Feature Flag (#6091) * removed CallsMobile feature flag; added server version check * added on-demand check and Alert for Calls enabled * merge with master * fix deps, typo, test snapshots --- app/actions/websocket/index.ts | 69 ++++++----- app/components/post_list/post/index.ts | 4 +- app/components/post_list/post/post.tsx | 5 +- .../__snapshots__/channel_item.test.js.snap | 113 +----------------- .../channel_item/channel_item.js | 3 +- .../channel_item/channel_item.test.js | 18 +-- .../main/channels_list/channel_item/index.js | 3 - app/constants/calls.ts | 11 ++ app/mm-redux/constants/posts.ts | 1 + app/products/calls/client/rest.ts | 13 ++ .../call_message/call_message.test.js | 3 +- .../calls/components/enable_disable_calls.tsx | 6 +- .../components/start_call/start_call.test.js | 65 +++++++++- .../components/start_call/start_call.tsx | 9 +- app/products/calls/hooks.ts | 35 ++++++ app/products/calls/store/selectors/calls.ts | 18 +++ app/screens/channel/channel.android.js | 4 +- app/screens/channel/channel.ios.js | 4 +- app/screens/channel/channel_base.js | 4 +- app/screens/channel/channel_base.test.js | 2 +- app/screens/channel/index.js | 7 +- .../__snapshots__/channel_info.test.js.snap | 6 +- app/screens/channel_info/channel_info.js | 6 +- app/screens/channel_info/channel_info.test.js | 14 +-- app/screens/channel_info/index.js | 7 +- 25 files changed, 219 insertions(+), 211 deletions(-) create mode 100644 app/constants/calls.ts create mode 100644 app/products/calls/hooks.ts diff --git a/app/actions/websocket/index.ts b/app/actions/websocket/index.ts index b17cc6522..f7128eb89 100644 --- a/app/actions/websocket/index.ts +++ b/app/actions/websocket/index.ts @@ -12,7 +12,7 @@ import {getThreads} from '@mm-redux/actions/threads'; import {getProfilesByIds, getStatusesByIds} from '@mm-redux/actions/users'; import {General} from '@mm-redux/constants'; import {getCurrentChannelId, getCurrentChannelStats} from '@mm-redux/selectors/entities/channels'; -import {getConfig, getFeatureFlagValue} from '@mm-redux/selectors/entities/general'; +import {getConfig} from '@mm-redux/selectors/entities/general'; import {getPostIdsInChannel} from '@mm-redux/selectors/entities/posts'; import {isCollapsedThreadsEnabled} from '@mm-redux/selectors/entities/preferences'; import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; @@ -38,6 +38,7 @@ import { handleCallScreenOn, handleCallScreenOff, handleCallUserRaiseHand, handleCallUserUnraiseHand, } from '@mmproducts/calls/store/actions/websockets'; +import {isSupportedServer} from '@mmproducts/calls/store/selectors/calls'; import {appsConfiguredAsEnabled} from '@utils/apps'; import {getChannelSinceValue} from '@utils/channels'; import {semverFromServerVersion} from '@utils/general'; @@ -152,6 +153,7 @@ export function doReconnect(now: number) { const currentChannelId = getCurrentChannelId(state); const currentUserId = getCurrentUserId(state); const users = getUsers(state); + const isSupportedServerCalls = isSupportedServer(state); const {lastDisconnectAt} = state.websocket; const actions: GenericAction[] = []; @@ -168,7 +170,7 @@ export function doReconnect(now: number) { const {data: me}: any = await dispatch(loadMe(null, null, true)); if (!me.error) { - if (getFeatureFlagValue(getState(), 'CallsMobile') === 'true') { + if (isSupportedServerCalls) { dispatch(loadCalls()); } @@ -448,40 +450,37 @@ function handleEvent(msg: WebSocketMessage) { return dispatch(handleSidebarCategoryDeleted(msg)); case WebsocketEvents.SIDEBAR_CATEGORY_ORDER_UPDATED: return dispatch(handleSidebarCategoryOrderUpdated(msg)); - } - if (getFeatureFlagValue(getState(), 'CallsMobile') === 'true') { - switch (msg.event) { - case WebsocketEvents.CALLS_CHANNEL_ENABLED: - return dispatch(handleCallChannelEnabled(msg)); - case WebsocketEvents.CALLS_CHANNEL_DISABLED: - return dispatch(handleCallChannelDisabled(msg)); - case WebsocketEvents.CALLS_USER_CONNECTED: - handleCallUserConnected(dispatch, getState, msg); - break; - case WebsocketEvents.CALLS_USER_DISCONNECTED: - return dispatch(handleCallUserDisconnected(msg)); - case WebsocketEvents.CALLS_USER_MUTED: - return dispatch(handleCallUserMuted(msg)); - case WebsocketEvents.CALLS_USER_UNMUTED: - return dispatch(handleCallUserUnmuted(msg)); - case WebsocketEvents.CALLS_USER_VOICE_ON: - handleCallUserVoiceOn(msg); - break; - case WebsocketEvents.CALLS_USER_VOICE_OFF: - handleCallUserVoiceOff(msg); - break; - case WebsocketEvents.CALLS_CALL_START: - return dispatch(handleCallStarted(msg)); - case WebsocketEvents.CALLS_SCREEN_ON: - return dispatch(handleCallScreenOn(msg)); - case WebsocketEvents.CALLS_SCREEN_OFF: - return dispatch(handleCallScreenOff(msg)); - case WebsocketEvents.CALLS_USER_RAISE_HAND: - return dispatch(handleCallUserRaiseHand(msg)); - case WebsocketEvents.CALLS_USER_UNRAISE_HAND: - return dispatch(handleCallUserUnraiseHand(msg)); - } + // Calls ws events: + case WebsocketEvents.CALLS_CHANNEL_ENABLED: + return dispatch(handleCallChannelEnabled(msg)); + case WebsocketEvents.CALLS_CHANNEL_DISABLED: + return dispatch(handleCallChannelDisabled(msg)); + case WebsocketEvents.CALLS_USER_CONNECTED: + handleCallUserConnected(dispatch, getState, msg); + break; + case WebsocketEvents.CALLS_USER_DISCONNECTED: + return dispatch(handleCallUserDisconnected(msg)); + case WebsocketEvents.CALLS_USER_MUTED: + return dispatch(handleCallUserMuted(msg)); + case WebsocketEvents.CALLS_USER_UNMUTED: + return dispatch(handleCallUserUnmuted(msg)); + case WebsocketEvents.CALLS_USER_VOICE_ON: + handleCallUserVoiceOn(msg); + break; + case WebsocketEvents.CALLS_USER_VOICE_OFF: + handleCallUserVoiceOff(msg); + break; + case WebsocketEvents.CALLS_CALL_START: + return dispatch(handleCallStarted(msg)); + case WebsocketEvents.CALLS_SCREEN_ON: + return dispatch(handleCallScreenOn(msg)); + case WebsocketEvents.CALLS_SCREEN_OFF: + return dispatch(handleCallScreenOff(msg)); + case WebsocketEvents.CALLS_USER_RAISE_HAND: + return dispatch(handleCallUserRaiseHand(msg)); + case WebsocketEvents.CALLS_USER_UNRAISE_HAND: + return dispatch(handleCallUserUnraiseHand(msg)); } return {data: true}; diff --git a/app/components/post_list/post/index.ts b/app/components/post_list/post/index.ts index 4e90b6ec1..de5f85ac8 100644 --- a/app/components/post_list/post/index.ts +++ b/app/components/post_list/post/index.ts @@ -7,7 +7,7 @@ import {showPermalink} from '@actions/views/permalink'; import {THREAD} from '@constants/screen'; import {removePost} from '@mm-redux/actions/posts'; import {getChannel} from '@mm-redux/selectors/entities/channels'; -import {getConfig, getFeatureFlagValue} from '@mm-redux/selectors/entities/general'; +import {getConfig} from '@mm-redux/selectors/entities/general'; import {getPost, isRootPost} from '@mm-redux/selectors/entities/posts'; import {getMyPreferences, getTeammateNameDisplaySetting, isCollapsedThreadsEnabled} from '@mm-redux/selectors/entities/preferences'; import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; @@ -49,7 +49,6 @@ function mapSateToProps(state: GlobalState, ownProps: OwnProps) { const teammateNameDisplay = getTeammateNameDisplaySetting(state); const enablePostUsernameOverride = config.EnablePostUsernameOverride === 'true'; const isConsecutivePost = post && previousPost && !author?.is_bot && !isRootPost(state, post.id) && areConsecutivePosts(post, previousPost); - const callsFeatureEnabled = getFeatureFlagValue(state, 'CallsMobile') === 'true'; let isFirstReply = true; let isLastReply = true; let canDelete = false; @@ -98,7 +97,6 @@ function mapSateToProps(state: GlobalState, ownProps: OwnProps) { teammateNameDisplay, thread, threadStarter: getUser(state, post.user_id), - callsFeatureEnabled, }; } diff --git a/app/components/post_list/post/post.tsx b/app/components/post_list/post/post.tsx index 5b99657ff..fd42708e0 100644 --- a/app/components/post_list/post/post.tsx +++ b/app/components/post_list/post/post.tsx @@ -55,7 +55,6 @@ type PostProps = { theme: Theme; thread: UserThread; threadStarter: UserProfile; - callsFeatureEnabled: boolean; }; const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { @@ -115,7 +114,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { const Post = ({ canDelete, collapsedThreadsEnabled, enablePostUsernameOverride, highlight, highlightPinnedOrFlagged = true, intl, isConsecutivePost, isFirstReply, isFlagged, isLastReply, location, post, removePost, rootPostAuthor, shouldRenderReplyButton, skipFlaggedHeader, skipPinnedHeader, showAddReaction = true, showPermalink, style, - teammateNameDisplay, testID, theme, thread, threadStarter, callsFeatureEnabled, + teammateNameDisplay, testID, theme, thread, threadStarter, }: PostProps) => { const pressDetected = useRef(false); const styles = getStyleSheet(theme); @@ -241,7 +240,7 @@ const Post = ({ theme={theme} /> ); - } else if (post.type === 'custom_calls' && callsFeatureEnabled) { + } else if (post.type === Posts.POST_TYPES.CUSTOM_CALLS) { body = ( - - - - - display_name - - - - -`; - -exports[`ChannelItem should match snapshot when there is a call and calls are enabled 1`] = ` +exports[`ChannelItem should match snapshot when there is a call 1`] = ` {customStatus} {badge} - {this.props.callsFeatureEnabled && this.props.channelHasCall && + {this.props.channelHasCall && { isBot: false, customStatusEnabled: true, channelHasCall: false, - callsFeatureEnabled: false, }; test('should match snapshot', () => { @@ -52,24 +51,9 @@ describe('ChannelItem', () => { expect(wrapper.getElement()).toMatchSnapshot(); }); - test('should match snapshot when there is a call and calls are enabled', () => { + test('should match snapshot when there is a call', () => { const newProps = { ...baseProps, - callsFeatureEnabled: true, - channelHasCall: true, - }; - - const wrapper = shallowWithIntl( - , - ); - - expect(wrapper.getElement()).toMatchSnapshot(); - }); - - test('should match snapshot when there is a call and but calls are disabled', () => { - const newProps = { - ...baseProps, - callsFeatureEnabled: false, channelHasCall: true, }; diff --git a/app/components/sidebars/main/channels_list/channel_item/index.js b/app/components/sidebars/main/channels_list/channel_item/index.js index 56b0494ab..95c69f2a6 100644 --- a/app/components/sidebars/main/channels_list/channel_item/index.js +++ b/app/components/sidebars/main/channels_list/channel_item/index.js @@ -11,7 +11,6 @@ import { makeGetChannel, shouldHideDefaultChannel, } from '@mm-redux/selectors/entities/channels'; -import {getFeatureFlagValue} from '@mm-redux/selectors/entities/general'; import {getTheme, getTeammateNameDisplaySetting, isCollapsedThreadsEnabled} from '@mm-redux/selectors/entities/preferences'; import {getCurrentUserId, getUser} from '@mm-redux/selectors/entities/users'; import {getMsgCountInChannel, getUserIdFromChannelName, isChannelMuted} from '@mm-redux/utils/channel_utils'; @@ -75,7 +74,6 @@ function makeMapStateToProps() { if (member && member.notify_props) { showUnreadForMsgs = member.notify_props.mark_unread !== General.MENTION; } - const callsFeatureEnabled = getFeatureFlagValue(state, 'CallsMobile') === 'true'; const viewingGlobalThreads = getViewingGlobalThreads(state); return { @@ -97,7 +95,6 @@ function makeMapStateToProps() { viewingGlobalThreads, customStatusEnabled: isCustomStatusEnabled(state), channelHasCall, - callsFeatureEnabled, }; }; } diff --git a/app/constants/calls.ts b/app/constants/calls.ts new file mode 100644 index 000000000..4db3f64f4 --- /dev/null +++ b/app/constants/calls.ts @@ -0,0 +1,11 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +const RequiredServer = { + FULL_VERSION: '6.3.0', + MAJOR_VERSION: 6, + MIN_VERSION: 3, + PATCH_VERSION: 0, +}; + +export default {RequiredServer}; diff --git a/app/mm-redux/constants/posts.ts b/app/mm-redux/constants/posts.ts index 921085eb1..dffb3d864 100644 --- a/app/mm-redux/constants/posts.ts +++ b/app/mm-redux/constants/posts.ts @@ -28,6 +28,7 @@ export const PostTypes = { COMBINED_USER_ACTIVITY: 'system_combined_user_activity', ME: 'me', ADD_BOT_TEAMS_CHANNELS: 'add_bot_teams_channels', + CUSTOM_CALLS: 'custom_calls', }; export default { diff --git a/app/products/calls/client/rest.ts b/app/products/calls/client/rest.ts index cbecb6054..a2d02de67 100644 --- a/app/products/calls/client/rest.ts +++ b/app/products/calls/client/rest.ts @@ -4,12 +4,25 @@ import type {ServerChannelState} from '@mmproducts/calls/store/types/calls'; export interface ClientCallsMix { + getEnabled: () => Promise; getCalls: () => Promise; enableChannelCalls: (channelId: string) => Promise; disableChannelCalls: (channelId: string) => Promise; } const ClientCalls = (superclass: any) => class extends superclass { + getEnabled = async () => { + try { + await this.doFetch( + `${this.getCallsRoute()}/version`, + {method: 'get'}, + ); + return true; + } catch (e) { + return false; + } + }; + getCalls = async () => { return this.doFetch( `${this.getCallsRoute()}/channels`, diff --git a/app/products/calls/components/call_message/call_message.test.js b/app/products/calls/components/call_message/call_message.test.js index 35b192410..7c1695c27 100644 --- a/app/products/calls/components/call_message/call_message.test.js +++ b/app/products/calls/components/call_message/call_message.test.js @@ -4,6 +4,7 @@ import React from 'react'; import {Alert, TouchableOpacity} from 'react-native'; +import {Posts} from '@mm-redux/constants'; import Preferences from '@mm-redux/constants/preferences'; import {shallowWithIntl} from '@test/intl-test-helper'; @@ -19,7 +20,7 @@ describe('CallMessage', () => { props: { start_at: 100, }, - type: 'custom_calls', + type: Posts.POST_TYPES.CUSTOM_CALLS, }, user: { id: 'user-1-id', diff --git a/app/products/calls/components/enable_disable_calls.tsx b/app/products/calls/components/enable_disable_calls.tsx index 31548f805..a17e7f79c 100644 --- a/app/products/calls/components/enable_disable_calls.tsx +++ b/app/products/calls/components/enable_disable_calls.tsx @@ -4,6 +4,7 @@ import React, {useCallback} from 'react'; import {Theme} from '@mm-redux/types/theme'; +import {useTryCallsFunction} from '@mmproducts/calls/hooks'; import ChannelInfoRow from '@screens/channel_info/channel_info_row'; import Separator from '@screens/channel_info/separator'; import {preventDoubleTap} from '@utils/tap'; @@ -19,7 +20,8 @@ type Props = { const EnableDisableCalls = (props: Props) => { const {testID, canEnableDisableCalls, theme, onPress, enabled} = props; - const handleEnableDisableCalls = useCallback(preventDoubleTap(onPress), [onPress]); + const [tryOnPress, msgPostfix] = useTryCallsFunction(onPress); + const handleEnableDisableCalls = useCallback(preventDoubleTap(tryOnPress), [tryOnPress]); if (!canEnableDisableCalls) { return null; @@ -31,7 +33,7 @@ const EnableDisableCalls = (props: Props) => { { + beforeAll(async () => { + await TestHelper.initBasic(Client4); + }); + + afterAll(async () => { + await TestHelper.tearDown(); + }); + const baseProps = { actions: { joinCall: jest.fn(), @@ -53,22 +64,70 @@ describe('StartCall', () => { expect(wrapper.getElement()).toBeNull(); }); - test('should join on click', () => { + test('should start on click when calls is enabled', async () => { + nock(Client4.getCallsRoute()). + get('/version'). + times(2). + reply(200, {version: 1, build: 2}); const joinCall = jest.fn(); const props = {...baseProps, actions: {joinCall}}; const wrapper = shallowWithIntl().dive(); - wrapper.find(ChannelInfoRow).dive().find(TouchableHighlight).simulate('press'); + + // This is so that the awaited call within ClientCalls in products/calls/client/rest.ts has + // a chance to be completed by nock: + await Client4.doFetch( + `${Client4.getUrl()}/plugins/com.mattermost.calls/version`, + {method: 'get'}, + ); + expect(Alert.alert).not.toHaveBeenCalled(); expect(props.actions.joinCall).toHaveBeenCalled(); }); - test('should ask for confirmation on click', () => { + test('should not start on click and should show alert when calls is not enabled', async () => { + nock(Client4.getCallsRoute()). + get('/version'). + times(2). + reply(404); + const joinCall = jest.fn(); + const props = {...baseProps, actions: {joinCall}}; + const wrapper = shallowWithIntl().dive(); + wrapper.find(ChannelInfoRow).dive().find(TouchableHighlight).simulate('press'); + + // This is so that the awaited call within ClientCalls in products/calls/client/rest.ts has + // a chance to be completed by nock: + try { + await Client4.doFetch( + `${Client4.getUrl()}/plugins/com.mattermost.calls/version`, + {method: 'get'}, + ); + } catch (e) { + // expected + } + + expect(Alert.alert).toHaveBeenCalled(); + expect(props.actions.joinCall).not.toHaveBeenCalled(); + }); + + test('should ask for confirmation on click', async () => { + nock(Client4.getCallsRoute()). + get('/version'). + times(2). + reply(200, {version: 1, build: 2}); const joinCall = jest.fn(); const props = {...baseProps, confirmToJoin: true, actions: {joinCall}}; const wrapper = shallowWithIntl().dive(); wrapper.find(ChannelInfoRow).dive().find(TouchableHighlight).simulate('press'); + + // This is so that the awaited call within ClientCalls in products/calls/client/rest.ts has + // a chance to be completed by nock: + await Client4.doFetch( + `${Client4.getUrl()}/plugins/com.mattermost.calls/version`, + {method: 'get'}, + ); + expect(Alert.alert).toHaveBeenCalled(); expect(props.actions.joinCall).not.toHaveBeenCalled(); }); diff --git a/app/products/calls/components/start_call/start_call.tsx b/app/products/calls/components/start_call/start_call.tsx index f84450310..249bdd4da 100644 --- a/app/products/calls/components/start_call/start_call.tsx +++ b/app/products/calls/components/start_call/start_call.tsx @@ -6,6 +6,7 @@ import {injectIntl, IntlShape} from 'react-intl'; import {Theme} from '@mm-redux/types/theme'; import leaveAndJoinWithAlert from '@mmproducts/calls/components/leave_and_join_alert'; +import {useTryCallsFunction} from '@mmproducts/calls/hooks'; import ChannelInfoRow from '@screens/channel_info/channel_info_row'; import Separator from '@screens/channel_info/separator'; import {preventDoubleTap} from '@utils/tap'; @@ -29,9 +30,11 @@ type Props = { const StartCall = (props: Props) => { const {testID, canStartCall, theme, actions, currentChannelId, callChannelName, currentChannelName, confirmToJoin, alreadyInTheCall, ongoingCall, intl} = props; - const handleStartCall = useCallback(preventDoubleTap(() => { + const leaveAndJoin = useCallback(() => { leaveAndJoinWithAlert(intl, currentChannelId, callChannelName, currentChannelName, confirmToJoin, actions.joinCall); - }), [actions.joinCall, currentChannelId]); + }, [intl, currentChannelId, callChannelName, currentChannelName, confirmToJoin, actions.joinCall]); + const [tryLeaveAndJoin, msgPostfix] = useTryCallsFunction(leaveAndJoin); + const handleStartCall = useCallback(preventDoubleTap(tryLeaveAndJoin), [tryLeaveAndJoin]); if (!canStartCall) { return null; @@ -47,7 +50,7 @@ const StartCall = (props: Props) => { void) => { + const [msgPostfix, setMsgPostfix] = useState(''); + + const tryFn = async (channelId: string) => { + if (await Client4.getEnabled()) { + setMsgPostfix(''); + fn(channelId); + return; + } + + Alert.alert( + 'Calls is not enabled', + 'Please contact your system administrator to enable the feature.', + [ + { + text: 'OK', + style: 'cancel', + }, + ], + ); + setMsgPostfix(' (Not Available)'); + }; + + return [tryFn, msgPostfix]; +}; diff --git a/app/products/calls/store/selectors/calls.ts b/app/products/calls/store/selectors/calls.ts index 09d3312b2..9df97fcf3 100644 --- a/app/products/calls/store/selectors/calls.ts +++ b/app/products/calls/store/selectors/calls.ts @@ -1,8 +1,12 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import {Client4} from '@client/rest'; +import Calls from '@constants/calls'; import {getCurrentChannelId} from '@mm-redux/selectors/entities/common'; +import {getServerVersion} from '@mm-redux/selectors/entities/general'; import {GlobalState} from '@mm-redux/types/store'; +import {isMinimumServerVersion} from '@mm-redux/utils/helpers'; export function getCalls(state: GlobalState) { return state.entities.calls.calls; @@ -27,3 +31,17 @@ export function getScreenShareURL(state: GlobalState) { export function isSpeakerphoneOn(state: GlobalState) { return state.entities.calls.speakerphoneOn; } + +export function isSupportedServer(state: GlobalState) { + const serverVersion = Client4.getServerVersion() || getServerVersion(state); + if (serverVersion) { + return isMinimumServerVersion( + serverVersion, + Calls.RequiredServer.MAJOR_VERSION, + Calls.RequiredServer.MIN_VERSION, + Calls.RequiredServer.PATCH_VERSION, + ); + } + + return false; +} diff --git a/app/screens/channel/channel.android.js b/app/screens/channel/channel.android.js index 8ecd5181c..716f33c19 100644 --- a/app/screens/channel/channel.android.js +++ b/app/screens/channel/channel.android.js @@ -64,7 +64,7 @@ export default class ChannelAndroid extends ChannelBase { } render() { - const {theme, viewingGlobalThreads, callsFeatureEnabled} = this.props; + const {theme, viewingGlobalThreads, isSupportedServerCalls} = this.props; let component; if (viewingGlobalThreads) { @@ -106,7 +106,7 @@ export default class ChannelAndroid extends ChannelBase { {component} - {callsFeatureEnabled && + {isSupportedServerCalls && diff --git a/app/screens/channel/channel.ios.js b/app/screens/channel/channel.ios.js index 09a72354d..fe98abf08 100644 --- a/app/screens/channel/channel.ios.js +++ b/app/screens/channel/channel.ios.js @@ -57,7 +57,7 @@ export default class ChannelIOS extends ChannelBase { }; render() { - const {currentChannelId, theme, viewingGlobalThreads, callsFeatureEnabled} = this.props; + const {currentChannelId, theme, viewingGlobalThreads, isSupportedServerCalls} = this.props; let component; let renderDraftArea = false; @@ -85,7 +85,7 @@ export default class ChannelIOS extends ChannelBase { <> - {callsFeatureEnabled && + {isSupportedServerCalls && diff --git a/app/screens/channel/channel_base.js b/app/screens/channel/channel_base.js index 528e6d2b1..5d19dfa4d 100644 --- a/app/screens/channel/channel_base.js +++ b/app/screens/channel/channel_base.js @@ -39,7 +39,7 @@ export default class ChannelBase extends PureComponent { skipMetrics: PropTypes.bool, viewingGlobalThreads: PropTypes.bool, collapsedThreadsEnabled: PropTypes.bool.isRequired, - callsFeatureEnabled: PropTypes.bool.isRequired, + isSupportedServerCalls: PropTypes.bool.isRequired, selectedPost: PropTypes.shape({ id: PropTypes.string.isRequired, channel_id: PropTypes.string.isRequired, @@ -105,7 +105,7 @@ export default class ChannelBase extends PureComponent { unsupportedServer(isSystemAdmin, this.context.intl.formatMessage); } - if (this.props.callsFeatureEnabled) { + if (this.props.isSupportedServerCalls) { this.props.actions.loadCalls(); } } diff --git a/app/screens/channel/channel_base.test.js b/app/screens/channel/channel_base.test.js index fb84f31d6..d2e4d73c7 100644 --- a/app/screens/channel/channel_base.test.js +++ b/app/screens/channel/channel_base.test.js @@ -28,7 +28,7 @@ describe('ChannelBase', () => { componentId: channelBaseComponentId, theme: Preferences.THEMES.denim, collapsedThreadsEnabled: false, - callsFeatureEnabled: false, + isSupportedServerCalls: false, }; const optionsForTheme = (theme) => { return { diff --git a/app/screens/channel/index.js b/app/screens/channel/index.js index c8a2a841c..7acdb5c7e 100644 --- a/app/screens/channel/index.js +++ b/app/screens/channel/index.js @@ -10,7 +10,7 @@ import {Client4} from '@client/rest'; import {ViewTypes} from '@constants'; import {getChannelStats} from '@mm-redux/actions/channels'; import {getCurrentChannelId} from '@mm-redux/selectors/entities/channels'; -import {getServerVersion, getFeatureFlagValue} from '@mm-redux/selectors/entities/general'; +import {getServerVersion} from '@mm-redux/selectors/entities/general'; import {getSelectedPost} from '@mm-redux/selectors/entities/posts'; import {getTheme, isCollapsedThreadsEnabled} from '@mm-redux/selectors/entities/preferences'; import {getCurrentTeam} from '@mm-redux/selectors/entities/teams'; @@ -18,6 +18,7 @@ import {getCurrentUserId, getCurrentUserRoles, shouldShowTermsOfService} from '@ import {isMinimumServerVersion} from '@mm-redux/utils/helpers'; import {isSystemAdmin as checkIsSystemAdmin} from '@mm-redux/utils/user_utils'; import {loadCalls} from '@mmproducts/calls/store/actions/calls'; +import {isSupportedServer as isSupportedServerForCalls} from '@mmproducts/calls/store/selectors/calls'; import {getViewingGlobalThreads} from '@selectors/threads'; import Channel from './channel'; @@ -42,7 +43,7 @@ function mapStateToProps(state) { const currentTeamId = currentTeam?.delete_at === 0 ? currentTeam?.id : ''; const currentChannelId = currentTeam?.delete_at === 0 ? getCurrentChannelId(state) : ''; const collapsedThreadsEnabled = isCollapsedThreadsEnabled(state); - const callsFeatureEnabled = getFeatureFlagValue(state, 'CallsMobile') === 'true'; + const isSupportedServerCalls = isSupportedServerForCalls(state); return { currentChannelId, @@ -56,7 +57,7 @@ function mapStateToProps(state) { teamName: currentTeam?.display_name, theme: getTheme(state), viewingGlobalThreads: collapsedThreadsEnabled && getViewingGlobalThreads(state), - callsFeatureEnabled, + isSupportedServerCalls, }; } diff --git a/app/screens/channel_info/__snapshots__/channel_info.test.js.snap b/app/screens/channel_info/__snapshots__/channel_info.test.js.snap index 22cf91134..2f5c7eb45 100644 --- a/app/screens/channel_info/__snapshots__/channel_info.test.js.snap +++ b/app/screens/channel_info/__snapshots__/channel_info.test.js.snap @@ -614,7 +614,7 @@ exports[`channelInfo should match snapshot 1`] = ` `; -exports[`channelInfo should match snapshot on calls features enabled and calls disabled for channel 1`] = ` +exports[`channelInfo should match snapshot on calls supported and calls disabled for channel 1`] = ` `; -exports[`channelInfo should match snapshot on calls features enabled and calls enabled for channel 1`] = ` +exports[`channelInfo should match snapshot on calls supported and calls enabled for channel 1`] = ` `; -exports[`channelInfo should match snapshot on calls features enabled, user is not admin and calls disabled for channel 1`] = ` +exports[`channelInfo should match snapshot on calls supported, user is not admin and calls disabled for channel 1`] = ` { - const {currentChannel, currentUserId, isDirectMessage, isGroupMessage, theme, isCallsEnabled, callsFeatureEnabled, isChannelAdmin} = this.props; + const {currentChannel, currentUserId, isDirectMessage, isGroupMessage, theme, isCallsEnabled, isSupportedServerCalls, isChannelAdmin} = this.props; if (channelIsArchived) { return ( @@ -178,7 +178,7 @@ export default class ChannelInfo extends PureComponent { testID='channel_info.edit_channel.action' theme={theme} /> - {callsFeatureEnabled && + {isSupportedServerCalls && <> { disableChannelCalls: jest.fn(), }, isCallsEnabled: false, - callsFeatureEnabled: false, + isSupportedServerCalls: false, isChannelAdmin: false, }; @@ -76,8 +76,8 @@ describe('channelInfo', () => { expect(wrapper.getElement()).toMatchSnapshot(); }); - test('should match snapshot on calls features enabled, user is not admin and calls disabled for channel', async () => { - const props = {...baseProps, isCallsEnabled: false, callsFeatureEnabled: true, isChannelAdmin: false}; + test('should match snapshot on calls supported, user is not admin and calls disabled for channel', async () => { + const props = {...baseProps, isCallsEnabled: false, isSupportedServerCalls: true, isChannelAdmin: false}; const wrapper = shallow( { expect(wrapper.getElement()).toMatchSnapshot(); }); - test('should match snapshot on calls features enabled and calls disabled for channel', async () => { - const props = {...baseProps, isCallsEnabled: false, callsFeatureEnabled: true, isChannelAdmin: true}; + test('should match snapshot on calls supported and calls disabled for channel', async () => { + const props = {...baseProps, isCallsEnabled: false, isSupportedServerCalls: true, isChannelAdmin: true}; const wrapper = shallow( { expect(wrapper.getElement()).toMatchSnapshot(); }); - test('should match snapshot on calls features enabled and calls enabled for channel', async () => { - const props = {...baseProps, isCallsEnabled: true, callsFeatureEnabled: true, isChannelAdmin: true}; + test('should match snapshot on calls supported and calls enabled for channel', async () => { + const props = {...baseProps, isCallsEnabled: true, isSupportedServerCalls: true, isChannelAdmin: true}; const wrapper = shallow(