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
This commit is contained in:
Christopher Poile 2022-03-29 10:54:29 -04:00 committed by GitHub
parent 87f891a457
commit 734675978d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 219 additions and 211 deletions

View file

@ -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};

View file

@ -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,
};
}

View file

@ -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 = (
<CallMessage
post={post}

View file

@ -808,118 +808,7 @@ exports[`ChannelItem should match snapshot for no displayName 1`] = `null`;
exports[`ChannelItem should match snapshot for showUnreadForMsgs 1`] = `null`;
exports[`ChannelItem should match snapshot when there is a call and but calls are disabled 1`] = `
<TouchableHighlight
onPress={[Function]}
underlayColor="rgba(40,66,123,0.5)"
>
<View
style={
Array [
Object {
"flex": 1,
"flexDirection": "row",
"height": 44,
},
undefined,
]
}
testID="main.sidebar.channels_list.list.channel_item"
>
<View
style={
Array [
Object {
"alignItems": "center",
"flex": 1,
"flexDirection": "row",
"paddingLeft": 16,
},
undefined,
]
}
testID="main.sidebar.channels_list.list.channel_item.channel_id"
>
<ChannelIcon
channelId="channel_id"
hasDraft={false}
isActive={false}
isArchived={false}
isInfo={false}
isUnread={true}
membersCount={1}
size={24}
statusStyle={
Object {
"backgroundColor": "#1e325c",
"borderColor": "transparent",
}
}
testID="main.sidebar.channels_list.list.channel_item.channel_icon"
theme={
Object {
"awayIndicator": "#ffbc1f",
"buttonBg": "#1c58d9",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3f4350",
"codeTheme": "github",
"dndIndicator": "#d24b4e",
"errorTextColor": "#d24b4e",
"linkColor": "#386fe5",
"mentionBg": "#ffffff",
"mentionColor": "#1e325c",
"mentionHighlightBg": "#ffd470",
"mentionHighlightLink": "#1b1d22",
"newMessageSeparator": "#cc8f00",
"onlineIndicator": "#3db887",
"sidebarBg": "#1e325c",
"sidebarHeaderBg": "#192a4d",
"sidebarHeaderTextColor": "#ffffff",
"sidebarTeamBarBg": "#14213e",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#5d89ea",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#28427b",
"sidebarUnreadText": "#ffffff",
"type": "Denim",
}
}
type="O"
/>
<Text
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"alignSelf": "center",
"color": "rgba(255,255,255,0.6)",
"fontFamily": "Open Sans",
"fontSize": 16,
"lineHeight": 24,
"marginLeft": 13,
"maxWidth": "80%",
"paddingRight": 10,
},
Object {
"color": "#ffffff",
"fontWeight": "500",
"maxWidth": "70%",
"opacity": 1,
},
]
}
testID="main.sidebar.channels_list.list.channel_item.display_name"
>
display_name
</Text>
</View>
</View>
</TouchableHighlight>
`;
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`] = `
<TouchableHighlight
onPress={[Function]}
underlayColor="rgba(40,66,123,0.5)"

View file

@ -43,7 +43,6 @@ export default class ChannelItem extends PureComponent {
viewingGlobalThreads: PropTypes.bool,
customStatusEnabled: PropTypes.bool.isRequired,
channelHasCall: PropTypes.bool.isRequired,
callsFeatureEnabled: PropTypes.bool.isRequired,
};
static defaultProps = {
@ -217,7 +216,7 @@ export default class ChannelItem extends PureComponent {
</Text>
{customStatus}
{badge}
{this.props.callsFeatureEnabled && this.props.channelHasCall &&
{this.props.channelHasCall &&
<CompassIcon
name='phone-in-talk'
size={16}

View file

@ -41,7 +41,6 @@ describe('ChannelItem', () => {
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(
<ChannelItem {...newProps}/>,
);
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,
};

View file

@ -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,
};
};
}

11
app/constants/calls.ts Normal file
View file

@ -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};

View file

@ -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 {

View file

@ -4,12 +4,25 @@
import type {ServerChannelState} from '@mmproducts/calls/store/types/calls';
export interface ClientCallsMix {
getEnabled: () => Promise<Boolean>;
getCalls: () => Promise<ServerChannelState[]>;
enableChannelCalls: (channelId: string) => Promise<ServerChannelState>;
disableChannelCalls: (channelId: string) => Promise<ServerChannelState>;
}
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`,

View file

@ -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',

View file

@ -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) => {
<ChannelInfoRow
testID={testID}
action={handleEnableDisableCalls}
defaultMessage={enabled ? 'Disable Calls' : 'Enable Calls'}
defaultMessage={(enabled ? 'Disable Calls' : 'Enable Calls') + msgPostfix}
icon='phone-outline'
theme={theme}
rightArrow={false}

View file

@ -1,16 +1,27 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import nock from 'nock';
import React from 'react';
import {Alert, TouchableHighlight} from 'react-native';
import {Client4} from '@client/rest';
import Preferences from '@mm-redux/constants/preferences';
import ChannelInfoRow from '@screens/channel_info/channel_info_row';
import {shallowWithIntl} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import StartCall from './start_call';
describe('StartCall', () => {
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(<StartCall {...props}/>).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(<StartCall {...props}/>).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(<StartCall {...props}/>).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();
});

View file

@ -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) => {
<ChannelInfoRow
testID={testID}
action={handleStartCall}
defaultMessage={ongoingCall ? 'Join Ongoing Call' : 'Start Call'}
defaultMessage={(ongoingCall ? 'Join Ongoing Call' : 'Start Call') + msgPostfix}
icon='phone-in-talk'
theme={theme}
rightArrow={false}

View file

@ -0,0 +1,35 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {useState} from 'react';
import {Alert} from 'react-native';
import {Client4} from '@client/rest';
// Check if calls is enabled. If it is, then run fn; if it isn't, show an alert and set
// msgPostfix to ' (Not Available)'.
export const useTryCallsFunction = (fn: (channelId: string) => 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];
};

View file

@ -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;
}

View file

@ -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}
<NetworkIndicator/>
<AnnouncementBanner/>
{callsFeatureEnabled &&
{isSupportedServerCalls &&
<FloatingCallContainer>
<JoinCall/>
<CurrentCall/>

View file

@ -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 {
<>
<AnnouncementBanner/>
<NetworkIndicator/>
{callsFeatureEnabled &&
{isSupportedServerCalls &&
<FloatingCallContainer>
<JoinCall/>
<CurrentCall/>

View file

@ -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();
}
}

View file

@ -28,7 +28,7 @@ describe('ChannelBase', () => {
componentId: channelBaseComponentId,
theme: Preferences.THEMES.denim,
collapsedThreadsEnabled: false,
callsFeatureEnabled: false,
isSupportedServerCalls: false,
};
const optionsForTheme = (theme) => {
return {

View file

@ -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,
};
}

View file

@ -614,7 +614,7 @@ exports[`channelInfo should match snapshot 1`] = `
</RNCSafeAreaView>
`;
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`] = `
<RNCSafeAreaView
edges={
Array [
@ -1301,7 +1301,7 @@ exports[`channelInfo should match snapshot on calls features enabled and calls d
</RNCSafeAreaView>
`;
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`] = `
<RNCSafeAreaView
edges={
Array [
@ -1988,7 +1988,7 @@ exports[`channelInfo should match snapshot on calls features enabled and calls e
</RNCSafeAreaView>
`;
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`] = `
<RNCSafeAreaView
edges={
Array [

View file

@ -60,7 +60,7 @@ export default class ChannelInfo extends PureComponent {
isCustomStatusExpirySupported: PropTypes.bool.isRequired,
isCallsEnabled: PropTypes.bool.isRequired,
isChannelAdmin: PropTypes.bool.isRequired,
callsFeatureEnabled: PropTypes.bool.isRequired,
isSupportedServerCalls: PropTypes.bool.isRequired,
};
static defaultProps = {
@ -117,7 +117,7 @@ export default class ChannelInfo extends PureComponent {
};
actionsRows = (channelIsArchived) => {
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 &&
<>
<StartCall
testID='channel_info.start_call.action'

View file

@ -62,7 +62,7 @@ describe('channelInfo', () => {
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(
<ChannelInfo
{...props}
@ -87,8 +87,8 @@ describe('channelInfo', () => {
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(
<ChannelInfo
{...props}
@ -98,8 +98,8 @@ describe('channelInfo', () => {
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(
<ChannelInfo
{...props}

View file

@ -9,13 +9,12 @@ import {getChannelStats} from '@mm-redux/actions/channels';
import {getCustomEmojisInText} from '@mm-redux/actions/emojis';
import {General} from '@mm-redux/constants';
import {getCurrentChannel, getCurrentChannelStats} from '@mm-redux/selectors/entities/channels';
import {getFeatureFlagValue} from '@mm-redux/selectors/entities/general';
import {getTeammateNameDisplaySetting, getTheme} from '@mm-redux/selectors/entities/preferences';
import {getCurrentUserRoles, getCurrentUserId, getUser} from '@mm-redux/selectors/entities/users';
import {getUserIdFromChannelName} from '@mm-redux/utils/channel_utils';
import {isAdmin as checkIsAdmin, isChannelAdmin as checkIsChannelAdmin, displayUsername} from '@mm-redux/utils/user_utils';
import {joinCall, enableChannelCalls, disableChannelCalls} from '@mmproducts/calls/store/actions/calls';
import {isCallsEnabled} from '@mmproducts/calls/store/selectors/calls';
import {isCallsEnabled, isSupportedServer} from '@mmproducts/calls/store/selectors/calls';
import {makeGetCustomStatus, isCustomStatusEnabled, isCustomStatusExpired, isCustomStatusExpirySupported} from '@selectors/custom_status';
import {isGuest} from '@utils/users';
@ -61,7 +60,7 @@ function makeMapStateToProps() {
currentChannelMemberCount = currentChannel.display_name.split(',').length;
}
const callsFeatureEnabled = getFeatureFlagValue(state, 'CallsMobile') === 'true';
const isSupportedServerCalls = isSupportedServer(state);
return {
currentChannel,
@ -79,7 +78,7 @@ function makeMapStateToProps() {
isCustomStatusExpired: customStatusExpired,
isCustomStatusExpirySupported: customStatusExpirySupported,
isCallsEnabled: isCallsEnabled(state),
callsFeatureEnabled,
isSupportedServerCalls,
isChannelAdmin,
};
};