Merge branch 'main' into MM-53902-cont
This commit is contained in:
commit
a8fe9794d0
38 changed files with 466 additions and 315 deletions
32
NOTICE.txt
32
NOTICE.txt
|
|
@ -667,6 +667,38 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## @voximplant/react-native-foreground-service
|
||||
|
||||
This product contains a modified version of '@voximplant/react-native-foreground-service' by Voximplant.
|
||||
|
||||
A foreground service performs some operation that is noticeable to the user.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/voximplant/react-native-foreground-service
|
||||
|
||||
* LICENSE: MIT License
|
||||
|
||||
Copyright (c) 2019 Zingaya, Inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ android {
|
|||
applicationId "com.mattermost.rnbeta"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 489
|
||||
versionName "2.9.0"
|
||||
versionCode 492
|
||||
versionName "2.10.0"
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,3 +77,11 @@ export const removeLastViewedChannelIdAndServer = async () => {
|
|||
export const removeLastViewedThreadIdAndServer = async () => {
|
||||
return storeGlobal(GLOBAL_IDENTIFIERS.LAST_VIEWED_THREAD, null, false);
|
||||
};
|
||||
|
||||
export const storePushDisabledInServerAcknowledged = async (serverUrl: string) => {
|
||||
return storeGlobal(`${GLOBAL_IDENTIFIERS.PUSH_DISABLED_ACK}${serverUrl}`, 'true', false);
|
||||
};
|
||||
|
||||
export const removePushDisabledInServerAcknowledged = async (serverUrl: string) => {
|
||||
return storeGlobal(`${GLOBAL_IDENTIFIERS.PUSH_DISABLED_ACK}${serverUrl}`, null, false);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ type MarkdownProps = {
|
|||
textStyles?: MarkdownTextStyles;
|
||||
theme: Theme;
|
||||
value?: string;
|
||||
onLinkLongPress?: (url?: string) => void;
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
|
|
@ -133,7 +134,7 @@ const Markdown = ({
|
|||
enableInlineLatex, enableLatex, maxNodes,
|
||||
imagesMetadata, isEdited, isReplyPost, isSearchResult, layoutHeight, layoutWidth,
|
||||
location, mentionKeys, minimumHashtagLength = 3, onPostPress, postId, searchPatterns,
|
||||
textStyles = {}, theme, value = '', baseParagraphStyle,
|
||||
textStyles = {}, theme, value = '', baseParagraphStyle, onLinkLongPress,
|
||||
}: MarkdownProps) => {
|
||||
const style = getStyleSheet(theme);
|
||||
const managedConfig = useManagedConfig<ManagedConfig>();
|
||||
|
|
@ -402,7 +403,10 @@ const Markdown = ({
|
|||
|
||||
const renderLink = ({children, href}: {children: ReactElement; href: string}) => {
|
||||
return (
|
||||
<MarkdownLink href={href}>
|
||||
<MarkdownLink
|
||||
href={href}
|
||||
onLinkLongPress={onLinkLongPress}
|
||||
>
|
||||
{children}
|
||||
</MarkdownLink>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ type MarkdownLinkProps = {
|
|||
experimentalNormalizeMarkdownLinks: string;
|
||||
href: string;
|
||||
siteURL: string;
|
||||
onLinkLongPress?: (url?: string) => void;
|
||||
}
|
||||
|
||||
const style = StyleSheet.create({
|
||||
|
|
@ -44,7 +45,7 @@ const parseLinkLiteral = (literal: string) => {
|
|||
return parsed.href;
|
||||
};
|
||||
|
||||
const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteURL}: MarkdownLinkProps) => {
|
||||
const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteURL, onLinkLongPress}: MarkdownLinkProps) => {
|
||||
const intl = useIntl();
|
||||
const {bottom} = useSafeAreaInsets();
|
||||
const managedConfig = useManagedConfig<ManagedConfig>();
|
||||
|
|
@ -109,6 +110,11 @@ const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteU
|
|||
|
||||
const handleLongPress = useCallback(() => {
|
||||
if (managedConfig?.copyAndPasteProtection !== 'true') {
|
||||
if (onLinkLongPress) {
|
||||
onLinkLongPress(href);
|
||||
return;
|
||||
}
|
||||
|
||||
const renderContent = () => {
|
||||
return (
|
||||
<View
|
||||
|
|
@ -145,7 +151,7 @@ const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteU
|
|||
theme,
|
||||
});
|
||||
}
|
||||
}, [managedConfig, intl, bottom, theme]);
|
||||
}, [managedConfig, intl, bottom, theme, onLinkLongPress]);
|
||||
|
||||
const renderChildren = experimentalNormalizeMarkdownLinks ? parseChildren() : children;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ type Props = {
|
|||
currentUserId?: string;
|
||||
currentUsername?: string;
|
||||
location: string;
|
||||
post: Post;
|
||||
post: Post | null;
|
||||
showJoinLeave: boolean;
|
||||
testID?: string;
|
||||
theme: Theme;
|
||||
|
|
@ -65,23 +65,11 @@ const CombinedUserActivity = ({
|
|||
const intl = useIntl();
|
||||
const isTablet = useIsTablet();
|
||||
const serverUrl = useServerUrl();
|
||||
const itemTestID = `${testID}.${post.id}`;
|
||||
const textStyles = getMarkdownTextStyles(theme);
|
||||
const {allUserIds, allUsernames, messageData} = post.props.user_activity;
|
||||
const styles = getStyleSheet(theme);
|
||||
const content = [];
|
||||
const removedUserIds: string[] = [];
|
||||
|
||||
const loadUserProfiles = () => {
|
||||
if (allUserIds.length) {
|
||||
fetchMissingProfilesByIds(serverUrl, allUserIds);
|
||||
}
|
||||
|
||||
if (allUsernames.length) {
|
||||
fetchMissingProfilesByUsernames(serverUrl, allUsernames);
|
||||
}
|
||||
};
|
||||
|
||||
const getUsernames = (userIds: string[]) => {
|
||||
const someone = intl.formatMessage({id: 'channel_loader.someone', defaultMessage: 'Someone'});
|
||||
const you = intl.formatMessage({id: 'combined_system_message.you', defaultMessage: 'You'});
|
||||
|
|
@ -120,6 +108,9 @@ const CombinedUserActivity = ({
|
|||
}, [post, canDelete, isTablet, intl, location]);
|
||||
|
||||
const renderMessage = (postType: string, userIds: string[], actorId: string) => {
|
||||
if (!post) {
|
||||
return null;
|
||||
}
|
||||
let actor = '';
|
||||
if (usernamesById[actorId]) {
|
||||
actor = `@${usernamesById[actorId]}`;
|
||||
|
|
@ -177,9 +168,26 @@ const CombinedUserActivity = ({
|
|||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadUserProfiles();
|
||||
}, [allUserIds, allUsernames]);
|
||||
if (!post) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {allUserIds, allUsernames} = post.props.user_activity;
|
||||
if (allUserIds.length) {
|
||||
fetchMissingProfilesByIds(serverUrl, allUserIds);
|
||||
}
|
||||
|
||||
if (allUsernames.length) {
|
||||
fetchMissingProfilesByUsernames(serverUrl, allUsernames);
|
||||
}
|
||||
}, [post?.props.user_activity.allUserIds, post?.props.user_activity.allUsernames]);
|
||||
|
||||
if (!post) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const itemTestID = `${testID}.${post.id}`;
|
||||
const {messageData} = post.props.user_activity;
|
||||
for (const message of messageData) {
|
||||
const {postType, actorId} = message;
|
||||
const userIds = new Set<string>(message.userIds);
|
||||
|
|
|
|||
|
|
@ -28,24 +28,29 @@ const withCombinedPosts = withObservables(['postId'], ({database, postId}: WithD
|
|||
|
||||
// Columns observed: `props` is used by `usernamesById`. `message` is used by generateCombinedPost.
|
||||
const posts = queryPostsById(database, postIds).observeWithColumns(['props', 'message']);
|
||||
const post = posts.pipe(map((ps) => generateCombinedPost(postId, ps)));
|
||||
const post = posts.pipe(map((ps) => (ps.length ? generateCombinedPost(postId, ps) : null)));
|
||||
const canDelete = combineLatest([posts, currentUser]).pipe(
|
||||
switchMap(([ps, u]) => (ps.length ? observePermissionForPost(database, ps[0], u, Permissions.DELETE_OTHERS_POSTS, false) : of$(false))),
|
||||
);
|
||||
|
||||
const usernamesById = post.pipe(
|
||||
switchMap(
|
||||
(p) => queryUsersByIdsOrUsernames(database, p.props.user_activity.allUserIds, p.props.user_activity.allUsernames).observeWithColumns(['username']).
|
||||
pipe(
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
switchMap((users) => {
|
||||
(p) => {
|
||||
if (!p) {
|
||||
return of$<Record<string, string>>({});
|
||||
}
|
||||
return queryUsersByIdsOrUsernames(database, p.props.user_activity.allUserIds, p.props.user_activity.allUsernames).observeWithColumns(['username']).
|
||||
pipe(
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
return of$(users.reduce((acc: Record<string, string>, user) => {
|
||||
acc[user.id] = user.username;
|
||||
return acc;
|
||||
}, {}));
|
||||
}),
|
||||
),
|
||||
switchMap((users) => {
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
return of$(users.reduce((acc: Record<string, string>, user) => {
|
||||
acc[user.id] = user.username;
|
||||
return acc;
|
||||
}, {}));
|
||||
}),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
import {Modal, StyleSheet, useWindowDimensions, View} from 'react-native';
|
||||
import {Modal, useWindowDimensions} from 'react-native';
|
||||
|
||||
import HighlightItem from './item';
|
||||
|
||||
|
|
@ -11,11 +11,10 @@ type Props = {
|
|||
itemBounds: TutorialItemBounds;
|
||||
itemBorderRadius?: number;
|
||||
onDismiss: () => void;
|
||||
onLayout: () => void;
|
||||
onShow?: () => void;
|
||||
}
|
||||
|
||||
const TutorialHighlight = ({children, itemBounds, itemBorderRadius, onDismiss, onLayout, onShow}: Props) => {
|
||||
const TutorialHighlight = ({children, itemBounds, itemBorderRadius, onDismiss, onShow}: Props) => {
|
||||
const {width, height} = useWindowDimensions();
|
||||
|
||||
const handleShowTutorial = useCallback(() => {
|
||||
|
|
@ -26,19 +25,13 @@ const TutorialHighlight = ({children, itemBounds, itemBorderRadius, onDismiss, o
|
|||
|
||||
return (
|
||||
<Modal
|
||||
visible={true}
|
||||
visible={itemBounds.endX > 0}
|
||||
transparent={true}
|
||||
animationType='fade'
|
||||
onDismiss={onDismiss}
|
||||
onRequestClose={onDismiss}
|
||||
testID='tutorial_highlight'
|
||||
>
|
||||
<View
|
||||
style={StyleSheet.absoluteFill}
|
||||
pointerEvents='box-none'
|
||||
onLayout={onLayout}
|
||||
/>
|
||||
{itemBounds.endX > 0 &&
|
||||
<HighlightItem
|
||||
borderRadius={itemBorderRadius}
|
||||
itemBounds={itemBounds}
|
||||
|
|
@ -47,7 +40,6 @@ const TutorialHighlight = ({children, itemBounds, itemBorderRadius, onDismiss, o
|
|||
width={width}
|
||||
onLayout={handleShowTutorial}
|
||||
/>
|
||||
}
|
||||
{children}
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ type Props = {
|
|||
rightDecorator?: React.ReactNode;
|
||||
onUserPress?: (user: UserProfile | UserModel) => void;
|
||||
onUserLongPress?: (user: UserProfile | UserModel) => void;
|
||||
onLayout?: () => void;
|
||||
disabled?: boolean;
|
||||
viewRef?: React.LegacyRef<View>;
|
||||
padding?: number;
|
||||
|
|
@ -102,6 +103,7 @@ const UserItem = ({
|
|||
locale,
|
||||
teammateNameDisplay,
|
||||
rightDecorator,
|
||||
onLayout,
|
||||
onUserPress,
|
||||
onUserLongPress,
|
||||
disabled = false,
|
||||
|
|
@ -159,6 +161,7 @@ const UserItem = ({
|
|||
onPress={onPress}
|
||||
onLongPress={onLongPress}
|
||||
disabled={!(onUserPress || onUserLongPress)}
|
||||
onLayout={onLayout}
|
||||
>
|
||||
<View
|
||||
ref={viewRef}
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ exports[`components/channel_list_row should show no results 1`] = `
|
|||
collapsable={false}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onLayout={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
|
|
@ -424,6 +425,7 @@ exports[`components/channel_list_row should show results and tutorial 1`] = `
|
|||
collapsable={false}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onLayout={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
|
|
@ -551,79 +553,8 @@ exports[`components/channel_list_row should show results and tutorial 1`] = `
|
|||
onRequestClose={[Function]}
|
||||
testID="tutorial_highlight"
|
||||
transparent={true}
|
||||
visible={true}
|
||||
>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
pointerEvents="box-none"
|
||||
style={
|
||||
{
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<View
|
||||
pointerEvents="none"
|
||||
style={
|
||||
[
|
||||
{
|
||||
"alignItems": "center",
|
||||
"bottom": 0,
|
||||
"justifyContent": "center",
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
testID="tutorial_swipe_left"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
[
|
||||
{
|
||||
"alignItems": "center",
|
||||
"backgroundColor": "#ffffff",
|
||||
"borderRadius": 8,
|
||||
"height": 161,
|
||||
"padding": 16,
|
||||
"width": 247,
|
||||
},
|
||||
{
|
||||
"top": -74,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<long_press_illustration.svg />
|
||||
<Text
|
||||
style={
|
||||
[
|
||||
{
|
||||
"color": "#3f4350",
|
||||
"fontFamily": "Metropolis-SemiBold",
|
||||
"fontSize": 16,
|
||||
"fontWeight": "600",
|
||||
"lineHeight": 24,
|
||||
"marginTop": 8,
|
||||
"paddingHorizontal": 12,
|
||||
"textAlign": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Long-press on an item to view a user's profile
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
visible={false}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
onFocusCapture={[Function]}
|
||||
|
|
@ -790,6 +721,7 @@ exports[`components/channel_list_row should show results no tutorial 1`] = `
|
|||
collapsable={false}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onLayout={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
|
|
@ -1108,6 +1040,7 @@ exports[`components/channel_list_row should show results no tutorial 2 users 1`]
|
|||
collapsable={false}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onLayout={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
|
|
@ -1299,6 +1232,7 @@ exports[`components/channel_list_row should show results no tutorial 2 users 1`]
|
|||
collapsable={false}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onLayout={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
|
|
|
|||
|
|
@ -155,8 +155,10 @@ function UserListRow({
|
|||
}, [isChannelAdmin, showManageMode, theme]);
|
||||
|
||||
const onLayout = useCallback(() => {
|
||||
startTutorial();
|
||||
}, []);
|
||||
if (showTutorial) {
|
||||
startTutorial();
|
||||
}
|
||||
}, [showTutorial]);
|
||||
|
||||
const icon = useMemo(() => {
|
||||
if (!selectable && !selected) {
|
||||
|
|
@ -190,17 +192,19 @@ function UserListRow({
|
|||
viewRef={viewRef}
|
||||
padding={20}
|
||||
includeMargin={includeMargin}
|
||||
onLayout={onLayout}
|
||||
/>
|
||||
{showTutorial &&
|
||||
<TutorialHighlight
|
||||
itemBounds={itemBounds}
|
||||
onDismiss={handleDismissTutorial}
|
||||
onLayout={onLayout}
|
||||
>
|
||||
{Boolean(itemBounds.endX) &&
|
||||
<TutorialLongPress
|
||||
message={formatMessage({id: 'user.tutorial.long_press', defaultMessage: "Long-press on an item to view a user's profile"})}
|
||||
style={isTablet ? style.tutorialTablet : style.tutorial}
|
||||
/>
|
||||
}
|
||||
</TutorialHighlight>
|
||||
}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ export const GLOBAL_IDENTIFIERS = {
|
|||
ONBOARDING: 'onboarding',
|
||||
LAST_VIEWED_CHANNEL: 'lastViewedChannel',
|
||||
LAST_VIEWED_THREAD: 'lastViewedThread',
|
||||
PUSH_DISABLED_ACK: 'pushDisabledAck',
|
||||
};
|
||||
|
||||
export enum OperationType {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ export default class CategoryModel extends Model implements CategoryInterface {
|
|||
toCategoryWithChannels = async (): Promise<CategoryWithChannels> => {
|
||||
const categoryChannels = await this.categoryChannels.fetch();
|
||||
const orderedChannelIds = categoryChannels.sort((a, b) => {
|
||||
return b.sortOrder - a.sortOrder;
|
||||
return a.sortOrder - b.sortOrder;
|
||||
}).map((cc) => cc.channelId);
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import CookieManager, {type Cookie} from '@react-native-cookies/cookies';
|
|||
import {AppState, type AppStateStatus, DeviceEventEmitter, Platform} from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
|
||||
import {storeOnboardingViewedValue} from '@actions/app/global';
|
||||
import {removePushDisabledInServerAcknowledged, storeOnboardingViewedValue} from '@actions/app/global';
|
||||
import {cancelSessionNotification, logout, scheduleSessionNotification} from '@actions/remote/session';
|
||||
import {Events, Launch} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
|
|
@ -22,6 +22,7 @@ import {getThemeFromState} from '@screens/navigation';
|
|||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import {deleteFileCache, deleteFileCacheByDir} from '@utils/file';
|
||||
import {isMainActivity} from '@utils/helpers';
|
||||
import {urlSafeBase64Encode} from '@utils/security';
|
||||
import {addNewServer} from '@utils/server';
|
||||
|
||||
import type {LaunchType} from '@typings/launch';
|
||||
|
|
@ -121,6 +122,7 @@ class SessionManager {
|
|||
WebsocketManager.invalidateClient(serverUrl);
|
||||
|
||||
if (removeServer) {
|
||||
await removePushDisabledInServerAcknowledged(urlSafeBase64Encode(serverUrl));
|
||||
await DatabaseManager.destroyServerDatabase(serverUrl);
|
||||
} else {
|
||||
await DatabaseManager.deleteServerDatabase(serverUrl);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,22 @@ export const getDontAskForReview = async () => {
|
|||
return Boolean(records?.[0]?.value);
|
||||
};
|
||||
|
||||
export const getPushDisabledInServerAcknowledged = async (serverDomainString: string) => {
|
||||
const records = await queryGlobalValue(`${GLOBAL_IDENTIFIERS.PUSH_DISABLED_ACK}${serverDomainString}`)?.fetch();
|
||||
return Boolean(records?.[0]?.value);
|
||||
};
|
||||
|
||||
export const observePushDisabledInServerAcknowledged = (serverDomainString: string) => {
|
||||
const query = queryGlobalValue(`${GLOBAL_IDENTIFIERS.PUSH_DISABLED_ACK}${serverDomainString}`);
|
||||
if (!query) {
|
||||
return of$(false);
|
||||
}
|
||||
return query.observe().pipe(
|
||||
switchMap((result) => (result.length ? result[0].observe() : of$(false))),
|
||||
switchMap((v) => of$(Boolean(v))),
|
||||
);
|
||||
};
|
||||
|
||||
export const getFirstLaunch = async () => {
|
||||
const records = await queryGlobalValue(GLOBAL_IDENTIFIERS.FIRST_LAUNCH)?.fetch();
|
||||
if (!records?.[0]?.value) {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,29 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {useManagedConfig} from '@mattermost/react-native-emm';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import moment from 'moment';
|
||||
import React, {useMemo} from 'react';
|
||||
import {Text, View} from 'react-native';
|
||||
import React, {useCallback, useMemo} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Platform, StyleSheet, Text, View} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
|
||||
import CustomStatusExpiry from '@components/custom_status/custom_status_expiry';
|
||||
import Emoji from '@components/emoji';
|
||||
import FormattedDate from '@components/formatted_date';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import Markdown from '@components/markdown';
|
||||
import SlideUpPanelItem, {ITEM_HEIGHT} from '@components/slide_up_panel_item';
|
||||
import TouchableWithFeedback from '@components/touchable_with_feedback';
|
||||
import {Screens} from '@constants';
|
||||
import {SNACK_BAR_TYPE} from '@constants/snack_bar';
|
||||
import {ANDROID_33, OS_VERSION} from '@constants/versions';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {bottomSheet, dismissBottomSheet} from '@screens/navigation';
|
||||
import {bottomSheetSnapPoint} from '@utils/helpers';
|
||||
import {getMarkdownBlockStyles, getMarkdownTextStyles} from '@utils/markdown';
|
||||
import {showSnackBar} from '@utils/snack_bar';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
|
|
@ -66,8 +77,30 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
},
|
||||
}));
|
||||
|
||||
const style = StyleSheet.create({
|
||||
bottomSheet: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const headerTestId = 'channel_info.extra.header';
|
||||
|
||||
const onCopy = async (text: string, isLink?: boolean) => {
|
||||
Clipboard.setString(text);
|
||||
await dismissBottomSheet();
|
||||
if ((Platform.OS === OS_VERSION.ANDROID && Number(Platform.Version) < ANDROID_33) || Platform.OS === OS_VERSION.IOS) {
|
||||
showSnackBar({
|
||||
barType: isLink ? SNACK_BAR_TYPE.LINK_COPIED : SNACK_BAR_TYPE.TEXT_COPIED,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const Extra = ({channelId, createdAt, createdBy, customStatus, header, isCustomStatusEnabled}: Props) => {
|
||||
const intl = useIntl();
|
||||
const {bottom} = useSafeAreaInsets();
|
||||
const theme = useTheme();
|
||||
const managedConfig = useManagedConfig<ManagedConfig>();
|
||||
|
||||
const styles = getStyleSheet(theme);
|
||||
const blockStyles = getMarkdownBlockStyles(theme);
|
||||
const textStyles = getMarkdownTextStyles(theme);
|
||||
|
|
@ -81,6 +114,70 @@ const Extra = ({channelId, createdAt, createdBy, customStatus, header, isCustomS
|
|||
),
|
||||
}), [createdAt, createdBy, theme]);
|
||||
|
||||
const handleLongPress = useCallback((url?: string) => {
|
||||
if (managedConfig?.copyAndPasteProtection !== 'true') {
|
||||
const renderContent = () => (
|
||||
<View
|
||||
testID={`${headerTestId}.bottom_sheet`}
|
||||
style={style.bottomSheet}
|
||||
>
|
||||
<SlideUpPanelItem
|
||||
leftIcon='content-copy'
|
||||
onPress={() => {
|
||||
onCopy(header!);
|
||||
}}
|
||||
testID={`${headerTestId}.bottom_sheet.copy_header_text`}
|
||||
text={intl.formatMessage({
|
||||
id: 'mobile.markdown.copy_header',
|
||||
defaultMessage: 'Copy header text',
|
||||
})}
|
||||
/>
|
||||
{Boolean(url) && (
|
||||
<SlideUpPanelItem
|
||||
leftIcon='link-variant'
|
||||
onPress={() => {
|
||||
onCopy(url!, true);
|
||||
}}
|
||||
testID={`${headerTestId}.bottom_sheet.copy_url`}
|
||||
text={intl.formatMessage({
|
||||
id: 'mobile.markdown.link.copy_url',
|
||||
defaultMessage: 'Copy URL',
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
<SlideUpPanelItem
|
||||
destructive={true}
|
||||
leftIcon='cancel'
|
||||
onPress={() => {
|
||||
dismissBottomSheet();
|
||||
}}
|
||||
testID={`${headerTestId}.bottom_sheet.cancel`}
|
||||
text={intl.formatMessage({
|
||||
id: 'mobile.post.cancel',
|
||||
defaultMessage: 'Cancel',
|
||||
})}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
bottomSheet({
|
||||
closeButtonId: 'close-markdown-link',
|
||||
renderContent,
|
||||
snapPoints: [1, bottomSheetSnapPoint(url ? 3 : 2, ITEM_HEIGHT, bottom)],
|
||||
title: intl.formatMessage({id: 'post.options.title', defaultMessage: 'Options'}),
|
||||
theme,
|
||||
});
|
||||
}
|
||||
}, [
|
||||
header,
|
||||
bottom,
|
||||
theme,
|
||||
intl.formatMessage,
|
||||
managedConfig?.copyAndPasteProtection,
|
||||
]);
|
||||
|
||||
const touchableHandleLongPress = useCallback(() => handleLongPress(), [handleLongPress]);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{isCustomStatusEnabled && Boolean(customStatus) &&
|
||||
|
|
@ -131,25 +228,32 @@ const Extra = ({channelId, createdAt, createdBy, customStatus, header, isCustomS
|
|||
id='channel_info.header'
|
||||
defaultMessage='Header:'
|
||||
style={styles.extraHeading}
|
||||
testID='channel_info.extra.header'
|
||||
/>
|
||||
<Markdown
|
||||
channelId={channelId}
|
||||
baseTextStyle={styles.header}
|
||||
blockStyles={blockStyles}
|
||||
disableBlockQuote={true}
|
||||
disableCodeBlock={true}
|
||||
disableGallery={true}
|
||||
disableHeading={true}
|
||||
disableTables={true}
|
||||
location={Screens.CHANNEL_INFO}
|
||||
textStyles={textStyles}
|
||||
layoutHeight={48}
|
||||
layoutWidth={100}
|
||||
theme={theme}
|
||||
imagesMetadata={headerMetadata}
|
||||
value={header}
|
||||
testID={headerTestId}
|
||||
/>
|
||||
<TouchableWithFeedback
|
||||
type='opacity'
|
||||
activeOpacity={0.8}
|
||||
onLongPress={touchableHandleLongPress}
|
||||
>
|
||||
<Markdown
|
||||
channelId={channelId}
|
||||
baseTextStyle={styles.header}
|
||||
blockStyles={blockStyles}
|
||||
disableBlockQuote={true}
|
||||
disableCodeBlock={true}
|
||||
disableGallery={true}
|
||||
disableHeading={true}
|
||||
disableTables={true}
|
||||
location={Screens.CHANNEL_INFO}
|
||||
textStyles={textStyles}
|
||||
layoutHeight={48}
|
||||
layoutWidth={100}
|
||||
theme={theme}
|
||||
imagesMetadata={headerMetadata}
|
||||
value={header}
|
||||
onLinkLongPress={handleLongPress}
|
||||
/>
|
||||
</TouchableWithFeedback>
|
||||
</View>
|
||||
}
|
||||
{Boolean(createdAt && createdBy) &&
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import {PUSH_PROXY_STATUS_VERIFIED} from '@constants/push_proxy';
|
||||
import {PUSH_PROXY_RESPONSE_NOT_AVAILABLE, PUSH_PROXY_STATUS_VERIFIED} from '@constants/push_proxy';
|
||||
import {renderWithIntl} from '@test/intl-test-helper';
|
||||
|
||||
import Header from './header';
|
||||
|
|
@ -22,4 +22,18 @@ describe('components/channel_list/header', () => {
|
|||
|
||||
expect(toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Push notifications disabled show alert icon', () => {
|
||||
const wrapper = renderWithIntl(
|
||||
<Header
|
||||
pushProxyStatus={PUSH_PROXY_RESPONSE_NOT_AVAILABLE}
|
||||
canCreateChannels={true}
|
||||
canJoinChannels={true}
|
||||
canInvitePeople={true}
|
||||
displayName={'Test!'}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper.getByTestId('channel_list_header.push_alert')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ const ChannelListHeader = ({
|
|||
>
|
||||
{serverDisplayName}
|
||||
</Text>
|
||||
{(pushProxyStatus !== PUSH_PROXY_STATUS_VERIFIED) && (
|
||||
{pushProxyStatus !== PUSH_PROXY_STATUS_VERIFIED && (
|
||||
<TouchableWithFeedback
|
||||
onPress={onPushAlertPress}
|
||||
testID='channel_list_header.push_alert'
|
||||
|
|
|
|||
|
|
@ -14,26 +14,26 @@ type PlusMenuItemProps = {
|
|||
const PlusMenuItem = ({pickerAction, onPress}: PlusMenuItemProps) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const menuItems = {
|
||||
const menuItems: {[key: string]: Omit<React.ComponentProps<typeof SlideUpPanelItem>, 'onPress'>} = {
|
||||
browseChannels: {
|
||||
icon: 'globe',
|
||||
leftIcon: 'globe',
|
||||
text: intl.formatMessage({id: 'plus_menu.browse_channels.title', defaultMessage: 'Browse Channels'}),
|
||||
testID: 'plus_menu_item.browse_channels',
|
||||
},
|
||||
|
||||
createNewChannel: {
|
||||
icon: 'plus',
|
||||
leftIcon: 'plus',
|
||||
text: intl.formatMessage({id: 'plus_menu.create_new_channel.title', defaultMessage: 'Create New Channel'}),
|
||||
testID: 'plus_menu_item.create_new_channel',
|
||||
},
|
||||
|
||||
openDirectMessage: {
|
||||
icon: 'account-outline',
|
||||
leftIcon: 'account-outline',
|
||||
text: intl.formatMessage({id: 'plus_menu.open_direct_message.title', defaultMessage: 'Open a Direct Message'}),
|
||||
testID: 'plus_menu_item.open_direct_message',
|
||||
},
|
||||
invitePeopleToTeam: {
|
||||
icon: 'account-plus-outline',
|
||||
leftIcon: 'account-plus-outline',
|
||||
text: intl.formatMessage({id: 'plus_menu.invite_people_to_team.title', defaultMessage: 'Invite people to the team'}),
|
||||
testID: 'plus_menu_item.invite_people_to_team',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import React, {useCallback, useEffect, useImperativeHandle, useRef, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {StyleSheet} from 'react-native';
|
||||
import {Dimensions, StyleSheet} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
|
||||
import ServerIcon from '@components/server_icon';
|
||||
|
|
@ -27,7 +27,8 @@ export type ServersRef = {
|
|||
openServers: () => void;
|
||||
}
|
||||
|
||||
export const SERVER_ITEM_HEIGHT = 72;
|
||||
export const SERVER_ITEM_HEIGHT = 75;
|
||||
export const PUSH_ALERT_TEXT_HEIGHT = 42;
|
||||
const subscriptions: Map<string, UnreadSubscription> = new Map();
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
|
@ -116,12 +117,18 @@ const Servers = React.forwardRef<ServersRef>((_, ref) => {
|
|||
<ServerList servers={registeredServers.current!}/>
|
||||
);
|
||||
};
|
||||
const maxScreenHeight = Math.ceil(0.6 * Dimensions.get('window').height);
|
||||
const maxSnapPoint = Math.min(
|
||||
maxScreenHeight,
|
||||
bottomSheetSnapPoint(registeredServers.current.length, SERVER_ITEM_HEIGHT, bottom) + TITLE_HEIGHT + BUTTON_HEIGHT +
|
||||
(registeredServers.current.filter((s: ServersModel) => s.lastActiveAt).length * PUSH_ALERT_TEXT_HEIGHT),
|
||||
);
|
||||
|
||||
const snapPoints: BottomSheetProps['snapPoints'] = [
|
||||
1,
|
||||
bottomSheetSnapPoint(Math.min(2.5, registeredServers.current.length), 72, bottom) + TITLE_HEIGHT + BUTTON_HEIGHT,
|
||||
maxSnapPoint,
|
||||
];
|
||||
if (registeredServers.current.length > 1) {
|
||||
if (maxSnapPoint === maxScreenHeight) {
|
||||
snapPoints.push('80%');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@
|
|||
import {BottomSheetFlatList} from '@gorhom/bottom-sheet';
|
||||
import React, {useCallback, useMemo} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {FlatList, type ListRenderItemInfo, StyleSheet, View} from 'react-native';
|
||||
import {FlatList, StyleSheet, View, type ListRenderItemInfo} from 'react-native';
|
||||
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
import {BUTTON_HEIGHT} from '@screens/bottom_sheet';
|
||||
import BottomSheetContent from '@screens/bottom_sheet/content';
|
||||
import {addNewServer} from '@utils/server';
|
||||
|
||||
|
|
@ -29,6 +30,9 @@ const styles = StyleSheet.create({
|
|||
contentContainer: {
|
||||
marginVertical: 4,
|
||||
},
|
||||
serverList: {
|
||||
marginBottom: BUTTON_HEIGHT,
|
||||
},
|
||||
});
|
||||
|
||||
const keyExtractor = (item: ServersModel) => item.url;
|
||||
|
|
@ -68,6 +72,7 @@ const ServerList = ({servers}: Props) => {
|
|||
<View style={[styles.container, {marginTop: isTablet ? 12 : 0}]}>
|
||||
<List
|
||||
data={servers}
|
||||
style={styles.serverList}
|
||||
renderItem={renderServer}
|
||||
keyExtractor={keyExtractor}
|
||||
contentContainerStyle={styles.contentContainer}
|
||||
|
|
|
|||
|
|
@ -213,9 +213,11 @@ const ServerItem = ({
|
|||
};
|
||||
|
||||
const onLayout = useCallback(() => {
|
||||
swipeable.current?.close();
|
||||
startTutorial();
|
||||
}, []);
|
||||
if (showTutorial) {
|
||||
swipeable.current?.close();
|
||||
startTutorial();
|
||||
}
|
||||
}, [showTutorial]);
|
||||
|
||||
const containerStyle = useMemo(() => {
|
||||
const style: StyleProp<ViewStyle> = [styles.container];
|
||||
|
|
@ -390,6 +392,7 @@ const ServerItem = ({
|
|||
style={containerStyle}
|
||||
ref={viewRef}
|
||||
testID={serverItemTestId}
|
||||
onLayout={onLayout}
|
||||
>
|
||||
<RectButton
|
||||
onPress={onServerPressed}
|
||||
|
|
@ -474,13 +477,14 @@ const ServerItem = ({
|
|||
itemBounds={itemBounds}
|
||||
onDismiss={handleDismissTutorial}
|
||||
onShow={handleShowTutorial}
|
||||
onLayout={onLayout}
|
||||
itemBorderRadius={8}
|
||||
>
|
||||
{Boolean(itemBounds.endX) &&
|
||||
<TutorialSwipeLeft
|
||||
message={intl.formatMessage({id: 'server.tutorial.swipe', defaultMessage: 'Swipe left on a server to see more actions'})}
|
||||
style={isTablet ? styles.tutorialTablet : styles.tutorial}
|
||||
/>
|
||||
}
|
||||
</TutorialHighlight>
|
||||
}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback, useMemo} from 'react';
|
||||
import React, {useCallback, useMemo, useState, useEffect} from 'react';
|
||||
|
||||
import {savePreference} from '@actions/remote/preference';
|
||||
import SettingContainer from '@components/settings/container';
|
||||
|
|
@ -26,17 +26,22 @@ const DisplayTheme = ({allowedThemeKeys, componentId, currentTeamId, currentUser
|
|||
const serverUrl = useServerUrl();
|
||||
const theme = useTheme();
|
||||
const initialTheme = useMemo(() => theme, [/* dependency array should remain empty */]);
|
||||
const [newTheme, setNewTheme] = useState<string | undefined>(undefined);
|
||||
|
||||
const close = () => popTopScreen(componentId);
|
||||
|
||||
const setThemePreference = useCallback((newTheme?: string) => {
|
||||
const allowedTheme = allowedThemeKeys.find((tk) => tk === newTheme);
|
||||
useEffect(() => {
|
||||
const differentTheme = theme.type?.toLowerCase() !== newTheme?.toLowerCase();
|
||||
|
||||
if (!differentTheme) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
setThemePreference();
|
||||
}, [newTheme]);
|
||||
|
||||
const setThemePreference = useCallback(() => {
|
||||
const allowedTheme = allowedThemeKeys.find((tk) => tk === newTheme);
|
||||
|
||||
const themeJson = Preferences.THEMES[allowedTheme as ThemeKey] || initialTheme;
|
||||
|
||||
|
|
@ -47,15 +52,20 @@ const DisplayTheme = ({allowedThemeKeys, componentId, currentTeamId, currentUser
|
|||
value: JSON.stringify(themeJson),
|
||||
};
|
||||
savePreference(serverUrl, [pref]);
|
||||
}, [allowedThemeKeys, currentTeamId, theme.type, serverUrl]);
|
||||
}, [allowedThemeKeys, currentTeamId, theme.type, serverUrl, newTheme]);
|
||||
|
||||
useAndroidHardwareBackHandler(componentId, setThemePreference);
|
||||
const onAndroidBack = () => {
|
||||
setThemePreference();
|
||||
close();
|
||||
};
|
||||
|
||||
useAndroidHardwareBackHandler(componentId, onAndroidBack);
|
||||
|
||||
return (
|
||||
<SettingContainer testID='theme_display_settings'>
|
||||
<ThemeTiles
|
||||
allowedThemeKeys={allowedThemeKeys}
|
||||
onThemeChange={setThemePreference}
|
||||
onThemeChange={setNewTheme}
|
||||
selectedTheme={theme.type}
|
||||
/>
|
||||
{initialTheme.type === 'custom' && (
|
||||
|
|
|
|||
|
|
@ -180,7 +180,9 @@ const sortChannelsByName = (notifyPropsPerChannel: Record<string, Partial<Channe
|
|||
export const sortChannels = (sorting: CategorySorting, channelsWithMyChannel: ChannelWithMyChannel[], notifyPropsPerChannel: Record<string, Partial<ChannelNotifyProps>>, locale: string) => {
|
||||
if (sorting === 'recent') {
|
||||
return channelsWithMyChannel.sort((cwmA, cwmB) => {
|
||||
return cwmB.myChannel.lastPostAt - cwmA.myChannel.lastPostAt;
|
||||
const a = Math.max(cwmA.myChannel.lastPostAt, cwmA.channel.createAt);
|
||||
const b = Math.max(cwmB.myChannel.lastPostAt, cwmB.channel.createAt);
|
||||
return b - a;
|
||||
}).map((cwm) => cwm.channel);
|
||||
} else if (sorting === 'manual') {
|
||||
return channelsWithMyChannel.sort((cwmA, cwmB) => {
|
||||
|
|
|
|||
|
|
@ -90,12 +90,27 @@ export const emitNotificationError = (type: 'Team' | 'Channel' | 'Post' | 'Conne
|
|||
|
||||
export const scheduleExpiredNotification = (serverUrl: string, session: Session, serverName: string, locale = DEFAULT_LOCALE) => {
|
||||
const expiresAt = session?.expires_at || 0;
|
||||
const expiresInDays = Math.ceil(Math.abs(moment.duration(moment().diff(moment(expiresAt))).asDays()));
|
||||
const expiresInHours = Math.ceil(Math.abs(moment.duration(moment().diff(moment(expiresAt))).asHours()));
|
||||
const expiresInDays = Math.floor(expiresInHours / 24); // Calculate expiresInDays
|
||||
const remainingHours = expiresInHours % 24; // Calculate remaining hours
|
||||
const intl = createIntl({locale, messages: getTranslations(locale)});
|
||||
const body = intl.formatMessage({
|
||||
id: 'mobile.session_expired',
|
||||
defaultMessage: 'Please log in to continue receiving notifications. Sessions for {siteName} are configured to expire every {daysCount, number} {daysCount, plural, one {day} other {days}}.',
|
||||
}, {siteName: serverName, daysCount: expiresInDays});
|
||||
let body = '';
|
||||
if (expiresInDays === 0) {
|
||||
body = intl.formatMessage({
|
||||
id: 'mobile.session_expired_hrs',
|
||||
defaultMessage: 'Please log in to continue receiving notifications. Sessions for {siteName} are configured to expire every {hoursCount, number} {hoursCount, plural, one {hour} other {hours}}.',
|
||||
}, {siteName: serverName, hoursCount: remainingHours});
|
||||
} else if (expiresInHours === 0) {
|
||||
body = intl.formatMessage({
|
||||
id: 'mobile.session_expired_days',
|
||||
defaultMessage: 'Please log in to continue receiving notifications. Sessions for {siteName} are configured to expire every {daysCount, number} {daysCount, plural, one {day} other {days}}.',
|
||||
}, {siteName: serverName, daysCount: expiresInDays});
|
||||
} else {
|
||||
body = intl.formatMessage({
|
||||
id: 'mobile.session_expired_days_hrs',
|
||||
defaultMessage: 'Please log in to continue receiving notifications. Sessions for {siteName} are configured to expire every {daysCount, number} {daysCount, plural, one {day} other {days}} and {hoursCount, number} {hoursCount, plural, one {hour} other {hours}}.',
|
||||
}, {siteName: serverName, daysCount: expiresInDays, hoursCount: remainingHours});
|
||||
}
|
||||
const title = intl.formatMessage({id: 'mobile.session_expired.title', defaultMessage: 'Session Expired'});
|
||||
|
||||
if (expiresAt) {
|
||||
|
|
|
|||
|
|
@ -3,16 +3,29 @@
|
|||
|
||||
import {Alert} from 'react-native';
|
||||
|
||||
import {storePushDisabledInServerAcknowledged} from '@actions/app/global';
|
||||
import {PUSH_PROXY_RESPONSE_NOT_AVAILABLE, PUSH_PROXY_RESPONSE_UNKNOWN, PUSH_PROXY_STATUS_NOT_AVAILABLE, PUSH_PROXY_STATUS_UNKNOWN, PUSH_PROXY_STATUS_VERIFIED} from '@constants/push_proxy';
|
||||
import {getPushDisabledInServerAcknowledged} from '@queries/app/global';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
|
||||
import {urlSafeBase64Encode} from './security';
|
||||
|
||||
import type {IntlShape} from 'react-intl';
|
||||
|
||||
export function canReceiveNotifications(serverUrl: string, verification: string, intl: IntlShape) {
|
||||
export function pushDisabledInServerAck(serverUrl: string) {
|
||||
const extractedDomain = urlSafeBase64Encode(serverUrl);
|
||||
return getPushDisabledInServerAcknowledged(extractedDomain);
|
||||
}
|
||||
|
||||
export async function canReceiveNotifications(serverUrl: string, verification: string, intl: IntlShape) {
|
||||
const hasAckNotification = await pushDisabledInServerAck(serverUrl);
|
||||
|
||||
switch (verification) {
|
||||
case PUSH_PROXY_RESPONSE_NOT_AVAILABLE:
|
||||
EphemeralStore.setPushProxyVerificationState(serverUrl, PUSH_PROXY_STATUS_NOT_AVAILABLE);
|
||||
alertPushProxyError(intl);
|
||||
if (!hasAckNotification) {
|
||||
alertPushProxyError(intl, serverUrl);
|
||||
}
|
||||
break;
|
||||
case PUSH_PROXY_RESPONSE_UNKNOWN:
|
||||
EphemeralStore.setPushProxyVerificationState(serverUrl, PUSH_PROXY_STATUS_UNKNOWN);
|
||||
|
|
@ -23,7 +36,14 @@ export function canReceiveNotifications(serverUrl: string, verification: string,
|
|||
}
|
||||
}
|
||||
|
||||
export function alertPushProxyError(intl: IntlShape) {
|
||||
const handleAlertResponse = async (buttonIndex: number, serverUrl?: string) => {
|
||||
if (buttonIndex === 0 && serverUrl) {
|
||||
// User clicked "Okay" acknowledging that the push notifications are disabled on that server
|
||||
await storePushDisabledInServerAcknowledged(urlSafeBase64Encode(serverUrl));
|
||||
}
|
||||
};
|
||||
|
||||
export function alertPushProxyError(intl: IntlShape, serverUrl?: string) {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'alert.push_proxy_error.title',
|
||||
|
|
@ -31,10 +51,11 @@ export function alertPushProxyError(intl: IntlShape) {
|
|||
}),
|
||||
intl.formatMessage({
|
||||
id: 'alert.push_proxy_error.description',
|
||||
defaultMessage: 'Due to the configuration for this server, notifications cannot be received in the mobile app. Contact your system admin for more information.',
|
||||
defaultMessage: 'Due to the configuration of this server, notifications cannot be received in the mobile app. Contact your system admin for more information.',
|
||||
}),
|
||||
[{
|
||||
text: intl.formatMessage({id: 'alert.push_proxy.button', defaultMessage: 'Okay'}),
|
||||
onPress: () => handleAlertResponse(0, serverUrl),
|
||||
}],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
"account.your_profile": "Your Profile",
|
||||
"alert.channel_deleted.description": "The channel {displayName} has been archived.",
|
||||
"alert.channel_deleted.title": "Archived channel",
|
||||
"alert.push_proxy_error.description": "Due to the configuration for this server, notifications cannot be received in the mobile app. Contact your system admin for more information.",
|
||||
"alert.push_proxy_error.description": "Due to the configuration of this server, notifications cannot be received in the mobile app. Contact your system admin for more information.",
|
||||
"alert.push_proxy_error.title": "Notifications cannot be received from this server",
|
||||
"alert.push_proxy_unknown.description": "This server was unable to receive push notifications for an unknown reason. This will be attempted again next time you connect.",
|
||||
"alert.push_proxy_unknown.title": "Notifications could not be received from this server",
|
||||
|
|
@ -613,6 +613,7 @@
|
|||
"mobile.managed.settings": "Go to settings",
|
||||
"mobile.markdown.code.copy_code": "Copy Code",
|
||||
"mobile.markdown.code.plusMoreLines": "+{count, number} more {count, plural, one {line} other {lines}}",
|
||||
"mobile.markdown.copy_header": "Copy header text",
|
||||
"mobile.markdown.image.too_large": "Image exceeds max dimensions of {maxWidth} by {maxHeight}:",
|
||||
"mobile.markdown.link.copy_url": "Copy URL",
|
||||
"mobile.mention.copy_mention": "Copy Mention",
|
||||
|
|
@ -709,7 +710,9 @@
|
|||
"mobile.server_url.deeplink.emm.denied": "This app is controlled by an EMM and the DeepLink server url does not match the EMM allowed server",
|
||||
"mobile.server_url.empty": "Please enter a valid server URL",
|
||||
"mobile.server_url.invalid_format": "URL must start with http:// or https://",
|
||||
"mobile.session_expired": "Please log in to continue receiving notifications. Sessions for {siteName} are configured to expire every {daysCount, number} {daysCount, plural, one {day} other {days}}.",
|
||||
"mobile.session_expired_days": "Please log in to continue receiving notifications. Sessions for {siteName} are configured to expire every {daysCount, number} {daysCount, plural, one {day} other {days}}.",
|
||||
"mobile.session_expired_days_hrs": "Please log in to continue receiving notifications. Sessions for {siteName} are configured to expire every {daysCount, number} {daysCount, plural, one {day} other {days}} and {hoursCount, number} {hoursCount, plural, one {hour} other {hours}}.",
|
||||
"mobile.session_expired_hrs": "Please log in to continue receiving notifications. Sessions for {siteName} are configured to expire every {hoursCount, number} {hoursCount, plural, one {hour} other {hours}}.",
|
||||
"mobile.session_expired.title": "Session Expired",
|
||||
"mobile.set_status.dnd": "Do Not Disturb",
|
||||
"mobile.storage_permission_denied_description": "Upload files to your server. Open Settings to grant {applicationName} Read and Write access to files on this device.",
|
||||
|
|
|
|||
|
|
@ -686,7 +686,7 @@
|
|||
"alert.push_proxy.button": "Okay",
|
||||
"alert.push_proxy_unknown.title": "Notifications could not be received from this server",
|
||||
"alert.push_proxy_error.title": "Notifications cannot be received from this server",
|
||||
"alert.push_proxy_error.description": "Due to the configuration for this server, notifications cannot be received in the mobile app. Contact your system admin for more information.",
|
||||
"alert.push_proxy_error.description": "Due to the configuration of this server, notifications cannot be received in the mobile app. Contact your system admin for more information.",
|
||||
"alert.channel_deleted.title": "Archived channel",
|
||||
"alert.channel_deleted.description": "The channel {displayName} has been archived.",
|
||||
"account.your_profile": "Your Profile",
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
{}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{}
|
||||
|
|
@ -1929,7 +1929,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 489;
|
||||
CURRENT_PROJECT_VERSION = 492;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
ENABLE_BITCODE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
|
|
@ -1973,7 +1973,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 489;
|
||||
CURRENT_PROJECT_VERSION = 492;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
ENABLE_BITCODE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
|
|
@ -2116,7 +2116,7 @@
|
|||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 489;
|
||||
CURRENT_PROJECT_VERSION = 492;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
|
@ -2165,7 +2165,7 @@
|
|||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 489;
|
||||
CURRENT_PROJECT_VERSION = 492;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.9.0</string>
|
||||
<string>2.10.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>489</string>
|
||||
<string>492</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.9.0</string>
|
||||
<string>2.10.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>489</string>
|
||||
<string>492</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>OpenSans-Bold.ttf</string>
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.9.0</string>
|
||||
<string>2.10.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>489</string>
|
||||
<string>492</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ PODS:
|
|||
- React-Core
|
||||
- Starscream (~> 4.0.4)
|
||||
- SwiftyJSON (~> 5.0)
|
||||
- react-native-notifications (5.0.0):
|
||||
- react-native-notifications (5.1.0):
|
||||
- React-Core
|
||||
- react-native-paste-input (0.6.4):
|
||||
- React-Core
|
||||
|
|
@ -946,7 +946,7 @@ SPEC CHECKSUMS:
|
|||
react-native-in-app-review: db8bb167a5f238e7ceca5c242d6b36ce8c4404a4
|
||||
react-native-netinfo: fefd4e98d75cbdd6e85fc530f7111a8afdf2b0c5
|
||||
react-native-network-client: 953ab4d0914fdde6dc40924b5faad8631a587d4e
|
||||
react-native-notifications: d309f7080aad71206882dbb98d9ed788969f3b6d
|
||||
react-native-notifications: 4601a5a8db4ced6ae7cfc43b44d35fe437ac50c4
|
||||
react-native-paste-input: 09f14cbfb646ad9d2ef79cdc6f3d45f337c10ad1
|
||||
react-native-safe-area-context: 9697629f7b2cda43cf52169bb7e0767d330648c2
|
||||
react-native-video: c26780b224543c62d5e1b2a7244a5cd1b50e8253
|
||||
|
|
@ -1001,4 +1001,4 @@ SPEC CHECKSUMS:
|
|||
|
||||
PODFILE CHECKSUM: 25f07cb9e5eed8c84db8e8723000e8470c349058
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
COCOAPODS: 1.14.2
|
||||
|
|
|
|||
177
package-lock.json
generated
177
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "mattermost-mobile",
|
||||
"version": "2.9.0",
|
||||
"version": "2.10.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mattermost-mobile",
|
||||
"version": "2.9.0",
|
||||
"version": "2.10.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache 2.0",
|
||||
"dependencies": {
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
"@voximplant/react-native-foreground-service": "3.0.2",
|
||||
"base-64": "1.0.0",
|
||||
"commonmark": "npm:@mattermost/commonmark@0.30.1-1",
|
||||
"commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#235bc817bcade503fb81fa51bbbe3c84f958ed12",
|
||||
"commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#81b5d27509652bae50b4b510ede777dd3bd923cf",
|
||||
"deep-equal": "2.2.2",
|
||||
"deepmerge": "4.3.1",
|
||||
"emoji-regex": "10.2.1",
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
"react-native-localize": "3.0.2",
|
||||
"react-native-math-view": "3.9.5",
|
||||
"react-native-navigation": "7.37.0",
|
||||
"react-native-notifications": "5.0.0",
|
||||
"react-native-notifications": "5.1.0",
|
||||
"react-native-permissions": "3.8.4",
|
||||
"react-native-reanimated": "3.4.2",
|
||||
"react-native-safe-area-context": "4.7.1",
|
||||
|
|
@ -9679,8 +9679,8 @@
|
|||
},
|
||||
"node_modules/commonmark-react-renderer": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "git+ssh://git@github.com/mattermost/commonmark-react-renderer.git#235bc817bcade503fb81fa51bbbe3c84f958ed12",
|
||||
"integrity": "sha512-GP3+17loU8tNal91FAlqDcDyUHdhahMPpV/XBm++VAyoyvsGKx3wGQZY/cVKXNx+SV2UANXVf4VFx8GpAkqCBQ==",
|
||||
"resolved": "git+ssh://git@github.com/mattermost/commonmark-react-renderer.git#81b5d27509652bae50b4b510ede777dd3bd923cf",
|
||||
"integrity": "sha512-2UYjN/Fix93L6udBsmZqCUggE7e5NA8rXHO2R3Dxs3lwHac3MsOMdEYZPST3Z/CCFc6gyKqWqDtCQXofbHffPA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash.assign": "^4.2.0",
|
||||
|
|
@ -19506,9 +19506,9 @@
|
|||
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
|
||||
},
|
||||
"node_modules/react-native-notifications": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-notifications/-/react-native-notifications-5.0.0.tgz",
|
||||
"integrity": "sha512-QXtBBmbDtwq9X8WAPLn+OctIeEtnJOQ+RCT6iweaypvFTydt2baLPtawTAbCSXKuWpVDqDAdmZnlQjCcavNzoA==",
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-notifications/-/react-native-notifications-5.1.0.tgz",
|
||||
"integrity": "sha512-laqDSDlCvEASmJR6cXpqaryK855ejQd07vrfYERzhv68YDOoSkKy/URExRP4vAfAOVqHhix80tLbNUcfvZk2VQ==",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
|
|
@ -23596,8 +23596,7 @@
|
|||
"version": "7.21.0-placeholder-for-preset-env.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
|
||||
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@babel/plugin-syntax-async-generators": {
|
||||
"version": "7.8.4",
|
||||
|
|
@ -25420,8 +25419,7 @@
|
|||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@mattermost/react-native-emm/-/react-native-emm-1.3.5.tgz",
|
||||
"integrity": "sha512-REdUEsm/RA6lI1Rt4b009jvWn28f7H+e27gd4hlNk6zesIh/dlfiHwYfInW/vwbNFBdSPpvHy7Qi2mdcvrNqhg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@mattermost/react-native-network-client": {
|
||||
"version": "1.4.1",
|
||||
|
|
@ -25444,8 +25442,7 @@
|
|||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-log/-/react-native-turbo-log-0.2.3.tgz",
|
||||
"integrity": "sha512-usWyD8zVAHzrYqgPH1ne5I14gCOkhS2mefK58g5v4DewZfCm0/Uc0w8MRuPS/9jyOPPq1rUZj8U1AqKgEne9tQ==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@msgpack/msgpack": {
|
||||
"version": "2.8.0",
|
||||
|
|
@ -25537,15 +25534,13 @@
|
|||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-camera-roll/camera-roll/-/camera-roll-5.7.2.tgz",
|
||||
"integrity": "sha512-s8VAUG1Kvi+tEJkLHObmOJdXAL/uclnXJ/IdnJtx2fCKiWA3Ho0ln9gDQqCYHHHHu+sXk7wovsH/I2/AYy0brg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@react-native-clipboard/clipboard": {
|
||||
"version": "1.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.11.2.tgz",
|
||||
"integrity": "sha512-bHyZVW62TuleiZsXNHS1Pv16fWc0fh8O9WvBzl4h2fykqZRW9a+Pv/RGTH56E3X2PqzHP38K5go8zmCZUoIsoQ==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@react-native-community/cli": {
|
||||
"version": "10.2.4",
|
||||
|
|
@ -27254,8 +27249,7 @@
|
|||
"version": "9.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-9.4.1.tgz",
|
||||
"integrity": "sha512-dAbY5mfw+6Kas/GJ6QX9AZyY+K+eq9ad4Su6utoph/nxyH3whp5cMSgRNgE2VhGQVRZ/OG0qq3IaD3+wzoqJXw==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@react-native-cookies/cookies": {
|
||||
"version": "6.2.1",
|
||||
|
|
@ -27421,8 +27415,7 @@
|
|||
"version": "1.3.18",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.18.tgz",
|
||||
"integrity": "sha512-/0hwnJkrr415yP0Hf4PjUKgGyfshrvNUKFXN85Mrt1gY49hy9IwxZgrrxlh0THXkPeq8q4VWw44eHDfAcQf20Q==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@react-navigation/native": {
|
||||
"version": "6.1.7",
|
||||
|
|
@ -27649,72 +27642,63 @@
|
|||
"version": "0.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@stream-io/flat-list-mvcp/-/flat-list-mvcp-0.10.3.tgz",
|
||||
"integrity": "sha512-2ZK8piYlEfKIPZrH8BpZz9uj8HZcUvMCV0X7qSLSAc/vhLOANBfR0SSn0OaWPbqb2mFGAd4FxmLSPp1zKEYuaw==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-add-jsx-attribute": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
|
||||
"integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-remove-jsx-attribute": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
|
||||
"integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-remove-jsx-empty-expression": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
|
||||
"integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-replace-jsx-attribute-value": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
|
||||
"integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-svg-dynamic-title": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
|
||||
"integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-svg-em-dimensions": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
|
||||
"integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-transform-react-native-svg": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.0.0.tgz",
|
||||
"integrity": "sha512-UKrY3860AQICgH7g+6h2zkoxeVEPLYwX/uAjmqo4PIq2FIHppwhIqZstIyTz0ZtlwreKR41O3W3BzsBBiJV2Aw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-transform-svg-component": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
|
||||
"integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-preset": {
|
||||
"version": "8.0.0",
|
||||
|
|
@ -28689,8 +28673,7 @@
|
|||
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz",
|
||||
"integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@webpack-cli/info": {
|
||||
"version": "1.4.0",
|
||||
|
|
@ -28706,8 +28689,7 @@
|
|||
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz",
|
||||
"integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"@xtuc/ieee754": {
|
||||
"version": "1.2.0",
|
||||
|
|
@ -28762,15 +28744,13 @@
|
|||
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "6.0.2",
|
||||
|
|
@ -28826,8 +28806,7 @@
|
|||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"anser": {
|
||||
"version": "1.4.10",
|
||||
|
|
@ -29105,8 +29084,7 @@
|
|||
"version": "7.0.0-bridge.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
|
||||
"integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"babel-jest": {
|
||||
"version": "29.6.2",
|
||||
|
|
@ -30055,9 +30033,9 @@
|
|||
}
|
||||
},
|
||||
"commonmark-react-renderer": {
|
||||
"version": "git+ssh://git@github.com/mattermost/commonmark-react-renderer.git#235bc817bcade503fb81fa51bbbe3c84f958ed12",
|
||||
"integrity": "sha512-GP3+17loU8tNal91FAlqDcDyUHdhahMPpV/XBm++VAyoyvsGKx3wGQZY/cVKXNx+SV2UANXVf4VFx8GpAkqCBQ==",
|
||||
"from": "commonmark-react-renderer@github:mattermost/commonmark-react-renderer#235bc817bcade503fb81fa51bbbe3c84f958ed12",
|
||||
"version": "git+ssh://git@github.com/mattermost/commonmark-react-renderer.git#81b5d27509652bae50b4b510ede777dd3bd923cf",
|
||||
"integrity": "sha512-2UYjN/Fix93L6udBsmZqCUggE7e5NA8rXHO2R3Dxs3lwHac3MsOMdEYZPST3Z/CCFc6gyKqWqDtCQXofbHffPA==",
|
||||
"from": "commonmark-react-renderer@github:mattermost/commonmark-react-renderer#81b5d27509652bae50b4b510ede777dd3bd923cf",
|
||||
"requires": {
|
||||
"lodash.assign": "^4.2.0",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
|
|
@ -30307,8 +30285,7 @@
|
|||
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz",
|
||||
"integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"deep-equal": {
|
||||
"version": "2.2.2",
|
||||
|
|
@ -31211,8 +31188,7 @@
|
|||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz",
|
||||
"integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"eslint-import-resolver-node": {
|
||||
"version": "0.3.7",
|
||||
|
|
@ -31297,8 +31273,7 @@
|
|||
"resolved": "https://registry.npmjs.org/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz",
|
||||
"integrity": "sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"eslint-plugin-import": {
|
||||
"version": "2.28.0",
|
||||
|
|
@ -31432,8 +31407,7 @@
|
|||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
|
||||
"integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"eslint-plugin-react-native": {
|
||||
"version": "4.0.0",
|
||||
|
|
@ -33807,8 +33781,7 @@
|
|||
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
|
||||
"integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"jest-regex-util": {
|
||||
"version": "29.4.3",
|
||||
|
|
@ -37036,8 +37009,7 @@
|
|||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.3.tgz",
|
||||
"integrity": "sha512-ZnXwLQnGzrDpHBHiC56TXFXvmolPeMjTn1UOm610M4EXGzbEDR7oOIyS2ZiItgbs6eZc4oU/a0hpk8PrcKvv5g==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-intl": {
|
||||
"version": "6.4.4",
|
||||
|
|
@ -37346,8 +37318,7 @@
|
|||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-background-timer/-/react-native-background-timer-2.4.1.tgz",
|
||||
"integrity": "sha512-TE4Kiy7jUyv+hugxDxitzu38sW1NqjCk4uE5IgU2WevLv7sZacaBc6PZKOShNRPGirLl1NWkaG3LDEkdb9Um5g==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-button": {
|
||||
"version": "3.1.0",
|
||||
|
|
@ -37400,15 +37371,13 @@
|
|||
"version": "1.6.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-create-thumbnail/-/react-native-create-thumbnail-1.6.4.tgz",
|
||||
"integrity": "sha512-JWuKXswDXtqUPfuqh6rjCVMvTSSG3kUtwvSK/YdaNU0i+nZKxeqHmt/CO2+TyI/WSUFynGVmWT1xOHhCZAFsRQ==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-device-info": {
|
||||
"version": "10.8.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-device-info/-/react-native-device-info-10.8.0.tgz",
|
||||
"integrity": "sha512-DE4/X82ZVhdcnR1Y21iTP46WSSJA/rHK3lmeqWfGGq1RKLwXTIdxmfbZZnYwryqJ+esrw2l4ND19qlgxDGby8A==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-document-picker": {
|
||||
"version": "9.0.1",
|
||||
|
|
@ -37445,22 +37414,19 @@
|
|||
"version": "2.10.10",
|
||||
"resolved": "https://registry.npmjs.org/react-native-exception-handler/-/react-native-exception-handler-2.10.10.tgz",
|
||||
"integrity": "sha512-otAXGoZDl1689OoUJWN/rXxVbdoZ3xcmyF1uq/CsizdLwwyZqVGd6d+p/vbYvnF996FfEyAEBnHrdFxulTn51w==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-fast-image": {
|
||||
"version": "8.6.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-8.6.3.tgz",
|
||||
"integrity": "sha512-Sdw4ESidXCXOmQ9EcYguNY2swyoWmx53kym2zRsvi+VeFCHEdkO+WG1DK+6W81juot40bbfLNhkc63QnWtesNg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-file-viewer": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/react-native-file-viewer/-/react-native-file-viewer-2.1.5.tgz",
|
||||
"integrity": "sha512-MGC6sx9jsqHdefhVQ6o0akdsPGpkXgiIbpygb2Sg4g4bh7v6K1cardLV1NwGB9A6u1yICOSDT/MOC//9Ez6EUg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-fs": {
|
||||
"version": "2.20.0",
|
||||
|
|
@ -37499,22 +37465,19 @@
|
|||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-haptic-feedback/-/react-native-haptic-feedback-2.0.3.tgz",
|
||||
"integrity": "sha512-7+qvcxXZts/hA+HOOIFyM1x9m9fn/TJVSTgXaoQ8uT4gLc97IMvqHQ559tDmnlth+hHMzd3HRMpmRLWoKPL0DA==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-hw-keyboard-event": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-hw-keyboard-event/-/react-native-hw-keyboard-event-0.0.4.tgz",
|
||||
"integrity": "sha512-G8qp0nm17PHigLb/axgdF9xg51BKCG2p1AGeq//J/luLp5zNczIcQJh+nm02R1MeEUE3e53wqO4LMe0MV3raZg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-image-picker": {
|
||||
"version": "5.6.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-5.6.1.tgz",
|
||||
"integrity": "sha512-LPPlgJi97EzCDY4NWp7z0oUWmCbagnB6HSoKcLJHJD/DaFYN/dJPrqjqKaqqw8K/5Ze6DIsNg9PZohjNEYQQWQ==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-in-app-review": {
|
||||
"version": "4.3.3",
|
||||
|
|
@ -37525,15 +37488,13 @@
|
|||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-incall-manager/-/react-native-incall-manager-4.1.0.tgz",
|
||||
"integrity": "sha512-v1c+XOGu5VudY5//E3i5xiaRA9v6RvevMzZ4RumLqI+hte+4XslB2z6HSek2FF0EmAnY1rCn4ckiwgkTI1Tmtw==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-iphone-x-helper": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz",
|
||||
"integrity": "sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-keyboard-aware-scroll-view": {
|
||||
"version": "0.9.5",
|
||||
|
|
@ -37548,8 +37509,7 @@
|
|||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-keyboard-tracking-view/-/react-native-keyboard-tracking-view-5.7.0.tgz",
|
||||
"integrity": "sha512-MDeEwAbn9LJDOfHq0QLCGaZirVLk2X/tHqkAqz3y6uxryTRdSl9PwleOVar5Jx2oAPEg4J9BXbUD1wwOOi+5Kg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-keychain": {
|
||||
"version": "8.1.2",
|
||||
|
|
@ -37560,15 +37520,13 @@
|
|||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.2.tgz",
|
||||
"integrity": "sha512-hgmCsgzd58WNcDCyPtKrvxsaoETjb/jLGxis/dmU3Aqm2u4ICIduj4ECjbil7B7pm9OnuTkmpwXu08XV2mpg8g==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-localize": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-localize/-/react-native-localize-3.0.2.tgz",
|
||||
"integrity": "sha512-/l/oE1LVNgIRRhLbhmfFMHiWV0xhUn0A0iz1ytLVRYywL7FTp8Rx2vkJS/q/RpExDvV7yLw2493XZBYIM1dnLQ==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-math-view": {
|
||||
"version": "3.9.5",
|
||||
|
|
@ -37601,11 +37559,10 @@
|
|||
}
|
||||
},
|
||||
"react-native-notifications": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-notifications/-/react-native-notifications-5.0.0.tgz",
|
||||
"integrity": "sha512-QXtBBmbDtwq9X8WAPLn+OctIeEtnJOQ+RCT6iweaypvFTydt2baLPtawTAbCSXKuWpVDqDAdmZnlQjCcavNzoA==",
|
||||
"requires": {
|
||||
}
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-notifications/-/react-native-notifications-5.1.0.tgz",
|
||||
"integrity": "sha512-laqDSDlCvEASmJR6cXpqaryK855ejQd07vrfYERzhv68YDOoSkKy/URExRP4vAfAOVqHhix80tLbNUcfvZk2VQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-permissions": {
|
||||
"version": "3.8.4",
|
||||
|
|
@ -37646,8 +37603,7 @@
|
|||
"version": "4.7.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.7.1.tgz",
|
||||
"integrity": "sha512-X2pJG2ttmAbiGlItWedvDkZg1T1ikmEDiz+7HsiIwAIm2UbFqlhqn+B1JF53mSxPzdNaDcCQVHRNPvj8oFu6Yg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-screens": {
|
||||
"version": "3.24.0",
|
||||
|
|
@ -37680,8 +37636,7 @@
|
|||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-size-matters/-/react-native-size-matters-0.3.1.tgz",
|
||||
"integrity": "sha512-mKOfBLIBFBcs9br1rlZDvxD5+mAl8Gfr5CounwJtxI6Z82rGrMO+Kgl9EIg3RMVf3G855a85YVqHJL2f5EDRlw==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-svg": {
|
||||
"version": "13.11.0",
|
||||
|
|
@ -39355,8 +39310,7 @@
|
|||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz",
|
||||
"integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"ts-jest": {
|
||||
"version": "29.1.1",
|
||||
|
|
@ -39677,15 +39631,13 @@
|
|||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.6.tgz",
|
||||
"integrity": "sha512-VO/P91A/PmKH9bcN9a7O3duSuxe6M14ZoYXgA6a8dab8doWNdhiIHzEkX/jFeTTRBsX0Ubk6nG4q2NIjNsj+bg==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"use-sync-external-store": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
|
||||
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"utf8": {
|
||||
"version": "3.0.0",
|
||||
|
|
@ -40018,8 +39970,7 @@
|
|||
"version": "7.5.5",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz",
|
||||
"integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==",
|
||||
"requires": {
|
||||
}
|
||||
"requires": {}
|
||||
},
|
||||
"xdate": {
|
||||
"version": "0.8.2",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mattermost-mobile",
|
||||
"version": "2.9.0",
|
||||
"version": "2.10.0",
|
||||
"description": "Mattermost Mobile with React Native",
|
||||
"repository": "git@github.com:mattermost/mattermost-mobile.git",
|
||||
"author": "Mattermost, Inc.",
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
"@voximplant/react-native-foreground-service": "3.0.2",
|
||||
"base-64": "1.0.0",
|
||||
"commonmark": "npm:@mattermost/commonmark@0.30.1-1",
|
||||
"commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#235bc817bcade503fb81fa51bbbe3c84f958ed12",
|
||||
"commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#81b5d27509652bae50b4b510ede777dd3bd923cf",
|
||||
"deep-equal": "2.2.2",
|
||||
"deepmerge": "4.3.1",
|
||||
"emoji-regex": "10.2.1",
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
"react-native-localize": "3.0.2",
|
||||
"react-native-math-view": "3.9.5",
|
||||
"react-native-navigation": "7.37.0",
|
||||
"react-native-notifications": "5.0.0",
|
||||
"react-native-notifications": "5.1.0",
|
||||
"react-native-permissions": "3.8.4",
|
||||
"react-native-reanimated": "3.4.2",
|
||||
"react-native-safe-area-context": "4.7.1",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
diff --git a/node_modules/react-native-notifications/lib/android/app/build.gradle b/node_modules/react-native-notifications/lib/android/app/build.gradle
|
||||
index d049e84..9ad7004 100644
|
||||
index 30bb01c..bba788d 100644
|
||||
--- a/node_modules/react-native-notifications/lib/android/app/build.gradle
|
||||
+++ b/node_modules/react-native-notifications/lib/android/app/build.gradle
|
||||
@@ -96,9 +96,9 @@ android {
|
||||
|
|
@ -7,10 +7,10 @@ index d049e84..9ad7004 100644
|
|||
testOptions {
|
||||
unitTests.all { t ->
|
||||
- reports {
|
||||
- html.enabled true
|
||||
- html.required.set true
|
||||
- }
|
||||
+ // reports {
|
||||
+ // html.enabled true
|
||||
+ // html.required.set true
|
||||
+ // }
|
||||
testLogging {
|
||||
events "PASSED", "SKIPPED", "FAILED", "standardOut", "standardError"
|
||||
|
|
@ -90,10 +90,10 @@ index 5b7f15f..9381794 100644
|
|||
}
|
||||
}
|
||||
diff --git a/node_modules/react-native-notifications/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java b/node_modules/react-native-notifications/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java
|
||||
index 1e7e871..62e5cb8 100644
|
||||
index 1e7e871..36b96b6 100644
|
||||
--- a/node_modules/react-native-notifications/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java
|
||||
+++ b/node_modules/react-native-notifications/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java
|
||||
@@ -14,17 +14,9 @@ public class NotificationIntentAdapter {
|
||||
@@ -14,17 +14,11 @@ public class NotificationIntentAdapter {
|
||||
|
||||
@SuppressLint("UnspecifiedImmutableFlag")
|
||||
public static PendingIntent createPendingNotificationIntent(Context appContext, PushNotificationProps notification) {
|
||||
|
|
@ -108,9 +108,11 @@ index 1e7e871..62e5cb8 100644
|
|||
- taskStackBuilder.addNextIntentWithParentStack(mainActivityIntent);
|
||||
- return taskStackBuilder.getPendingIntent((int) System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
|
||||
- }
|
||||
+ Intent intent = appContext.getPackageManager().getLaunchIntentForPackage(appContext.getPackageName());
|
||||
+ intent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
|
||||
+ return PendingIntent.getActivity(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
|
||||
+ Intent mainActivityIntent = appContext.getPackageManager().getLaunchIntentForPackage(appContext.getPackageName());
|
||||
+ mainActivityIntent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
|
||||
+ TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(appContext);
|
||||
+ taskStackBuilder.addNextIntentWithParentStack(mainActivityIntent);
|
||||
+ return taskStackBuilder.getPendingIntent((int) System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
|
||||
}
|
||||
|
||||
public static boolean canHandleTrampolineActivity(Context appContext) {
|
||||
Loading…
Reference in a new issue