[MM-57781] Limit group calls to DMs only on unlicensed servers (#8075) (#8145)

* Limit group calls to DMs only on unlicensed servers

* Update calls-common

(cherry picked from commit 4e4bd8fe27)

Co-authored-by: Claudio Costa <cstcld91@gmail.com>
This commit is contained in:
Mattermost Build 2024-08-13 09:48:27 +03:00 committed by GitHub
parent 446e720124
commit cb6f22e5b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 60 additions and 11 deletions

View file

@ -166,7 +166,7 @@ export default function SendHandler({
const sendCommand = useCallback(async () => {
if (value.trim().startsWith('/call')) {
const {handled, error} = await handleCallsSlashCommand(value.trim(), serverUrl, channelId, rootId, currentUserId, intl);
const {handled, error} = await handleCallsSlashCommand(value.trim(), serverUrl, channelId, channelType ?? '', rootId, currentUserId, intl);
if (handled) {
setSendingMessage(false);
clearDraft();

View file

@ -30,6 +30,7 @@ import {
setSpeakerPhone,
} from '@calls/state';
import {type AudioDevice, type Call, type CallSession, type CallsConnection, EndCallReturn} from '@calls/types/calls';
import {areGroupCallsAllowed} from '@calls/utils';
import {General, Preferences} from '@constants';
import Calls from '@constants/calls';
import DatabaseManager from '@database/manager';
@ -493,7 +494,7 @@ export const dismissIncomingCall = async (serverUrl: string, channelId: string)
};
// handleCallsSlashCommand will return true if the slash command was handled
export const handleCallsSlashCommand = async (value: string, serverUrl: string, channelId: string, rootId: string, currentUserId: string, intl: IntlShape):
export const handleCallsSlashCommand = async (value: string, serverUrl: string, channelId: string, channelType: string, rootId: string, currentUserId: string, intl: IntlShape):
Promise<{ handled?: boolean; error?: string }> => {
const tokens = value.split(' ');
if (tokens.length < 2 || tokens[0] !== '/call') {
@ -505,6 +506,15 @@ export const handleCallsSlashCommand = async (value: string, serverUrl: string,
await handleEndCall(serverUrl, channelId, currentUserId, intl);
return {handled: true};
case 'start': {
if (!areGroupCallsAllowed(getCallsConfig(serverUrl)) && channelType !== General.DM_CHANNEL) {
return {
error: intl.formatMessage({
id: 'mobile.calls_group_calls_not_available',
defaultMessage: 'Calls are only available in DM channels.',
}),
};
}
if (getChannelsWithCalls(serverUrl)[channelId]) {
return {
error: intl.formatMessage({
@ -518,6 +528,15 @@ export const handleCallsSlashCommand = async (value: string, serverUrl: string,
return {handled: true};
}
case 'join': {
if (!areGroupCallsAllowed(getCallsConfig(serverUrl)) && channelType !== General.DM_CHANNEL) {
return {
error: intl.formatMessage({
id: 'mobile.calls_group_calls_not_available',
defaultMessage: 'Calls are only available in DM channels.',
}),
};
}
const title = tokens.length > 2 ? tokens.slice(2).join(' ') : undefined;
await leaveAndJoinWithAlert(intl, serverUrl, channelId, title, rootId);
return {handled: true};

View file

@ -177,6 +177,7 @@ export const DefaultCallsConfig: CallsConfigState = {
HostControlsAllowed: false,
EnableAV1: false,
TranscribeAPI: TranscribeAPI.WhisperCPP,
GroupCallsAllowed: true, // Set to true to keep backward compatibility with older servers.
};
export type ApiResp = {

View file

@ -108,6 +108,10 @@ export function isHostControlsAllowed(config: CallsConfigState) {
return Boolean(config.HostControlsAllowed);
}
export function areGroupCallsAllowed(config: CallsConfigState) {
return Boolean(config.GroupCallsAllowed);
}
export function isCallsCustomMessage(post: PostModel | Post): boolean {
return Boolean(post.type && post.type === Post.POST_TYPES.CUSTOM_CALLS);
}

View file

@ -34,6 +34,7 @@ type ChannelProps = {
showJoinCallBanner: boolean;
isInACall: boolean;
isCallsEnabledInChannel: boolean;
groupCallsAllowed: boolean;
showIncomingCalls: boolean;
isTabletView?: boolean;
dismissedGMasDMNotice: PreferenceModel[];
@ -58,6 +59,7 @@ const Channel = ({
showJoinCallBanner,
isInACall,
isCallsEnabledInChannel,
groupCallsAllowed,
showIncomingCalls,
isTabletView,
dismissedGMasDMNotice,
@ -125,6 +127,7 @@ const Channel = ({
channelId={channelId}
componentId={componentId}
callsEnabledInChannel={isCallsEnabledInChannel}
groupCallsAllowed={groupCallsAllowed}
isTabletView={isTabletView}
shouldRenderBookmarks={shouldRender}
/>

View file

@ -46,6 +46,7 @@ type ChannelProps = {
searchTerm: string;
teamId: string;
callsEnabledInChannel: boolean;
groupCallsAllowed: boolean;
isTabletView?: boolean;
shouldRenderBookmarks: boolean;
};
@ -78,7 +79,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
const ChannelHeader = ({
canAddBookmarks, channelId, channelType, componentId, customStatus, displayName, hasBookmarks,
isBookmarksEnabled, isCustomStatusEnabled, isCustomStatusExpired, isOwnDirectMessage, memberCount,
searchTerm, teamId, callsEnabledInChannel, isTabletView, shouldRenderBookmarks,
searchTerm, teamId, callsEnabledInChannel, groupCallsAllowed, isTabletView, shouldRenderBookmarks,
}: ChannelProps) => {
const intl = useIntl();
const isTablet = useIsTablet();
@ -89,7 +90,10 @@ const ChannelHeader = ({
// NOTE: callsEnabledInChannel will be true/false (not undefined) based on explicit state + the DefaultEnabled system setting
// which ultimately comes from channel/index.tsx, and observeIsCallsEnabledInChannel
const callsAvailable = callsEnabledInChannel;
let callsAvailable = callsEnabledInChannel;
if (!groupCallsAllowed && channelType !== General.DM_CHANNEL) {
callsAvailable = false;
}
const isDMorGM = isTypeDMorGM(channelType);
const contextStyle = useMemo(() => ({

View file

@ -5,6 +5,7 @@ import {withDatabase, withObservables} from '@nozbe/watermelondb/react';
import {combineLatestWith, distinctUntilChanged, of as of$, switchMap} from 'rxjs';
import {observeCallStateInChannel, observeIsCallsEnabledInChannel} from '@calls/observers';
import {observeCallsConfig} from '@calls/state';
import {Preferences} from '@constants';
import {withServerUrl} from '@context/server';
import {observeCurrentChannel} from '@queries/servers/channel';
@ -43,10 +44,16 @@ const enhanced = withObservables([], ({database, serverUrl}: EnhanceProps) => {
}),
);
const groupCallsAllowed = observeCallsConfig(serverUrl).pipe(
switchMap((config) => of$(config.GroupCallsAllowed)),
distinctUntilChanged(),
);
return {
channelId,
...observeCallStateInChannel(serverUrl, database, channelId),
isCallsEnabledInChannel: observeIsCallsEnabledInChannel(database, serverUrl, channelId),
groupCallsAllowed,
dismissedGMasDMNotice,
channelType,
currentUserId,

View file

@ -28,13 +28,14 @@ import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
canAddBookmarks: boolean;
canEnableDisableCalls: boolean;
canManageMembers: boolean;
canManageSettings: boolean;
channelId: string;
closeButtonId: string;
componentId: AvailableScreens;
isBookmarksEnabled: boolean;
isCallsEnabledInChannel: boolean;
groupCallsAllowed: boolean;
canManageMembers: boolean;
isConvertGMFeatureAvailable: boolean;
isCRTEnabled: boolean;
isGuestUser: boolean;
@ -68,6 +69,7 @@ const ChannelInfo = ({
componentId,
isBookmarksEnabled,
isCallsEnabledInChannel,
groupCallsAllowed,
isConvertGMFeatureAvailable,
isCRTEnabled,
isGuestUser,
@ -79,7 +81,10 @@ const ChannelInfo = ({
// NOTE: isCallsEnabledInChannel will be true/false (not undefined) based on explicit state + the DefaultEnabled system setting
// which comes from observeIsCallsEnabledInChannel
const callsAvailable = isCallsEnabledInChannel;
let callsAvailable = isCallsEnabledInChannel;
if (!groupCallsAllowed && type !== General.DM_CHANNEL) {
callsAvailable = false;
}
const onPressed = useCallback(() => {
return dismissModal({componentId});

View file

@ -102,6 +102,10 @@ const enhanced = withObservables([], ({serverUrl, database}: Props) => {
}),
);
const isCallsEnabledInChannel = observeIsCallsEnabledInChannel(database, serverUrl, observeCurrentChannelId(database));
const groupCallsAllowed = observeCallsConfig(serverUrl).pipe(
switchMap((config) => of$(config.GroupCallsAllowed)),
distinctUntilChanged(),
);
const canManageMembers = currentUser.pipe(
combineLatestWith(channelId),
@ -135,11 +139,12 @@ const enhanced = withObservables([], ({serverUrl, database}: Props) => {
return {
type,
canEnableDisableCalls,
isCallsEnabledInChannel,
groupCallsAllowed,
canAddBookmarks,
canManageMembers,
canManageSettings,
isBookmarksEnabled,
isCallsEnabledInChannel,
isCRTEnabled: observeIsCRTEnabled(database),
isGuestUser,
isConvertGMFeatureAvailable,

View file

@ -486,6 +486,7 @@
"mobile.calls_ended_at": "Ended at",
"mobile.calls_error_message": "Error: {error}",
"mobile.calls_error_title": "Error",
"mobile.calls_group_calls_not_available": "Calls are only available in DM channels.",
"mobile.calls_headset": "Headset",
"mobile.calls_hide_cc": "Hide live captions",
"mobile.calls_host": "host",

6
package-lock.json generated
View file

@ -17,7 +17,7 @@
"@formatjs/intl-numberformat": "8.10.3",
"@formatjs/intl-pluralrules": "5.2.14",
"@gorhom/bottom-sheet": "4.6.4",
"@mattermost/calls": "github:mattermost/calls-common#5cc5598fe9574125a61a3b54501deb6b65fcc70f",
"@mattermost/calls": "github:mattermost/calls-common#1ce6defb1ee0c1e0f106ddff8f46c37d10d60b76",
"@mattermost/compass-icons": "0.1.45",
"@mattermost/hardware-keyboard": "file:./libraries/@mattermost/hardware-keyboard",
"@mattermost/keyboard-tracker": "file:./libraries/@mattermost/keyboard-tracker",
@ -5860,8 +5860,8 @@
"node_modules/@mattermost/calls": {
"name": "@mattermost/calls-common",
"version": "0.27.2",
"resolved": "git+ssh://git@github.com/mattermost/calls-common.git#5cc5598fe9574125a61a3b54501deb6b65fcc70f",
"integrity": "sha512-oJkw51naheYGDlxV4iRx0rnI1zAjWE/InRG6QXPvq2nbJ9U0QUPsk/H9/O6trP2ZuXR/v1u72z/OwqLud1blbQ=="
"resolved": "git+ssh://git@github.com/mattermost/calls-common.git#1ce6defb1ee0c1e0f106ddff8f46c37d10d60b76",
"integrity": "sha512-VeX0GT1g8bl7AqG5TJEnbkTTVbc+CqZttpPBKYDkMJd86CGjtURc4o83OUu3TNsEI3opSpJfbetScUTG9TWNLw=="
},
"node_modules/@mattermost/commonmark": {
"version": "0.30.1-2",

View file

@ -18,7 +18,7 @@
"@formatjs/intl-numberformat": "8.10.3",
"@formatjs/intl-pluralrules": "5.2.14",
"@gorhom/bottom-sheet": "4.6.4",
"@mattermost/calls": "github:mattermost/calls-common#5cc5598fe9574125a61a3b54501deb6b65fcc70f",
"@mattermost/calls": "github:mattermost/calls-common#1ce6defb1ee0c1e0f106ddff8f46c37d10d60b76",
"@mattermost/compass-icons": "0.1.45",
"@mattermost/hardware-keyboard": "file:./libraries/@mattermost/hardware-keyboard",
"@mattermost/keyboard-tracker": "file:./libraries/@mattermost/keyboard-tracker",