diff --git a/app/components/channel_actions/copy_channel_link_option/copy_channel_link_option.tsx b/app/components/channel_actions/copy_channel_link_option/copy_channel_link_option.tsx
index 2331b143c..997f7bb44 100644
--- a/app/components/channel_actions/copy_channel_link_option/copy_channel_link_option.tsx
+++ b/app/components/channel_actions/copy_channel_link_option/copy_channel_link_option.tsx
@@ -35,7 +35,7 @@ const CopyChannelLinkOption = ({channelName, teamName, showAsLabel, testID}: Pro
);
diff --git a/app/components/channel_actions/info_box/index.tsx b/app/components/channel_actions/info_box/index.tsx
index 036e4a2b6..f55fbd320 100644
--- a/app/components/channel_actions/info_box/index.tsx
+++ b/app/components/channel_actions/info_box/index.tsx
@@ -45,7 +45,7 @@ const InfoBox = ({channelId, containerStyle, showAsLabel = false, testID}: Props
if (showAsLabel) {
return (
{
dismissBottomSheet();
let username = mentionName;
@@ -182,7 +182,7 @@ const AtMention = ({
/>
{
dismissBottomSheet();
}}
diff --git a/app/components/markdown/markdown_code_block/index.tsx b/app/components/markdown/markdown_code_block/index.tsx
index 903504d44..a9d799b96 100644
--- a/app/components/markdown/markdown_code_block/index.tsx
+++ b/app/components/markdown/markdown_code_block/index.tsx
@@ -123,7 +123,7 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc
style={style.bottomSheet}
>
{
dismissBottomSheet();
Clipboard.setString(content);
@@ -133,7 +133,7 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc
/>
{
dismissBottomSheet();
}}
diff --git a/app/components/markdown/markdown_image/index.tsx b/app/components/markdown/markdown_image/index.tsx
index 5cc5a62ef..5cb5f6a8a 100644
--- a/app/components/markdown/markdown_image/index.tsx
+++ b/app/components/markdown/markdown_image/index.tsx
@@ -157,7 +157,7 @@ const MarkdownImage = ({
style={style.bottomSheet}
>
{
dismissBottomSheet();
Clipboard.setString(linkDestination || source);
@@ -167,7 +167,7 @@ const MarkdownImage = ({
/>
{
dismissBottomSheet();
}}
diff --git a/app/components/markdown/markdown_latex_block/index.tsx b/app/components/markdown/markdown_latex_block/index.tsx
index 3b7dd644c..65437cb9e 100644
--- a/app/components/markdown/markdown_latex_block/index.tsx
+++ b/app/components/markdown/markdown_latex_block/index.tsx
@@ -139,7 +139,7 @@ const LatexCodeBlock = ({content, theme}: Props) => {
style={styles.bottomSheet}
>
{
dismissBottomSheet();
Clipboard.setString(content);
@@ -149,7 +149,7 @@ const LatexCodeBlock = ({content, theme}: Props) => {
/>
{
dismissBottomSheet();
Clipboard.setString(href);
@@ -126,7 +126,7 @@ const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteU
/>
{
dismissBottomSheet();
}}
diff --git a/app/components/post_draft/quick_actions/camera_quick_action/camera_type.tsx b/app/components/post_draft/quick_actions/camera_quick_action/camera_type.tsx
index e681c7a56..c5198299a 100644
--- a/app/components/post_draft/quick_actions/camera_quick_action/camera_type.tsx
+++ b/app/components/post_draft/quick_actions/camera_quick_action/camera_type.tsx
@@ -66,13 +66,13 @@ const CameraType = ({onPress}: Props) => {
/>
}
{
style={styles.bottomSheet}
>
{
dismissBottomSheet();
retryFailedPost(serverUrl, post);
@@ -54,7 +54,7 @@ const Failed = ({post, theme}: FailedProps) => {
/>
{
dismissBottomSheet();
removePost(serverUrl, post);
diff --git a/app/components/slide_up_panel_item/index.tsx b/app/components/slide_up_panel_item/index.tsx
index ce02022c5..37a4c4adf 100644
--- a/app/components/slide_up_panel_item/index.tsx
+++ b/app/components/slide_up_panel_item/index.tsx
@@ -14,10 +14,12 @@ import {isValidUrl} from '@utils/url';
type SlideUpPanelProps = {
destructive?: boolean;
- icon?: string | Source;
- rightIcon?: boolean;
- imageStyles?: StyleProp;
- iconStyles?: StyleProp;
+ leftIcon?: string | Source;
+ leftImageStyles?: StyleProp;
+ leftIconStyles?: StyleProp;
+ rightIcon?: string | Source;
+ rightImageStyles?: StyleProp;
+ rightIconStyles?: StyleProp;
onPress: () => void;
textStyles?: TextStyle;
testID?: string;
@@ -65,13 +67,55 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
};
});
-const SlideUpPanelItem = ({destructive, icon, imageStyles, onPress, testID, text, textStyles, iconStyles, rightIcon = false}: SlideUpPanelProps) => {
+const SlideUpPanelItem = ({
+ destructive = false,
+ leftIcon,
+ leftImageStyles,
+ leftIconStyles,
+ rightIcon,
+ rightImageStyles,
+ rightIconStyles,
+ onPress,
+ testID,
+ text,
+ textStyles,
+}: SlideUpPanelProps) => {
const theme = useTheme();
+ const style = getStyleSheet(theme);
+
+ const {image: leftImage, iconStyle: leftIconStyle} = useImageAndStyle(leftIcon, leftImageStyles, leftIconStyles, destructive);
+ const {image: rightImage, iconStyle: rightIconStyle} = useImageAndStyle(rightIcon, rightImageStyles, rightIconStyles, destructive);
+
const handleOnPress = useCallback(preventDoubleTap(onPress, 500), []);
+
+ return (
+
+
+ {Boolean(leftImage) &&
+ {leftImage}
+ }
+
+ {text}
+
+ {Boolean(rightImage) &&
+ {rightImage}
+ }
+
+
+ );
+};
+
+const useImageAndStyle = (icon: string | Source | undefined, imageStyles: StyleProp, iconStyles: StyleProp, destructive: boolean) => {
+ const theme = useTheme();
const style = getStyleSheet(theme);
let image;
- let iconStyle: StyleProp = [style.iconContainer];
+ let iconStyle: Array> = [style.iconContainer];
if (icon) {
if (typeof icon === 'object') {
if (icon.uri && isValidUrl(icon.uri)) {
@@ -101,26 +145,7 @@ const SlideUpPanelItem = ({destructive, icon, imageStyles, onPress, testID, text
}
}
- return (
-
-
- {Boolean(image) && !rightIcon &&
- {image}
- }
-
- {text}
-
- {Boolean(image) && rightIcon &&
- {image}
- }
-
-
- );
+ return {image, iconStyle};
};
export default SlideUpPanelItem;
diff --git a/app/products/calls/components/audio_device_button.tsx b/app/products/calls/components/audio_device_button.tsx
index 47c339bec..a62fdbaf6 100644
--- a/app/products/calls/components/audio_device_button.tsx
+++ b/app/products/calls/components/audio_device_button.tsx
@@ -14,7 +14,7 @@ import {Device} from '@constants';
import {useTheme} from '@context/theme';
import {bottomSheet, dismissBottomSheet} from '@screens/navigation';
import {bottomSheetSnapPoint} from '@utils/helpers';
-import {typography} from '@utils/typography';
+import {makeStyleSheetFromTheme} from '@utils/theme';
type Props = {
pressableStyle: StyleProp;
@@ -23,13 +23,16 @@ type Props = {
currentCall: CurrentCall;
}
-const style = {
- bold: typography('Body', 200, 'SemiBold'),
-};
+const getStyleFromTheme = makeStyleSheetFromTheme((theme: Theme) => ({
+ checkIcon: {
+ color: theme.buttonBg,
+ },
+}));
export const AudioDeviceButton = ({pressableStyle, iconStyle, buttonTextStyle, currentCall}: Props) => {
const intl = useIntl();
const theme = useTheme();
+ const style = getStyleFromTheme(theme);
const {bottom} = useSafeAreaInsets();
const isTablet = Device.IS_TABLET; // not `useIsTablet` because even if we're in splitView, we're still using a tablet.
const color = theme.awayIndicator;
@@ -38,10 +41,14 @@ export const AudioDeviceButton = ({pressableStyle, iconStyle, buttonTextStyle, c
const tabletLabel = intl.formatMessage({id: 'mobile.calls_tablet', defaultMessage: 'Tablet'});
const speakerLabel = intl.formatMessage({id: 'mobile.calls_speaker', defaultMessage: 'SpeakerPhone'});
const bluetoothLabel = intl.formatMessage({id: 'mobile.calls_bluetooth', defaultMessage: 'Bluetooth'});
+ const headsetLabel = intl.formatMessage({id: 'mobile.calls_headset', defaultMessage: 'Headset'});
const deviceSelector = useCallback(async () => {
const currentDevice = audioDeviceInfo.selectedAudioDevice;
- const available = audioDeviceInfo.availableAudioDeviceList;
+ let available = audioDeviceInfo.availableAudioDeviceList;
+ if (available.includes(AudioDevice.WiredHeadset)) {
+ available = available.filter((d) => d !== AudioDevice.Earpiece);
+ }
const selectDevice = (device: AudioDevice) => {
setPreferredAudioRoute(device);
dismissBottomSheet();
@@ -52,34 +59,47 @@ export const AudioDeviceButton = ({pressableStyle, iconStyle, buttonTextStyle, c
{available.includes(AudioDevice.Earpiece) && isTablet &&
selectDevice(AudioDevice.Earpiece)}
text={tabletLabel}
- textStyles={currentDevice === AudioDevice.Earpiece ? {...style.bold, color} : {}}
+ rightIcon={currentDevice === AudioDevice.Earpiece ? 'check' : undefined}
+ rightIconStyles={currentDevice === AudioDevice.Earpiece ? style.checkIcon : {}}
/>
}
{available.includes(AudioDevice.Earpiece) && !isTablet &&
selectDevice(AudioDevice.Earpiece)}
text={phoneLabel}
- textStyles={currentDevice === AudioDevice.Earpiece ? {...style.bold, color} : {}}
+ rightIcon={currentDevice === AudioDevice.Earpiece ? 'check' : undefined}
+ rightIconStyles={currentDevice === AudioDevice.Earpiece ? style.checkIcon : {}}
/>
}
{available.includes(AudioDevice.Speakerphone) &&
selectDevice(AudioDevice.Speakerphone)}
text={speakerLabel}
- textStyles={currentDevice === AudioDevice.Speakerphone ? {...style.bold, color} : {}}
+ rightIcon={currentDevice === AudioDevice.Speakerphone ? 'check' : undefined}
+ rightIconStyles={currentDevice === AudioDevice.Speakerphone ? style.checkIcon : {}}
/>
}
{available.includes(AudioDevice.Bluetooth) &&
selectDevice(AudioDevice.Bluetooth)}
text={bluetoothLabel}
- textStyles={currentDevice === AudioDevice.Bluetooth ? {...style.bold, color} : {}}
+ rightIcon={currentDevice === AudioDevice.Bluetooth ? 'check' : undefined}
+ rightIconStyles={currentDevice === AudioDevice.Bluetooth ? style.checkIcon : {}}
+ />
+ }
+ {available.includes(AudioDevice.WiredHeadset) &&
+ selectDevice(AudioDevice.WiredHeadset)}
+ text={headsetLabel}
+ rightIcon={currentDevice === AudioDevice.WiredHeadset ? 'check' : undefined}
+ rightIconStyles={currentDevice === AudioDevice.WiredHeadset ? style.checkIcon : {}}
/>
}
@@ -89,7 +109,7 @@ export const AudioDeviceButton = ({pressableStyle, iconStyle, buttonTextStyle, c
await bottomSheet({
closeButtonId: 'close-other-actions',
renderContent,
- snapPoints: [1, bottomSheetSnapPoint(audioDeviceInfo.availableAudioDeviceList.length + 1, ITEM_HEIGHT, bottom)],
+ snapPoints: [1, bottomSheetSnapPoint(available.length + 1, ITEM_HEIGHT, bottom)],
title: intl.formatMessage({id: 'mobile.calls_audio_device', defaultMessage: 'Select audio device'}),
theme,
});
@@ -106,6 +126,10 @@ export const AudioDeviceButton = ({pressableStyle, iconStyle, buttonTextStyle, c
icon = 'bluetooth';
label = bluetoothLabel;
break;
+ case AudioDevice.WiredHeadset:
+ icon = 'headphones';
+ label = headsetLabel;
+ break;
}
return (
diff --git a/app/products/calls/connection/connection.ts b/app/products/calls/connection/connection.ts
index 0dd69a3d2..6d736e3ff 100644
--- a/app/products/calls/connection/connection.ts
+++ b/app/products/calls/connection/connection.ts
@@ -3,7 +3,7 @@
import {RTCMonitor, RTCPeer} from '@mattermost/calls/lib';
import {deflate} from 'pako';
-import {DeviceEventEmitter, type EmitterSubscription, Platform} from 'react-native';
+import {DeviceEventEmitter, type EmitterSubscription, NativeEventEmitter, NativeModules, Platform} from 'react-native';
import InCallManager from 'react-native-incall-manager';
import {mediaDevices, MediaStream, MediaStreamTrack, RTCPeerConnection} from 'react-native-webrtc';
@@ -24,6 +24,8 @@ import type {EmojiData} from '@mattermost/calls/lib/types';
const peerConnectTimeout = 5000;
const rtcMonitorInterval = 4000;
+const InCallManagerEmitter = new NativeEventEmitter(NativeModules.InCallManager);
+
export async function newConnection(
serverUrl: string,
channelID: string,
@@ -40,6 +42,7 @@ export async function newConnection(
let isClosed = false;
let onCallEnd: EmitterSubscription | null = null;
let audioDeviceChanged: EmitterSubscription | null = null;
+ let wiredHeadsetEvent: EmitterSubscription | null = null;
const streams: MediaStream[] = [];
let rtcMonitor: RTCMonitor | null = null;
const logger = {
@@ -106,6 +109,7 @@ export async function newConnection(
peer = null;
InCallManager.stop();
audioDeviceChanged?.remove();
+ wiredHeadsetEvent?.remove();
if (closeCb) {
closeCb();
@@ -224,29 +228,50 @@ export async function newConnection(
let btInitialized = false;
let speakerInitialized = false;
- audioDeviceChanged = DeviceEventEmitter.addListener('onAudioDeviceChanged', (data: AudioDeviceInfoRaw) => {
- const info: AudioDeviceInfo = {
- availableAudioDeviceList: JSON.parse(data.availableAudioDeviceList),
- selectedAudioDevice: data.selectedAudioDevice,
- };
- setAudioDeviceInfo(info);
+ if (Platform.OS === 'android') {
+ audioDeviceChanged = DeviceEventEmitter.addListener('onAudioDeviceChanged', (data: AudioDeviceInfoRaw) => {
+ const info: AudioDeviceInfo = {
+ availableAudioDeviceList: JSON.parse(data.availableAudioDeviceList),
+ selectedAudioDevice: data.selectedAudioDevice,
+ };
+ setAudioDeviceInfo(info);
+ logDebug('AudioDeviceChanged. info:', info);
- // Auto switch to bluetooth the first time we connect to bluetooth, but not after.
- if (!btInitialized) {
- if (info.availableAudioDeviceList.includes(AudioDevice.Bluetooth)) {
- setPreferredAudioRoute(AudioDevice.Bluetooth);
- btInitialized = true;
- } else if (!speakerInitialized) {
- // If we don't have bluetooth available, default to speakerphone on.
- setPreferredAudioRoute(AudioDevice.Speakerphone);
- speakerInitialized = true;
+ // Auto switch to bluetooth the first time we connect to bluetooth, but not after.
+ if (!btInitialized) {
+ if (info.availableAudioDeviceList.includes(AudioDevice.Bluetooth)) {
+ setPreferredAudioRoute(AudioDevice.Bluetooth);
+ btInitialized = true;
+ } else if (!speakerInitialized) {
+ // If we don't have bluetooth available, default to speakerphone on.
+ setPreferredAudioRoute(AudioDevice.Speakerphone);
+ speakerInitialized = true;
+ }
}
- }
- });
+ });
+ }
- // We default to speakerphone (Android is handled above in the onAudioDeviceChanged handler above).
+ // We default to speakerphone, but not if the WiredHeadset is plugged in.
if (Platform.OS === 'ios') {
- setSpeakerphoneOn(true);
+ wiredHeadsetEvent = InCallManagerEmitter.addListener('WiredHeadset', (data) => {
+ // Log for customer debugging. For the moment we're not changing output labels because of incall-manager iOS
+ // limitations with how it reports Bluetooth -- namely that it doesn't, so we don't know when Bluetooth is
+ // overriding the earpiece and/or headset.
+ logDebug('WiredHeadset plugged in. Data:', data);
+
+ // iOS switches to the headset when we connect it, so turn off speakerphone to keep UI in sync.
+ if (data.isPlugged) {
+ setSpeakerphoneOn(false);
+ }
+ });
+
+ // If headset is plugged in when the call starts, use it.
+ const report = await InCallManager.getIsWiredHeadsetPluggedIn();
+ if (report.isWiredHeadsetPluggedIn) {
+ setSpeakerphoneOn(false);
+ } else {
+ setSpeakerphoneOn(true);
+ }
}
peer = new RTCPeer({
diff --git a/app/products/calls/screens/call_screen/call_screen.tsx b/app/products/calls/screens/call_screen/call_screen.tsx
index 8deaad047..103ced171 100644
--- a/app/products/calls/screens/call_screen/call_screen.tsx
+++ b/app/products/calls/screens/call_screen/call_screen.tsx
@@ -477,7 +477,7 @@ const CallScreen = ({
{
showStartRecording &&
@@ -485,14 +485,14 @@ const CallScreen = ({
{
showStopRecording &&
}
@@ -764,7 +764,6 @@ const CallScreen = ({
iconStyle={[
style.buttonIcon,
isLandscape && style.buttonIconLandscape,
- style.speakerphoneIcon,
currentCall.speakerphoneOn && style.buttonOn,
]}
buttonTextStyle={style.buttonText}
diff --git a/app/screens/browse_channels/dropdown_slideup.tsx b/app/screens/browse_channels/dropdown_slideup.tsx
index f9f8e51c1..c1ae0b44a 100644
--- a/app/screens/browse_channels/dropdown_slideup.tsx
+++ b/app/screens/browse_channels/dropdown_slideup.tsx
@@ -42,11 +42,6 @@ export default function DropdownSlideup({
const style = getStyleFromTheme(theme);
const isTablet = useIsTablet();
- const commonProps = {
- rightIcon: true,
- iconStyles: style.checkIcon,
- };
-
const handlePublicPress = useCallback(() => {
dismissBottomSheet();
onPress(PUBLIC);
@@ -73,16 +68,16 @@ export default function DropdownSlideup({
onPress={handlePublicPress}
testID='browse_channels.dropdown_slideup_item.public_channels'
text={intl.formatMessage({id: 'browse_channels.publicChannels', defaultMessage: 'Public Channels'})}
- icon={selected === PUBLIC ? 'check' : undefined}
- {...commonProps}
+ rightIcon={selected === PUBLIC ? 'check' : undefined}
+ rightIconStyles={style.checkIcon}
/>
{canShowArchivedChannels && (
)}
{sharedChannelsEnabled && (
@@ -90,8 +85,8 @@ export default function DropdownSlideup({
onPress={handleSharedPress}
testID='browse_channels.dropdown_slideup_item.shared_channels'
text={intl.formatMessage({id: 'browse_channels.sharedChannels', defaultMessage: 'Shared Channels'})}
- icon={selected === SHARED ? 'check' : undefined}
- {...commonProps}
+ rightIcon={selected === SHARED ? 'check' : undefined}
+ rightIconStyles={style.checkIcon}
/>
)}
diff --git a/app/screens/edit_profile/components/panel_item.tsx b/app/screens/edit_profile/components/panel_item.tsx
index 9bd3025a1..5cb414e9a 100644
--- a/app/screens/edit_profile/components/panel_item.tsx
+++ b/app/screens/edit_profile/components/panel_item.tsx
@@ -71,7 +71,7 @@ const PanelItem = ({pickerAction, pictureUtils, onRemoveProfileImage}: PanelItem
return (
{
)}
setUserStatus(ONLINE)}
testID='user_status.online.option'
text={intl.formatMessage({
@@ -89,8 +89,8 @@ const UserStatus = ({currentUser}: Props) => {
textStyles={styles.label}
/>
setUserStatus(AWAY)}
testID='user_status.away.option'
text={intl.formatMessage({
@@ -100,8 +100,8 @@ const UserStatus = ({currentUser}: Props) => {
textStyles={styles.label}
/>
setUserStatus(DND)}
testID='user_status.dnd.option'
text={intl.formatMessage({
@@ -111,8 +111,8 @@ const UserStatus = ({currentUser}: Props) => {
textStyles={styles.label}
/>
setUserStatus(OFFLINE)}
testID='user_status.offline.option'
text={intl.formatMessage({
diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json
index 15707f980..4b8a02ce2 100644
--- a/assets/base/i18n/en.json
+++ b/assets/base/i18n/en.json
@@ -435,6 +435,7 @@
"mobile.calls_ended_at": "Ended at",
"mobile.calls_error_message": "Error: {error}",
"mobile.calls_error_title": "Error",
+ "mobile.calls_headset": "Headset",
"mobile.calls_host": "host",
"mobile.calls_host_rec": "You are recording this meeting. Consider letting everyone know that this meeting is being recorded.",
"mobile.calls_host_rec_error": "Please try to record again. You can also contact your system admin for troubleshooting help.",
diff --git a/package-lock.json b/package-lock.json
index 057f7c33e..7f7928ca5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,7 +18,7 @@
"@formatjs/intl-relativetimeformat": "11.2.4",
"@gorhom/bottom-sheet": "4.4.7",
"@mattermost/calls": "github:mattermost/calls-common#v0.17.0",
- "@mattermost/compass-icons": "0.1.37",
+ "@mattermost/compass-icons": "0.1.38",
"@mattermost/react-native-emm": "1.3.5",
"@mattermost/react-native-network-client": "1.4.1",
"@mattermost/react-native-paste-input": "0.6.4",
@@ -3436,9 +3436,9 @@
}
},
"node_modules/@mattermost/compass-icons": {
- "version": "0.1.37",
- "resolved": "https://registry.npmjs.org/@mattermost/compass-icons/-/compass-icons-0.1.37.tgz",
- "integrity": "sha512-4me1W0hj1nu8A1gpdQA6cij/hyb2P7uIYMJQ+xrNvn5ImTRfQ67LEdyNOa/LY+oT1NO2ui6kKOs8oLUehIaneg=="
+ "version": "0.1.38",
+ "resolved": "https://registry.npmjs.org/@mattermost/compass-icons/-/compass-icons-0.1.38.tgz",
+ "integrity": "sha512-JfLQJtvxD++7lw+jiLWs55+SOhF8wPQgfTCOEi/uyl9bRxfY736a9fPzRcRJwF80se7lPMxvAx8itwvTz0o7CQ=="
},
"node_modules/@mattermost/react-native-emm": {
"version": "1.3.5",
@@ -25415,9 +25415,9 @@
}
},
"@mattermost/compass-icons": {
- "version": "0.1.37",
- "resolved": "https://registry.npmjs.org/@mattermost/compass-icons/-/compass-icons-0.1.37.tgz",
- "integrity": "sha512-4me1W0hj1nu8A1gpdQA6cij/hyb2P7uIYMJQ+xrNvn5ImTRfQ67LEdyNOa/LY+oT1NO2ui6kKOs8oLUehIaneg=="
+ "version": "0.1.38",
+ "resolved": "https://registry.npmjs.org/@mattermost/compass-icons/-/compass-icons-0.1.38.tgz",
+ "integrity": "sha512-JfLQJtvxD++7lw+jiLWs55+SOhF8wPQgfTCOEi/uyl9bRxfY736a9fPzRcRJwF80se7lPMxvAx8itwvTz0o7CQ=="
},
"@mattermost/react-native-emm": {
"version": "1.3.5",
diff --git a/package.json b/package.json
index fa464345b..5f5ea59c9 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
"@formatjs/intl-relativetimeformat": "11.2.4",
"@gorhom/bottom-sheet": "4.4.7",
"@mattermost/calls": "github:mattermost/calls-common#v0.17.0",
- "@mattermost/compass-icons": "0.1.37",
+ "@mattermost/compass-icons": "0.1.38",
"@mattermost/react-native-emm": "1.3.5",
"@mattermost/react-native-network-client": "1.4.1",
"@mattermost/react-native-paste-input": "0.6.4",