forked from Ivasoft/mattermost-mobile
Compare commits
7 Commits
v1.44.0
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0dd11d45e9 | ||
|
|
ddf0c5b740 | ||
|
|
76702fb4bb | ||
|
|
b028b2e146 | ||
|
|
3c034ae3c4 | ||
|
|
2119cb4f85 | ||
|
|
d78ad793a8 |
@@ -132,8 +132,8 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60"
|
||||
versionCode 359
|
||||
versionName "1.44.0"
|
||||
versionCode 360
|
||||
versionName "1.44.1"
|
||||
multiDexEnabled = true
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -7,16 +7,22 @@ import {Keyboard} from 'react-native';
|
||||
import {dismissAllModals, showModalOverCurrentContext} from '@actions/navigation';
|
||||
import {loadChannelsByTeamName} from '@actions/views/channel';
|
||||
import {selectFocusedPostId} from '@mm-redux/actions/posts';
|
||||
import {getCurrentTeam} from '@mm-redux/selectors/entities/teams';
|
||||
import {permalinkBadTeam} from '@utils/general';
|
||||
import {changeOpacity} from '@utils/theme';
|
||||
|
||||
import type {DispatchFunc} from '@mm-redux/types/actions';
|
||||
import type {DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
|
||||
|
||||
let showingPermalink = false;
|
||||
|
||||
export function showPermalink(intl: typeof intlShape, teamName: string, postId: string, openAsPermalink = true) {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
const loadTeam = await dispatch(loadChannelsByTeamName(teamName, permalinkBadTeam.bind(null, intl)));
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let name = teamName;
|
||||
if (!name) {
|
||||
name = getCurrentTeam(getState()).name;
|
||||
}
|
||||
|
||||
const loadTeam = await dispatch(loadChannelsByTeamName(name, permalinkBadTeam.bind(null, intl)));
|
||||
|
||||
if (!loadTeam.error) {
|
||||
Keyboard.dismiss();
|
||||
|
||||
@@ -151,6 +151,9 @@ export function doReconnect(now: number) {
|
||||
}
|
||||
|
||||
actions.push({
|
||||
type: UserTypes.RECEIVED_ME,
|
||||
data: me.user,
|
||||
}, {
|
||||
type: PreferenceTypes.RECEIVED_ALL_PREFERENCES,
|
||||
data: me.preferences,
|
||||
}, {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import React, {useMemo} from 'react';
|
||||
import {Text, TextStyle} from 'react-native';
|
||||
import {useSelector} from 'react-redux';
|
||||
|
||||
@@ -17,7 +17,7 @@ interface ComponentProps {
|
||||
}
|
||||
|
||||
const CustomStatusEmoji = ({emojiSize, userID, style, testID}: ComponentProps) => {
|
||||
const getCustomStatus = makeGetCustomStatus();
|
||||
const getCustomStatus = useMemo(makeGetCustomStatus, []);
|
||||
const customStatus = useSelector((state: GlobalState) => {
|
||||
return getCustomStatus(state, userID);
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ export default class PostDraft extends PureComponent {
|
||||
};
|
||||
|
||||
updateNativeScrollView = (scrollViewNativeID) => {
|
||||
if (this.keyboardTracker?.current) {
|
||||
if (this.keyboardTracker?.current && this.props.scrollViewNativeID === scrollViewNativeID) {
|
||||
const resetScrollView = requestAnimationFrame(() => {
|
||||
this.keyboardTracker.current.resetScrollView(scrollViewNativeID);
|
||||
cancelAnimationFrame(resetScrollView);
|
||||
|
||||
@@ -22,7 +22,7 @@ const EmbeddedBindings = ({embeds, postId, theme}: Props) => {
|
||||
content.push(
|
||||
<EmbeddedBinding
|
||||
embed={embed}
|
||||
key={'att_' + i.toString()}
|
||||
key={'binding_' + i.toString()}
|
||||
postId={postId}
|
||||
theme={theme}
|
||||
/>,
|
||||
|
||||
@@ -65,22 +65,28 @@ const Content = ({isReplyPost, post, theme}: ContentProps) => {
|
||||
/>
|
||||
);
|
||||
case contentType.message_attachment:
|
||||
return (
|
||||
<MessageAttachments
|
||||
attachments={post.props.attachments}
|
||||
metadata={post.metadata}
|
||||
postId={post.id}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
if (post.props.attachments?.length) {
|
||||
return (
|
||||
<MessageAttachments
|
||||
attachments={post.props.attachments}
|
||||
metadata={post.metadata}
|
||||
postId={post.id}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
break;
|
||||
case contentType.app_bindings:
|
||||
return (
|
||||
<EmbeddedBindings
|
||||
embeds={post.props.app_bindings}
|
||||
postId={post.id}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
if (post.props.app_bindings?.length) {
|
||||
return (
|
||||
<EmbeddedBindings
|
||||
embeds={post.props.app_bindings}
|
||||
postId={post.id}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -92,6 +92,7 @@ const Header = ({
|
||||
<CustomStatusEmoji
|
||||
userID={post.user_id}
|
||||
style={style.customStatusEmoji}
|
||||
testID='post_header'
|
||||
/>
|
||||
)}
|
||||
{!isSystemPost &&
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {showPermalink} from '@actions/views/permalink';
|
||||
import {removePost} from '@mm-redux/actions/posts';
|
||||
import {getChannel} from '@mm-redux/selectors/entities/channels';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
@@ -21,10 +22,12 @@ import type {GlobalState} from '@mm-redux/types/store';
|
||||
import Post from './post';
|
||||
|
||||
type OwnProps = {
|
||||
highlight?: boolean;
|
||||
postId: string;
|
||||
post?: PostType;
|
||||
previousPostId?: string;
|
||||
nextPostId?: string;
|
||||
testID: string;
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
@@ -83,6 +86,7 @@ function mapSateToProps(state: GlobalState, ownProps: OwnProps) {
|
||||
|
||||
const mapDispatchToProps = {
|
||||
removePost,
|
||||
showPermalink,
|
||||
};
|
||||
|
||||
export default connect(mapSateToProps, mapDispatchToProps)(Post);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import React, {ReactNode, useRef} from 'react';
|
||||
import {Keyboard, StyleProp, View, ViewStyle} from 'react-native';
|
||||
import {injectIntl, intlShape} from 'react-intl';
|
||||
|
||||
import {showModalOverCurrentContext} from '@actions/navigation';
|
||||
import SystemHeader from '@components/post_list/system_header';
|
||||
@@ -28,6 +29,7 @@ type PostProps = {
|
||||
enablePostUsernameOverride: boolean;
|
||||
highlight?: boolean;
|
||||
highlightPinnedOrFlagged?: boolean;
|
||||
intl: typeof intlShape;
|
||||
isConsecutivePost?: boolean;
|
||||
isFirstReply?: boolean;
|
||||
isFlagged?: boolean;
|
||||
@@ -38,6 +40,7 @@ type PostProps = {
|
||||
rootPostAuthor?: string;
|
||||
shouldRenderReplyButton?: boolean;
|
||||
showAddReaction?: boolean;
|
||||
showPermalink: (intl: typeof intlShape, teamName: string, postId: string) => null;
|
||||
skipFlaggedHeader?: boolean;
|
||||
skipPinnedHeader?: boolean;
|
||||
teammateNameDisplay: string;
|
||||
@@ -86,8 +89,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
});
|
||||
|
||||
const Post = ({
|
||||
canDelete, enablePostUsernameOverride, highlight, highlightPinnedOrFlagged = true, isConsecutivePost, isFirstReply, isFlagged, isLastReply,
|
||||
location, post, removePost, rootPostAuthor, shouldRenderReplyButton, skipFlaggedHeader, skipPinnedHeader, showAddReaction = true,
|
||||
canDelete, enablePostUsernameOverride, highlight, highlightPinnedOrFlagged = true, intl, isConsecutivePost, isFirstReply, isFlagged, isLastReply,
|
||||
location, post, removePost, rootPostAuthor, shouldRenderReplyButton, skipFlaggedHeader, skipPinnedHeader, showAddReaction = true, showPermalink,
|
||||
teammateNameDisplay, testID, theme,
|
||||
}: PostProps) => {
|
||||
const pressDetected = useRef(false);
|
||||
@@ -99,11 +102,14 @@ const Post = ({
|
||||
if (post) {
|
||||
if (location === Screens.THREAD) {
|
||||
Keyboard.dismiss();
|
||||
} else if (location === Screens.SEARCH) {
|
||||
showPermalink(intl, '', post.id);
|
||||
return;
|
||||
}
|
||||
|
||||
const isValidSystemMessage = fromAutoResponder(post) || !isSystemMessage(post);
|
||||
if (post.state !== Posts.POST_DELETED && isValidSystemMessage && !isPostPendingOrFailed(post)) {
|
||||
if ([Screens.CHANNEL, Screens.PERMALINK, Screens.SEARCH].includes(location)) {
|
||||
if ([Screens.CHANNEL, Screens.PERMALINK].includes(location)) {
|
||||
EventEmitter.emit('goToThread', post);
|
||||
}
|
||||
} else if ((isPostEphemeral(post) || post.state === Posts.POST_DELETED)) {
|
||||
@@ -257,4 +263,4 @@ const Post = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default Post;
|
||||
export default injectIntl(Post);
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
import React, {ReactElement, useCallback, useEffect, useLayoutEffect, useRef} from 'react';
|
||||
import {injectIntl, intlShape} from 'react-intl';
|
||||
import {DeviceEventEmitter, FlatList, Platform, StyleSheet, ViewToken} from 'react-native';
|
||||
import {DeviceEventEmitter, FlatList, Platform, RefreshControl, StyleSheet, ViewToken} from 'react-native';
|
||||
|
||||
import {DeepLinkTypes, NavigationTypes} from '@constants';
|
||||
import * as Screens from '@constants/screen';
|
||||
import {useResetNativeScrollView} from '@hooks';
|
||||
import {Posts} from '@mm-redux/constants';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
@@ -145,7 +146,7 @@ const PostList = ({
|
||||
if (onViewableItemsChangedListener.current && !deepLinkURL) {
|
||||
onViewableItemsChangedListener.current(viewableItems);
|
||||
}
|
||||
}, [deepLinkURL]);
|
||||
}, []);
|
||||
|
||||
const renderItem = useCallback(({item, index}) => {
|
||||
if (isStartOfNewMessages(item)) {
|
||||
@@ -281,6 +282,18 @@ const PostList = ({
|
||||
}
|
||||
}, [initialIndex, highlightPostId]);
|
||||
|
||||
let refreshControl;
|
||||
if (location === Screens.PERMALINK) {
|
||||
// Hack so that the scrolling the permalink does not dismisses the modal screens
|
||||
refreshControl = (
|
||||
<RefreshControl
|
||||
refreshing={false}
|
||||
enabled={Platform.OS === 'ios'}
|
||||
colors={[theme.centerChannelColor]}
|
||||
tintColor={theme.centerChannelColor}
|
||||
/>);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<FlatList
|
||||
@@ -309,6 +322,7 @@ const PostList = ({
|
||||
windowSize={Posts.POST_CHUNK_SIZE / 2}
|
||||
viewabilityConfig={VIEWABILITY_CONFIG}
|
||||
onViewableItemsChanged={onViewableItemsChanged}
|
||||
refreshControl={refreshControl}
|
||||
testID={testID}
|
||||
/>
|
||||
{showMoreMessagesButton &&
|
||||
|
||||
@@ -59,11 +59,11 @@ describe('PushNotification', () => {
|
||||
});
|
||||
|
||||
it('should clear all notifications', async () => {
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(PushNotification, 'setApplicationIconBadgeNumber');
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(Notifications.ios, 'setBadgeCount');
|
||||
const cancelAllLocalNotifications = jest.spyOn(PushNotification, 'cancelAllLocalNotifications');
|
||||
|
||||
PushNotification.clearNotifications();
|
||||
await expect(setApplicationIconBadgeNumber).toHaveBeenCalledWith(0, true);
|
||||
await expect(setApplicationIconBadgeNumber).toHaveBeenCalledWith(0);
|
||||
expect(Notifications.ios.setBadgeCount).toHaveBeenCalledWith(0);
|
||||
expect(cancelAllLocalNotifications).toHaveBeenCalled();
|
||||
expect(Notifications.cancelAllLocalNotifications).toHaveBeenCalled();
|
||||
@@ -71,7 +71,7 @@ describe('PushNotification', () => {
|
||||
|
||||
it('clearChannelNotifications should set app badge number from to delivered notification count when redux store is not set', async () => {
|
||||
Store.redux = null;
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(PushNotification, 'setApplicationIconBadgeNumber');
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(Notifications.ios, 'setBadgeCount');
|
||||
const deliveredNotifications = [{identifier: 1}, {identifier: 2}];
|
||||
Notifications.setDeliveredNotifications(deliveredNotifications);
|
||||
|
||||
@@ -83,7 +83,7 @@ describe('PushNotification', () => {
|
||||
Store.redux = {
|
||||
getState: jest.fn(),
|
||||
};
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(PushNotification, 'setApplicationIconBadgeNumber');
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(Notifications.ios, 'setBadgeCount');
|
||||
const deliveredNotifications = [{identifier: 1}, {identifier: 2}];
|
||||
Notifications.setDeliveredNotifications(deliveredNotifications);
|
||||
|
||||
@@ -99,12 +99,11 @@ describe('PushNotification', () => {
|
||||
|
||||
let deliveredNotifications = [{identifier: 1}];
|
||||
Notifications.setDeliveredNotifications(deliveredNotifications);
|
||||
await PushNotification.setApplicationIconBadgeNumber(0);
|
||||
expect(setBadgeCount).not.toHaveBeenCalled();
|
||||
await Notifications.ios.setBadgeCount(0);
|
||||
|
||||
deliveredNotifications = [];
|
||||
Notifications.setDeliveredNotifications(deliveredNotifications);
|
||||
await PushNotification.setApplicationIconBadgeNumber(0);
|
||||
await PushNotification.clearChannelNotifications();
|
||||
expect(setBadgeCount).toHaveBeenCalledWith(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -65,10 +65,13 @@ class PushNotifications {
|
||||
}
|
||||
|
||||
clearNotifications = () => {
|
||||
this.setApplicationIconBadgeNumber(0, true);
|
||||
|
||||
// TODO: Only cancel the local notifications that belong to this server
|
||||
this.cancelAllLocalNotifications();
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
// TODO: Set the badge number to the total amount of mentions on other servers
|
||||
Notifications.ios.setBadgeCount(0);
|
||||
}
|
||||
};
|
||||
|
||||
clearChannelNotifications = async (channelId: string) => {
|
||||
@@ -81,11 +84,14 @@ class PushNotifications {
|
||||
} else {
|
||||
const ids: string[] = [];
|
||||
const notifications = await Notifications.ios.getDeliveredNotifications();
|
||||
|
||||
//set the badge count to the total amount of notifications present in the not-center
|
||||
let badgeCount = notifications.length;
|
||||
|
||||
if (Store.redux) {
|
||||
const totalMentions = getBadgeCount(Store.redux.getState());
|
||||
if (totalMentions > -1) {
|
||||
// replaces the badge count based on the redux store.
|
||||
badgeCount = totalMentions;
|
||||
}
|
||||
}
|
||||
@@ -101,7 +107,10 @@ class PushNotifications {
|
||||
Notifications.ios.removeDeliveredNotifications(ids);
|
||||
}
|
||||
|
||||
this.setApplicationIconBadgeNumber(badgeCount);
|
||||
if (Platform.OS === 'ios') {
|
||||
badgeCount = badgeCount <= 0 ? 0 : badgeCount;
|
||||
Notifications.ios.setBadgeCount(badgeCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,16 +252,6 @@ class PushNotifications {
|
||||
}
|
||||
};
|
||||
|
||||
setApplicationIconBadgeNumber = async (value: number, force = false) => {
|
||||
if (Platform.OS === 'ios') {
|
||||
const count = value < 0 ? 0 : value;
|
||||
const notifications = await Notifications.ios.getDeliveredNotifications();
|
||||
if (count === 0 && (force || notifications.length === 0)) {
|
||||
Notifications.ios.setBadgeCount(count);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
scheduleNotification = (notification: Notification) => {
|
||||
if (notification.fireDate) {
|
||||
if (Platform.OS === 'ios') {
|
||||
|
||||
@@ -85,7 +85,7 @@ export default class ChannelBase extends PureComponent {
|
||||
}
|
||||
|
||||
if (currentChannelId) {
|
||||
PushNotifications.clearChannelNotifications(currentChannelId);
|
||||
this.clearChannelNotifications();
|
||||
requestAnimationFrame(() => {
|
||||
actions.getChannelStats(currentChannelId);
|
||||
});
|
||||
@@ -123,7 +123,7 @@ export default class ChannelBase extends PureComponent {
|
||||
}
|
||||
|
||||
if (this.props.currentChannelId && this.props.currentChannelId !== prevProps.currentChannelId) {
|
||||
PushNotifications.clearChannelNotifications(this.props.currentChannelId);
|
||||
this.clearChannelNotifications();
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
this.props.actions.getChannelStats(this.props.currentChannelId);
|
||||
@@ -137,6 +137,13 @@ export default class ChannelBase extends PureComponent {
|
||||
EventEmitter.off(General.REMOVED_FROM_CHANNEL, this.handleRemovedFromChannel);
|
||||
}
|
||||
|
||||
clearChannelNotifications = () => {
|
||||
const clearNotificationsTimeout = setTimeout(() => {
|
||||
clearTimeout(clearNotificationsTimeout);
|
||||
PushNotifications.clearChannelNotifications(this.props.currentChannelId);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
registerTypingAnimation = (animation) => {
|
||||
const length = this.typingAnimations.push(animation);
|
||||
const removeAnimation = () => {
|
||||
|
||||
@@ -11,7 +11,6 @@ import {intlShape} from 'react-intl';
|
||||
|
||||
import Badge from '@components/badge';
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import PushNotifications from '@init/push_notifications';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {t} from '@utils/i18n';
|
||||
@@ -37,23 +36,6 @@ export default class MainSidebarDrawerButton extends PureComponent {
|
||||
visible: true,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.badgeCount > 0) {
|
||||
// Only set the icon badge number if once the component mounts we have at least one mention
|
||||
// reason is to prevent the notification in the notification center to get cleared
|
||||
// while the app is retrieving unread mentions from the server
|
||||
PushNotifications.setApplicationIconBadgeNumber(this.props.badgeCount);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
// Once the component updates we know for sure if there are or not mentions when it mounted
|
||||
// a) the app had mentions
|
||||
if (prevProps.badgeCount !== this.props.badgeCount) {
|
||||
PushNotifications.setApplicationIconBadgeNumber(this.props.badgeCount);
|
||||
}
|
||||
}
|
||||
|
||||
handlePress = preventDoubleTap(() => {
|
||||
this.props.openSidebar();
|
||||
});
|
||||
|
||||
@@ -5,7 +5,6 @@ import React from 'react';
|
||||
|
||||
import Badge from '@components/badge';
|
||||
import Preferences from '@mm-redux/constants/preferences';
|
||||
import PushNotification from '@init/push_notifications';
|
||||
import {shallowWithIntl} from 'test/intl-test-helper';
|
||||
|
||||
import MainSidebarDrawerButton from './main_sidebar_drawer_button';
|
||||
@@ -18,8 +17,6 @@ describe('MainSidebarDrawerButton', () => {
|
||||
visible: false,
|
||||
};
|
||||
|
||||
afterEach(() => PushNotification.setApplicationIconBadgeNumber(0));
|
||||
|
||||
test('should match, full snapshot', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<MainSidebarDrawerButton {...baseProps}/>,
|
||||
@@ -35,65 +32,6 @@ describe('MainSidebarDrawerButton', () => {
|
||||
expect(wrapper.find(Badge).length).toEqual(1);
|
||||
});
|
||||
|
||||
test('should not set app icon badge on mount', () => {
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(PushNotification, 'setApplicationIconBadgeNumber');
|
||||
const props = {
|
||||
...baseProps,
|
||||
badgeCount: 0,
|
||||
};
|
||||
|
||||
shallowWithIntl(
|
||||
<MainSidebarDrawerButton {...props}/>,
|
||||
);
|
||||
expect(setApplicationIconBadgeNumber).not.toBeCalled();
|
||||
});
|
||||
|
||||
test('should set app icon badge on mount', () => {
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(PushNotification, 'setApplicationIconBadgeNumber');
|
||||
const props = {
|
||||
...baseProps,
|
||||
badgeCount: 1,
|
||||
};
|
||||
|
||||
shallowWithIntl(
|
||||
<MainSidebarDrawerButton {...props}/>,
|
||||
);
|
||||
expect(setApplicationIconBadgeNumber).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should set app icon badge update', () => {
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(PushNotification, 'setApplicationIconBadgeNumber');
|
||||
const props = {
|
||||
...baseProps,
|
||||
badgeCount: 0,
|
||||
};
|
||||
|
||||
const wrapper = shallowWithIntl(
|
||||
<MainSidebarDrawerButton {...props}/>,
|
||||
);
|
||||
|
||||
wrapper.setProps({badgeCount: 2});
|
||||
expect(setApplicationIconBadgeNumber).toHaveBeenCalledTimes(1);
|
||||
expect(setApplicationIconBadgeNumber).toHaveBeenCalledWith(2);
|
||||
});
|
||||
|
||||
test('should set remove icon badge on update', () => {
|
||||
const setApplicationIconBadgeNumber = jest.spyOn(PushNotification, 'setApplicationIconBadgeNumber');
|
||||
const props = {
|
||||
...baseProps,
|
||||
badgeCount: 0,
|
||||
};
|
||||
|
||||
const wrapper = shallowWithIntl(
|
||||
<MainSidebarDrawerButton {...props}/>,
|
||||
);
|
||||
wrapper.setProps({badgeCount: 2});
|
||||
expect(setApplicationIconBadgeNumber).toHaveBeenCalledWith(2);
|
||||
|
||||
wrapper.setProps({badgeCount: -1});
|
||||
expect(setApplicationIconBadgeNumber).toHaveBeenCalledWith(-1);
|
||||
});
|
||||
|
||||
test('Should be accessible', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<MainSidebarDrawerButton {...baseProps}/>,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`SearchResultPost should match snapshot 1`] = `
|
||||
<Connect(Post)
|
||||
<Connect(InjectIntl(Post))
|
||||
highlightPinnedOrFlagged={false}
|
||||
isSearchResult={true}
|
||||
location="Search"
|
||||
|
||||
@@ -213,14 +213,14 @@ describe('Custom status', () => {
|
||||
|
||||
// # Post a message and check if custom status emoji is present in the post header
|
||||
await ChannelScreen.postMessage(message);
|
||||
await expect(element(by.id(`custom_status_emoji.${customStatus.emojiName}`).withAncestor(by.id('post_header')))).toBeVisible();
|
||||
await expect(element(by.id(`post_header.custom_status_emoji.${customStatus.emojiName}`))).toBeVisible();
|
||||
|
||||
// # Open the reply thread for the last post
|
||||
const {post} = await Post.apiGetLastPostInChannel(testChannel.id);
|
||||
await ChannelScreen.openReplyThreadFor(post.id, message);
|
||||
|
||||
// * Check if the custom status emoji is present in the post header and close thread
|
||||
await expect(element(by.id(`custom_status_emoji.${customStatus.emojiName}`).withAncestor(by.id('post_header')))).toBeVisible();
|
||||
await expect(element(by.id(`post_header.custom_status_emoji.${customStatus.emojiName}`))).toBeVisible();
|
||||
await ThreadScreen.back();
|
||||
|
||||
// # Open user profile screen
|
||||
|
||||
@@ -7,13 +7,13 @@ GEM
|
||||
artifactory (3.0.15)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.1.1)
|
||||
aws-partitions (1.467.0)
|
||||
aws-sdk-core (3.114.2)
|
||||
aws-partitions (1.471.0)
|
||||
aws-sdk-core (3.115.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.239.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-kms (1.43.0)
|
||||
aws-sdk-kms (1.44.0)
|
||||
aws-sdk-core (~> 3, >= 3.112.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.96.1)
|
||||
@@ -36,7 +36,7 @@ GEM
|
||||
dotenv (2.7.6)
|
||||
emoji_regex (3.2.2)
|
||||
excon (0.82.0)
|
||||
faraday (1.4.2)
|
||||
faraday (1.4.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
faraday-excon (~> 1.1)
|
||||
@@ -55,7 +55,7 @@ GEM
|
||||
faraday_middleware (1.0.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.4)
|
||||
fastlane (2.185.0)
|
||||
fastlane (2.186.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.3, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
@@ -99,7 +99,7 @@ GEM
|
||||
fastlane-plugin-find_replace_string (0.1.0)
|
||||
fastlane-plugin-versioning_android (0.1.0)
|
||||
gh_inspector (1.1.3)
|
||||
google-apis-androidpublisher_v3 (0.5.0)
|
||||
google-apis-androidpublisher_v3 (0.6.0)
|
||||
google-apis-core (~> 0.1)
|
||||
google-apis-core (0.3.0)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
@@ -123,13 +123,13 @@ GEM
|
||||
google-cloud-env (1.5.0)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
google-cloud-errors (1.1.0)
|
||||
google-cloud-storage (1.31.1)
|
||||
google-cloud-storage (1.32.0)
|
||||
addressable (~> 2.5)
|
||||
digest-crc (~> 0.4)
|
||||
google-apis-iamcredentials_v1 (~> 0.1)
|
||||
google-apis-storage_v1 (~> 0.1)
|
||||
google-cloud-core (~> 1.2)
|
||||
googleauth (~> 0.9)
|
||||
google-cloud-core (~> 1.6)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (0.16.2)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
|
||||
@@ -912,7 +912,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 359;
|
||||
CURRENT_PROJECT_VERSION = 360;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -954,7 +954,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 359;
|
||||
CURRENT_PROJECT_VERSION = 360;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
ENABLE_BITCODE = NO;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.44.0</string>
|
||||
<string>1.44.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@@ -37,7 +37,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>359</string>
|
||||
<string>360</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.44.0</string>
|
||||
<string>1.44.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>359</string>
|
||||
<string>360</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.44.0</string>
|
||||
<string>1.44.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>359</string>
|
||||
<string>360</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
|
||||
@@ -20,7 +20,7 @@ target 'Mattermost' do
|
||||
pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"
|
||||
pod 'Permission-PhotoLibraryAddOnly', :path => "#{permissions_path}/PhotoLibraryAddOnly"
|
||||
|
||||
pod 'XCDYouTubeKit', '2.8.3'
|
||||
pod 'XCDYouTubeKit', :git => 'https://github.com/hinge-agency/XCDYouTubeKit.git', :branch => 'fix/issue-534-XCDYouTubeVideoErrorDomain-error-code-3'
|
||||
pod 'Swime', '3.0.6'
|
||||
|
||||
# Enables Flipper.
|
||||
|
||||
@@ -336,12 +336,12 @@ PODS:
|
||||
- React-Core
|
||||
- ReactNativeKeyboardTrackingView (5.7.0):
|
||||
- React
|
||||
- ReactNativeNavigation (7.13.0):
|
||||
- ReactNativeNavigation (7.11.3):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- React-RCTText
|
||||
- ReactNativeNavigation/Core (= 7.13.0)
|
||||
- ReactNativeNavigation/Core (7.13.0):
|
||||
- ReactNativeNavigation/Core (= 7.11.3)
|
||||
- ReactNativeNavigation/Core (7.11.3):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- React-RCTText
|
||||
@@ -429,7 +429,7 @@ PODS:
|
||||
- Sentry/Core (= 6.1.4)
|
||||
- Sentry/Core (6.1.4)
|
||||
- Swime (3.0.6)
|
||||
- XCDYouTubeKit (2.8.3)
|
||||
- XCDYouTubeKit (2.15.2)
|
||||
- Yoga (1.14.0)
|
||||
- YoutubePlayer-in-WKWebView (0.3.5)
|
||||
|
||||
@@ -511,7 +511,7 @@ DEPENDENCIES:
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
|
||||
- Swime (= 3.0.6)
|
||||
- XCDYouTubeKit (= 2.8.3)
|
||||
- XCDYouTubeKit (from `https://github.com/hinge-agency/XCDYouTubeKit.git`, branch `fix/issue-534-XCDYouTubeVideoErrorDomain-error-code-3`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
@@ -525,7 +525,6 @@ SPEC REPOS:
|
||||
- SDWebImageWebPCoder
|
||||
- Sentry
|
||||
- Swime
|
||||
- XCDYouTubeKit
|
||||
- YoutubePlayer-in-WKWebView
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
@@ -677,9 +676,17 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-svg"
|
||||
RNVectorIcons:
|
||||
:path: "../node_modules/react-native-vector-icons"
|
||||
XCDYouTubeKit:
|
||||
:branch: fix/issue-534-XCDYouTubeVideoErrorDomain-error-code-3
|
||||
:git: https://github.com/hinge-agency/XCDYouTubeKit.git
|
||||
Yoga:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
XCDYouTubeKit:
|
||||
:commit: 38170db3934e575ad4bfb782dedc544f304b482f
|
||||
:git: https://github.com/hinge-agency/XCDYouTubeKit.git
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
|
||||
@@ -738,7 +745,7 @@ SPEC CHECKSUMS:
|
||||
ReactCommon: bedc99ed4dae329c4fcf128d0c31b9115e5365ca
|
||||
ReactNativeExceptionHandler: b11ff67c78802b2f62eed0e10e75cb1ef7947c60
|
||||
ReactNativeKeyboardTrackingView: 02137fac3b2ebd330d74fa54ead48b14750a2306
|
||||
ReactNativeNavigation: 4c4ca87edc0da4ee818158a62cb6188088454e5c
|
||||
ReactNativeNavigation: 906b631a6847c26cacf5cb3791566f1fe205c65c
|
||||
rn-fetch-blob: 17961aec08caae68bb8fc0e5b40f93b3acfa6932
|
||||
RNCAsyncStorage: cb9a623793918c6699586281f0b51cbc38f046f9
|
||||
RNCClipboard: 5e299c6df8e0c98f3d7416b86ae563d3a9f768a3
|
||||
@@ -764,10 +771,10 @@ SPEC CHECKSUMS:
|
||||
SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21
|
||||
Sentry: 9d055e2de30a77685e86b219acf02e59b82091fc
|
||||
Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b
|
||||
XCDYouTubeKit: 46df93c4dc4d48763ad720d997704384635c4335
|
||||
XCDYouTubeKit: b120aced3d8638ffb570c5450cddb5a1dac448c7
|
||||
Yoga: a7de31c64fe738607e7a3803e3f591a4b1df7393
|
||||
YoutubePlayer-in-WKWebView: cfbf46da51d7370662a695a8f351e5fa1d3e1008
|
||||
|
||||
PODFILE CHECKSUM: a4402d26aaec4ef7e58bd8304848d89c876d285a
|
||||
PODFILE CHECKSUM: c3bbb0fd2d81abb15a1f699210f18b2577ec458f
|
||||
|
||||
COCOAPODS: 1.10.1
|
||||
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mattermost-mobile",
|
||||
"version": "1.44.0",
|
||||
"version": "1.44.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -21489,9 +21489,9 @@
|
||||
}
|
||||
},
|
||||
"react-native-navigation": {
|
||||
"version": "7.13.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-navigation/-/react-native-navigation-7.13.0.tgz",
|
||||
"integrity": "sha512-/mdNuTlz9YVplJRB7Rv3g5cDgHCtw4RyG6ATdvrIJvMJOCU57ivCHuZkZDI/YQv7Txm48XD/EUkNahFFUATFZg==",
|
||||
"version": "7.11.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-navigation/-/react-native-navigation-7.11.3.tgz",
|
||||
"integrity": "sha512-3cCtHwa2Tqc5Uk4QFSfocfOgOSKcRgfVlZ1m40oFUGV8yx9TaqA9BlPyQnWtaaPz8lHgKA3pkUmXQpFq0zOQzw==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "3.x.x",
|
||||
"lodash": "4.17.x",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mattermost-mobile",
|
||||
"version": "1.44.0",
|
||||
"version": "1.44.1",
|
||||
"description": "Mattermost Mobile with React Native",
|
||||
"repository": "git@github.com:mattermost/mattermost-mobile.git",
|
||||
"author": "Mattermost, Inc.",
|
||||
@@ -55,7 +55,7 @@
|
||||
"react-native-local-auth": "1.6.0",
|
||||
"react-native-localize": "2.0.3",
|
||||
"react-native-mmkv-storage": "0.4.4",
|
||||
"react-native-navigation": "7.13.0",
|
||||
"react-native-navigation": "7.11.3",
|
||||
"react-native-notifications": "3.4.2",
|
||||
"react-native-passcode-status": "1.1.2",
|
||||
"react-native-permissions": "3.0.3",
|
||||
|
||||
Reference in New Issue
Block a user