Merge branch 'main' into gm_to_channel
This commit is contained in:
commit
ba9a84e3e6
17 changed files with 223 additions and 33 deletions
|
|
@ -7,7 +7,7 @@ import Animated, {interpolate, useAnimatedStyle, useSharedValue, withSpring} fro
|
|||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
|
||||
import {resetMessageCount} from '@actions/local/channel';
|
||||
import {useCallsAdjustment} from '@app/products/calls/hooks';
|
||||
import {useCallsAdjustment} from '@calls/hooks';
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import TouchableWithFeedback from '@components/touchable_with_feedback';
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ export const MAX_CHANNEL_NAME_LENGTH = 64;
|
|||
export const IGNORE_CHANNEL_MENTIONS_ON = 'on';
|
||||
export const IGNORE_CHANNEL_MENTIONS_OFF = 'off';
|
||||
export const IGNORE_CHANNEL_MENTIONS_DEFAULT = 'default';
|
||||
export const CHANNEL_AUTO_FOLLOW_THREADS_TRUE = 'on';
|
||||
export const CHANNEL_AUTO_FOLLOW_THREADS_FALSE = 'off';
|
||||
|
||||
export default {
|
||||
IGNORE_CHANNEL_MENTIONS_ON,
|
||||
|
|
@ -13,4 +15,6 @@ export default {
|
|||
IGNORE_CHANNEL_MENTIONS_DEFAULT,
|
||||
MAX_CHANNEL_NAME_LENGTH,
|
||||
MIN_CHANNEL_NAME_LENGTH,
|
||||
CHANNEL_AUTO_FOLLOW_THREADS_TRUE,
|
||||
CHANNEL_AUTO_FOLLOW_THREADS_FALSE,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback, useEffect} from 'react';
|
||||
import React, {useCallback, useEffect, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Pressable, Text, View} from 'react-native';
|
||||
|
||||
|
|
@ -18,11 +18,14 @@ import {useServerUrl} from '@context/server';
|
|||
import {useTheme} from '@context/theme';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import WebsocketManager from '@managers/websocket_manager';
|
||||
import {getServerDisplayName} from '@queries/app/servers';
|
||||
import ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
import {displayUsername} from '@utils/user';
|
||||
|
||||
import type ServersModel from '@typings/database/models/app/servers';
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
outerContainer: {
|
||||
borderRadius: 8,
|
||||
|
|
@ -39,6 +42,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
shadowRadius: 4,
|
||||
elevation: 4,
|
||||
},
|
||||
outerContainerServerName: {
|
||||
height: CALL_NOTIFICATION_BAR_HEIGHT + 8,
|
||||
},
|
||||
innerContainer: {
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
|
|
@ -71,6 +77,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
},
|
||||
textContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
marginLeft: 8,
|
||||
},
|
||||
text: {
|
||||
|
|
@ -81,6 +88,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
...typography('Body', 100, 'SemiBold'),
|
||||
lineHeight: 20,
|
||||
},
|
||||
textServerName: {
|
||||
...typography('Heading', 25),
|
||||
color: changeOpacity(theme.buttonColor, 0.72),
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
dismissContainer: {
|
||||
alignItems: 'center',
|
||||
width: 32,
|
||||
|
|
@ -93,6 +105,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
}));
|
||||
|
||||
type Props = {
|
||||
servers: ServersModel[];
|
||||
incomingCall: IncomingCallNotification;
|
||||
currentUserId: string;
|
||||
teammateNameDisplay: string;
|
||||
|
|
@ -101,6 +114,7 @@ type Props = {
|
|||
}
|
||||
|
||||
export const CallNotification = ({
|
||||
servers,
|
||||
incomingCall,
|
||||
currentUserId,
|
||||
teammateNameDisplay,
|
||||
|
|
@ -111,6 +125,8 @@ export const CallNotification = ({
|
|||
const serverUrl = useServerUrl();
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
const [serverName, setServerName] = useState('');
|
||||
const moreThanOneServer = servers.length > 1;
|
||||
|
||||
useEffect(() => {
|
||||
const channelMembers = members?.filter((m) => m.userId !== currentUserId);
|
||||
|
|
@ -119,13 +135,24 @@ export const CallNotification = ({
|
|||
}
|
||||
}, []);
|
||||
|
||||
// We only need to getServerDisplayName once
|
||||
useEffect(() => {
|
||||
async function getName() {
|
||||
setServerName(await getServerDisplayName(incomingCall.serverUrl));
|
||||
}
|
||||
|
||||
if (moreThanOneServer) {
|
||||
getName();
|
||||
}
|
||||
}, [moreThanOneServer, incomingCall.serverUrl]);
|
||||
|
||||
const onContainerPress = useCallback(async () => {
|
||||
if (serverUrl !== incomingCall.serverUrl) {
|
||||
if (incomingCall.serverUrl !== serverUrl) {
|
||||
await DatabaseManager.setActiveServerDatabase(incomingCall.serverUrl);
|
||||
await WebsocketManager.initializeClient(incomingCall.serverUrl);
|
||||
}
|
||||
switchToChannelById(incomingCall.serverUrl, incomingCall.channelID);
|
||||
}, [serverUrl, incomingCall]);
|
||||
}, [incomingCall, serverUrl]);
|
||||
|
||||
const onDismissPress = useCallback(() => {
|
||||
removeIncomingCall(serverUrl, incomingCall.callID, incomingCall.channelID);
|
||||
|
|
@ -143,7 +170,7 @@ export const CallNotification = ({
|
|||
name: displayUsername(incomingCall.callerModel, intl.locale, teammateNameDisplay),
|
||||
}}
|
||||
style={style.text}
|
||||
numberOfLines={2}
|
||||
numberOfLines={1}
|
||||
ellipsizeMode={'tail'}
|
||||
/>
|
||||
);
|
||||
|
|
@ -158,14 +185,14 @@ export const CallNotification = ({
|
|||
num: (members?.length || 2) - 1,
|
||||
}}
|
||||
style={style.text}
|
||||
numberOfLines={2}
|
||||
numberOfLines={1}
|
||||
ellipsizeMode={'tail'}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[style.outerContainer]}>
|
||||
<View style={[style.outerContainer, moreThanOneServer && style.outerContainerServerName]}>
|
||||
<Pressable
|
||||
style={[style.innerContainer, onCallsScreen && style.innerOnCallsScreen]}
|
||||
onPress={onContainerPress}
|
||||
|
|
@ -180,6 +207,11 @@ export const CallNotification = ({
|
|||
</View>
|
||||
<View style={style.textContainer}>
|
||||
{message}
|
||||
{moreThanOneServer &&
|
||||
<Text style={style.textServerName}>
|
||||
{serverName}
|
||||
</Text>
|
||||
}
|
||||
</View>
|
||||
<Pressable onPress={onDismissPress}>
|
||||
<View style={style.dismissContainer}>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import withObservables from '@nozbe/with-observables';
|
|||
import {of as of$} from 'rxjs';
|
||||
import {distinctUntilChanged, switchMap} from 'rxjs/operators';
|
||||
|
||||
import {observeAllActiveServers} from '@app/queries/app/servers';
|
||||
import {CallNotification} from '@calls/components/call_notification/call_notification';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {observeChannelMembers} from '@queries/servers/channel';
|
||||
|
|
@ -33,6 +34,7 @@ const enhanced = withObservables(['incomingCall'], ({incomingCall}: OwnProps) =>
|
|||
);
|
||||
|
||||
return {
|
||||
servers: observeAllActiveServers(),
|
||||
currentUserId,
|
||||
teammateNameDisplay,
|
||||
members,
|
||||
|
|
|
|||
|
|
@ -8,13 +8,26 @@ import {useIntl} from 'react-intl';
|
|||
import {Alert, Platform} from 'react-native';
|
||||
import Permissions from 'react-native-permissions';
|
||||
|
||||
import {CALL_ERROR_BAR_HEIGHT, CALL_NOTIFICATION_BAR_HEIGHT, CURRENT_CALL_BAR_HEIGHT, JOIN_CALL_BAR_HEIGHT} from '@app/constants/view';
|
||||
import {initializeVoiceTrack} from '@calls/actions/calls';
|
||||
import {setMicPermissionsGranted, useCallsState, useChannelsWithCalls, useCurrentCall, useGlobalCallsState, useIncomingCalls} from '@calls/state';
|
||||
import {
|
||||
setMicPermissionsGranted,
|
||||
useCallsState,
|
||||
useChannelsWithCalls,
|
||||
useCurrentCall,
|
||||
useGlobalCallsState,
|
||||
useIncomingCalls,
|
||||
} from '@calls/state';
|
||||
import {errorAlert} from '@calls/utils';
|
||||
import {
|
||||
CALL_ERROR_BAR_HEIGHT,
|
||||
CALL_NOTIFICATION_BAR_HEIGHT,
|
||||
CURRENT_CALL_BAR_HEIGHT,
|
||||
JOIN_CALL_BAR_HEIGHT,
|
||||
} from '@constants/view';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {useAppState} from '@hooks/device';
|
||||
import NetworkManager from '@managers/network_manager';
|
||||
import {queryAllActiveServers} from '@queries/app/servers';
|
||||
import {getFullErrorMessage} from '@utils/errors';
|
||||
|
||||
import type {Client} from '@client/rest';
|
||||
|
|
@ -110,26 +123,35 @@ export const usePermissionsChecker = (micPermissionsGranted: boolean) => {
|
|||
}, [appState]);
|
||||
};
|
||||
|
||||
export const useCallsAdjustment = (serverUrl: string, channelId: string) => {
|
||||
export const useCallsAdjustment = (serverUrl: string, channelId: string): number => {
|
||||
const incomingCalls = useIncomingCalls().incomingCalls;
|
||||
const channelsWithCalls = useChannelsWithCalls(serverUrl);
|
||||
const callsState = useCallsState(serverUrl);
|
||||
const globalCallsState = useGlobalCallsState();
|
||||
const currentCall = useCurrentCall();
|
||||
const [numServers, setNumServers] = useState(1);
|
||||
const dismissed = Boolean(callsState.calls[channelId]?.dismissed[callsState.myUserId]);
|
||||
const inCurrentCall = currentCall?.id === channelId;
|
||||
const joinCallBannerVisible = Boolean(channelsWithCalls[channelId]) && !dismissed && !inCurrentCall;
|
||||
|
||||
useEffect(() => {
|
||||
const getNumServers = async () => {
|
||||
const query = await queryAllActiveServers()?.fetch();
|
||||
setNumServers(query?.length || 0);
|
||||
};
|
||||
getNumServers();
|
||||
}, []);
|
||||
|
||||
// Do we have calls banners?
|
||||
const currentCallBarVisible = Boolean(currentCall);
|
||||
const micPermissionsError = !globalCallsState.micPermissionsGranted && (currentCall && !currentCall.micPermissionsErrorDismissed);
|
||||
const callQualityAlert = Boolean(currentCall?.callQualityAlert);
|
||||
const incomingCallsShowing = incomingCalls.filter((ic) => ic.channelID !== channelId);
|
||||
const callsIncomingAdjustment = (incomingCallsShowing.length * CALL_NOTIFICATION_BAR_HEIGHT) + (incomingCallsShowing.length * 8);
|
||||
const callsAdjustment = (currentCallBarVisible ? CURRENT_CALL_BAR_HEIGHT + 8 : 0) +
|
||||
const notificationBarHeight = CALL_NOTIFICATION_BAR_HEIGHT + (numServers > 1 ? 8 : 0);
|
||||
const callsIncomingAdjustment = (incomingCallsShowing.length * notificationBarHeight) + (incomingCallsShowing.length * 8);
|
||||
return (currentCallBarVisible ? CURRENT_CALL_BAR_HEIGHT + 8 : 0) +
|
||||
(micPermissionsError ? CALL_ERROR_BAR_HEIGHT + 8 : 0) +
|
||||
(callQualityAlert ? CALL_ERROR_BAR_HEIGHT + 8 : 0) +
|
||||
(joinCallBannerVisible ? JOIN_CALL_BAR_HEIGHT + 8 : 0) +
|
||||
callsIncomingAdjustment;
|
||||
return callsAdjustment;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ type Props = {
|
|||
canEnableDisableCalls: boolean;
|
||||
isCallsEnabledInChannel: boolean;
|
||||
canManageMembers: boolean;
|
||||
isCRTEnabled: boolean;
|
||||
canManageSettings: boolean;
|
||||
isGuestUser: boolean;
|
||||
isConvertGMFeatureAvailable: boolean;
|
||||
|
|
@ -55,6 +56,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
}));
|
||||
|
||||
const ChannelInfo = ({
|
||||
isCRTEnabled,
|
||||
channelId,
|
||||
closeButtonId,
|
||||
componentId,
|
||||
|
|
@ -113,6 +115,7 @@ const ChannelInfo = ({
|
|||
type={type}
|
||||
callsEnabled={callsAvailable}
|
||||
canManageMembers={canManageMembers}
|
||||
isCRTEnabled={isCRTEnabled}
|
||||
canManageSettings={canManageSettings}
|
||||
/>
|
||||
<View style={styles.separator}/>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
observeCurrentTeamId,
|
||||
observeCurrentUserId,
|
||||
} from '@queries/servers/system';
|
||||
import {observeIsCRTEnabled} from '@queries/servers/thread';
|
||||
import {observeCurrentUser, observeUserIsChannelAdmin, observeUserIsTeamAdmin} from '@queries/servers/user';
|
||||
import {isTypeDMorGM} from '@utils/channel';
|
||||
import {isMinimumServerVersion} from '@utils/helpers';
|
||||
|
|
@ -126,6 +127,7 @@ const enhanced = withObservables([], ({serverUrl, database}: Props) => {
|
|||
canEnableDisableCalls,
|
||||
isCallsEnabledInChannel,
|
||||
canManageMembers,
|
||||
isCRTEnabled: observeIsCRTEnabled(database),
|
||||
canManageSettings,
|
||||
isGuestUser,
|
||||
isConvertGMFeatureAvailable,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useState} from 'react';
|
||||
import {defineMessage, useIntl} from 'react-intl';
|
||||
|
||||
import {updateChannelNotifyProps} from '@actions/remote/channel';
|
||||
import OptionItem from '@components/option_item';
|
||||
import {
|
||||
CHANNEL_AUTO_FOLLOW_THREADS_FALSE,
|
||||
CHANNEL_AUTO_FOLLOW_THREADS_TRUE,
|
||||
} from '@constants/channel';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {alertErrorWithFallback} from '@utils/draft';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
type Props = {
|
||||
channelId: string;
|
||||
followedStatus: boolean;
|
||||
displayName: string;
|
||||
};
|
||||
|
||||
const AutoFollowThreads = ({channelId, displayName, followedStatus}: Props) => {
|
||||
const [autoFollow, setAutoFollow] = useState(followedStatus);
|
||||
const serverUrl = useServerUrl();
|
||||
const intl = useIntl();
|
||||
|
||||
const toggleFollow = preventDoubleTap(async () => {
|
||||
const props: Partial<ChannelNotifyProps> = {
|
||||
channel_auto_follow_threads: followedStatus ? CHANNEL_AUTO_FOLLOW_THREADS_FALSE : CHANNEL_AUTO_FOLLOW_THREADS_TRUE,
|
||||
};
|
||||
setAutoFollow((v) => !v);
|
||||
const result = await updateChannelNotifyProps(serverUrl, channelId, props);
|
||||
if (result?.error) {
|
||||
alertErrorWithFallback(
|
||||
intl,
|
||||
result.error,
|
||||
defineMessage({
|
||||
id: 'channel_info.channel_auto_follow_threads_failed',
|
||||
defaultMessage: 'An error occurred trying to auto follow all threads in channel {displayName}',
|
||||
}),
|
||||
{displayName},
|
||||
);
|
||||
setAutoFollow((v) => !v);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<OptionItem
|
||||
action={toggleFollow}
|
||||
label={intl.formatMessage({id: 'channel_info.channel_auto_follow_threads', defaultMessage: 'Follow all threads in this channel'})}
|
||||
icon='message-plus-outline'
|
||||
type='toggle'
|
||||
selected={autoFollow}
|
||||
testID={`channel_info.options.channel_auto_follow_threads.option.toggled.${autoFollow}`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default AutoFollowThreads;
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import {of as of$} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
|
||||
import {Channel} from '@constants';
|
||||
import {observeChannel, observeChannelSettings} from '@queries/servers/channel';
|
||||
|
||||
import AutoFollowThreads from './auto_follow_threads';
|
||||
|
||||
import type {WithDatabaseArgs} from '@typings/database/database';
|
||||
|
||||
type Props = WithDatabaseArgs & {
|
||||
channelId: string;
|
||||
}
|
||||
|
||||
const enhanced = withObservables(['channelId'], ({channelId, database}: Props) => {
|
||||
const channel = observeChannel(database, channelId);
|
||||
const settings = observeChannelSettings(database, channelId);
|
||||
const followedStatus = settings.pipe(
|
||||
switchMap((s) => {
|
||||
return of$(s?.notifyProps?.channel_auto_follow_threads === Channel.CHANNEL_AUTO_FOLLOW_THREADS_TRUE);
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
followedStatus,
|
||||
displayName: channel.pipe(switchMap((c) => of$(c?.displayName))),
|
||||
};
|
||||
});
|
||||
|
||||
export default withDatabase(enhanced(AutoFollowThreads));
|
||||
|
|
@ -2,35 +2,49 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {defineMessage, useIntl} from 'react-intl';
|
||||
|
||||
import {updateChannelNotifyProps} from '@actions/remote/channel';
|
||||
import OptionItem from '@components/option_item';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {alertErrorWithFallback} from '@utils/draft';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
type Props = {
|
||||
channelId: string;
|
||||
ignoring: boolean;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
const IgnoreMentions = ({channelId, ignoring}: Props) => {
|
||||
const IgnoreMentions = ({channelId, ignoring, displayName}: Props) => {
|
||||
const [ignored, setIgnored] = useState(ignoring);
|
||||
const serverUrl = useServerUrl();
|
||||
const {formatMessage} = useIntl();
|
||||
const intl = useIntl();
|
||||
|
||||
const toggleIgnore = preventDoubleTap(() => {
|
||||
const toggleIgnore = preventDoubleTap(async () => {
|
||||
const props: Partial<ChannelNotifyProps> = {
|
||||
ignore_channel_mentions: ignoring ? 'off' : 'on',
|
||||
};
|
||||
setIgnored(!ignored);
|
||||
updateChannelNotifyProps(serverUrl, channelId, props);
|
||||
setIgnored((v) => !v);
|
||||
const result = await updateChannelNotifyProps(serverUrl, channelId, props);
|
||||
if (result?.error) {
|
||||
alertErrorWithFallback(
|
||||
intl,
|
||||
result.error,
|
||||
defineMessage({
|
||||
id: 'channel_info.channel_auto_follow_threads_failed',
|
||||
defaultMessage: 'An error occurred trying to auto follow all threads in channel {displayName}',
|
||||
}),
|
||||
{displayName},
|
||||
);
|
||||
setIgnored((v) => !v);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<OptionItem
|
||||
action={toggleIgnore}
|
||||
label={formatMessage({id: 'channel_info.ignore_mentions', defaultMessage: 'Ignore @channel, @here, @all'})}
|
||||
label={intl.formatMessage({id: 'channel_info.ignore_mentions', defaultMessage: 'Ignore @channel, @here, @all'})}
|
||||
icon='at'
|
||||
type='toggle'
|
||||
selected={ignored}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {of as of$} from 'rxjs';
|
|||
import {combineLatestWith, switchMap} from 'rxjs/operators';
|
||||
|
||||
import {Channel} from '@constants';
|
||||
import {observeChannelSettings} from '@queries/servers/channel';
|
||||
import {observeChannel, observeChannelSettings} from '@queries/servers/channel';
|
||||
import {observeCurrentUser} from '@queries/servers/user';
|
||||
|
||||
import IgnoreMentions from './ignore_mentions';
|
||||
|
|
@ -34,6 +34,7 @@ const isChannelMentionsIgnored = (channelNotifyProps?: Partial<ChannelNotifyProp
|
|||
};
|
||||
|
||||
const enhanced = withObservables(['channelId'], ({channelId, database}: Props) => {
|
||||
const channel = observeChannel(database, channelId);
|
||||
const currentUser = observeCurrentUser(database);
|
||||
const settings = observeChannelSettings(database, channelId);
|
||||
const ignoring = currentUser.pipe(
|
||||
|
|
@ -43,6 +44,7 @@ const enhanced = withObservables(['channelId'], ({channelId, database}: Props) =
|
|||
|
||||
return {
|
||||
ignoring,
|
||||
displayName: channel.pipe(switchMap((c) => of$(c?.displayName))),
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {General} from '@constants';
|
|||
import {isTypeDMorGM} from '@utils/channel';
|
||||
|
||||
import AddMembers from './add_members';
|
||||
import AutoFollowThreads from './auto_follow_threads';
|
||||
import ChannelFiles from './channel_files';
|
||||
import EditChannel from './edit_channel';
|
||||
import IgnoreMentions from './ignore_mentions';
|
||||
|
|
@ -20,6 +21,7 @@ type Props = {
|
|||
type?: ChannelType;
|
||||
callsEnabled: boolean;
|
||||
canManageMembers: boolean;
|
||||
isCRTEnabled: boolean;
|
||||
canManageSettings: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -28,15 +30,21 @@ const Options = ({
|
|||
type,
|
||||
callsEnabled,
|
||||
canManageMembers,
|
||||
isCRTEnabled,
|
||||
canManageSettings,
|
||||
}: Props) => {
|
||||
const isDMorGM = isTypeDMorGM(type);
|
||||
|
||||
return (
|
||||
<>
|
||||
{type !== General.DM_CHANNEL &&
|
||||
<IgnoreMentions channelId={channelId}/>
|
||||
}
|
||||
{type !== General.DM_CHANNEL && (
|
||||
<>
|
||||
{isCRTEnabled && (
|
||||
<AutoFollowThreads channelId={channelId}/>
|
||||
)}
|
||||
<IgnoreMentions channelId={channelId}/>
|
||||
</>
|
||||
)}
|
||||
<NotificationPreference channelId={channelId}/>
|
||||
<PinnedMessages channelId={channelId}/>
|
||||
<ChannelFiles channelId={channelId}/>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import AppVersion from '@components/app_version';
|
|||
import {Screens, Launch} from '@constants';
|
||||
import useNavButtonPressed from '@hooks/navigation_button_pressed';
|
||||
import {t} from '@i18n';
|
||||
import {getServerCredentials} from '@init/credentials';
|
||||
import PushNotifications from '@init/push_notifications';
|
||||
import NetworkManager from '@managers/network_manager';
|
||||
import {getServerByDisplayName, getServerByIdentifier} from '@queries/app/servers';
|
||||
|
|
@ -244,7 +245,8 @@ const Server = ({
|
|||
}
|
||||
|
||||
const server = await getServerByDisplayName(displayName);
|
||||
if (server && server.lastActiveAt > 0) {
|
||||
const credentials = await getServerCredentials(serverUrl);
|
||||
if (server && server.lastActiveAt > 0 && credentials?.token) {
|
||||
setButtonDisabled(true);
|
||||
setDisplayNameError(formatMessage({
|
||||
id: 'mobile.server_name.exists',
|
||||
|
|
@ -330,9 +332,10 @@ const Server = ({
|
|||
}
|
||||
|
||||
const server = await getServerByIdentifier(data.config.DiagnosticId);
|
||||
const credentials = await getServerCredentials(serverUrl);
|
||||
setConnecting(false);
|
||||
|
||||
if (server && server.lastActiveAt > 0) {
|
||||
if (server && server.lastActiveAt > 0 && credentials?.token) {
|
||||
setButtonDisabled(true);
|
||||
setUrlError(formatMessage({
|
||||
id: 'mobile.server_identifier.exists',
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@
|
|||
"channel_info.archive_description.cannot_view_archived": "This will archive the channel from the team and remove it from the user interface. Archived channels can be unarchived if needed again.\n\nAre you sure you wish to archive the {term} {name}?",
|
||||
"channel_info.archive_failed": "An error occurred trying to archive the channel {displayName}",
|
||||
"channel_info.archive_title": "Archive {term}",
|
||||
"channel_info.channel_auto_follow_threads": "Follow all threads in this channel",
|
||||
"channel_info.channel_auto_follow_threads_failed": "An error occurred trying to auto follow all threads in channel {displayName}",
|
||||
"channel_info.channel_files": "Files",
|
||||
"channel_info.close": "Close",
|
||||
"channel_info.close_dm": "Close direct message",
|
||||
|
|
|
|||
12
package-lock.json
generated
12
package-lock.json
generated
|
|
@ -165,7 +165,7 @@
|
|||
"jest-cli": "29.6.2",
|
||||
"jetifier": "2.0.0",
|
||||
"metro-react-native-babel-preset": "0.77.0",
|
||||
"mmjstool": "github:mattermost/mattermost-utilities#e65ab00f22628cbdee736fd2e4f192f07225e82d",
|
||||
"mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||
"mock-async-storage": "2.2.0",
|
||||
"nock": "13.3.2",
|
||||
"patch-package": "8.0.0",
|
||||
|
|
@ -17464,8 +17464,8 @@
|
|||
},
|
||||
"node_modules/mmjstool": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#e65ab00f22628cbdee736fd2e4f192f07225e82d",
|
||||
"integrity": "sha512-tY5XH26LwPztivGSbUWWaxZCkp/cKWTrtWBUnG8L1J+QIcLua8hzyZBe+VGDGdoHUJn4PbGpawJlUyoiC3r9Lg==",
|
||||
"resolved": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||
"integrity": "sha512-SFAbT+eN1mvgSfRTe8k6IMKVWbhGItTJtxZ+Pt0mX+fe8pakB3MkIkWzHBHVnEDI9Ek9kmQFGF1aZwzKFHXyYQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"estree-walk": "^2.2.0",
|
||||
|
|
@ -35875,10 +35875,10 @@
|
|||
}
|
||||
},
|
||||
"mmjstool": {
|
||||
"version": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#e65ab00f22628cbdee736fd2e4f192f07225e82d",
|
||||
"integrity": "sha512-tY5XH26LwPztivGSbUWWaxZCkp/cKWTrtWBUnG8L1J+QIcLua8hzyZBe+VGDGdoHUJn4PbGpawJlUyoiC3r9Lg==",
|
||||
"version": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||
"integrity": "sha512-SFAbT+eN1mvgSfRTe8k6IMKVWbhGItTJtxZ+Pt0mX+fe8pakB3MkIkWzHBHVnEDI9Ek9kmQFGF1aZwzKFHXyYQ==",
|
||||
"dev": true,
|
||||
"from": "mmjstool@github:mattermost/mattermost-utilities#e65ab00f22628cbdee736fd2e4f192f07225e82d",
|
||||
"from": "mmjstool@github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||
"requires": {
|
||||
"estree-walk": "^2.2.0",
|
||||
"filehound": "^1.17.5",
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@
|
|||
"jest-cli": "29.6.2",
|
||||
"jetifier": "2.0.0",
|
||||
"metro-react-native-babel-preset": "0.77.0",
|
||||
"mmjstool": "github:mattermost/mattermost-utilities#e65ab00f22628cbdee736fd2e4f192f07225e82d",
|
||||
"mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||
"mock-async-storage": "2.2.0",
|
||||
"nock": "13.3.2",
|
||||
"patch-package": "8.0.0",
|
||||
|
|
|
|||
1
types/api/channels.d.ts
vendored
1
types/api/channels.d.ts
vendored
|
|
@ -17,6 +17,7 @@ type ChannelNotifyProps = {
|
|||
mark_unread: 'all' | 'mention';
|
||||
push: NotificationLevel;
|
||||
ignore_channel_mentions: 'default' | 'off' | 'on';
|
||||
channel_auto_follow_threads: 'on' | 'off';
|
||||
push_threads: 'all' | 'mention';
|
||||
};
|
||||
type Channel = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue