Merge branch 'master' into mark-as-unread
This commit is contained in:
commit
d59b62daf8
15 changed files with 574 additions and 72 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -40,6 +40,9 @@ ios/Pods
|
|||
local.properties
|
||||
*.iml
|
||||
android/app/bin
|
||||
.settings
|
||||
.project
|
||||
.classpath
|
||||
|
||||
# node.js
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1,22 +1,37 @@
|
|||
Please make sure you've read the [pull request](https://developers.mattermost.com/contribute/getting-started/contribution-checklist/) section of our [code contribution guidelines](https://developers.mattermost.com/contribute/getting-started/).
|
||||
<!-- Thank you for contributing a pull request! Here are a few tips to help you:
|
||||
|
||||
When filling in a section please remove the help text and the above text.
|
||||
1. If this is your first contribution, make sure you've read the Contribution Checklist https://developers.mattermost.com/contribute/getting-started/contribution-checklist/
|
||||
2. Read our blog post about "Submitting Great PRs" https://developers.mattermost.com/blog/2019-01-24-submitting-great-prs
|
||||
3. Take a look at other repository specific documentation at https://developers.mattermost.com/contribute
|
||||
-->
|
||||
|
||||
#### Summary
|
||||
[A brief description of what this pull request does.]
|
||||
<!--
|
||||
A brief description of what this pull request does.
|
||||
-->
|
||||
|
||||
#### Ticket Link
|
||||
[Please link the GitHub issue or Jira ticket this PR addresses.]
|
||||
<!--
|
||||
If this pull request addresses a Help Wanted ticket, please link the relevant GitHub issue, e.g.
|
||||
|
||||
Fixes https://github.com/mattermost/mattermost-server/issues/XXXXX
|
||||
|
||||
Otherwise, link the JIRA ticket.
|
||||
-->
|
||||
|
||||
#### Checklist
|
||||
[Place an '[x]' (no spaces) in all applicable fields. Please remove unrelated fields.]
|
||||
<!--
|
||||
Place an '[x]' (no spaces) in all applicable fields. Please remove unrelated fields.
|
||||
-->
|
||||
- [ ] Added or updated unit tests (required for all new features)
|
||||
- [ ] All new/modified APIs include changes to [mattermost-redux](https://github.com/mattermost/mattermost-redux) (please link)
|
||||
- [ ] Has UI changes
|
||||
- [ ] Includes text changes and localization file updates
|
||||
|
||||
#### Device Information
|
||||
This PR was tested on: [Device name(s), OS version(s)]
|
||||
This PR was tested on: <!-- Device name(s), OS version(s) -->
|
||||
|
||||
#### Screenshots
|
||||
[If the PR includes UI changes, include screenshots (for both iOS and Android if possible).]
|
||||
<!--
|
||||
If the PR includes UI changes, include screenshots/GIFs (for both iOS and Android if possible).
|
||||
-->
|
||||
|
|
@ -84,17 +84,15 @@ export default class SafeAreaIos extends PureComponent {
|
|||
getSafeAreaInsets = async (dimensions) => {
|
||||
this.getStatusBarHeight();
|
||||
|
||||
const safeAreaInsetsStored = EphemeralStore.safeAreaInsets[PORTRAIT] !== null && EphemeralStore.safeAreaInsets[LANDSCAPE] !== null;
|
||||
if ((DeviceTypes.IS_IPHONE_WITH_INSETS || mattermostManaged.hasSafeAreaInsets) && !safeAreaInsetsStored) {
|
||||
if (DeviceTypes.IS_IPHONE_WITH_INSETS || mattermostManaged.hasSafeAreaInsets) {
|
||||
const window = dimensions?.window || Dimensions.get('window');
|
||||
const landscape = window.width > window.length;
|
||||
const orientation = window.width > window.length ? LANDSCAPE : PORTRAIT;
|
||||
const {safeAreaInsets} = await SafeArea.getSafeAreaInsetsForRootView();
|
||||
this.setSafeAreaInsets(safeAreaInsets, landscape);
|
||||
this.setSafeAreaInsets(safeAreaInsets, orientation);
|
||||
}
|
||||
}
|
||||
|
||||
setSafeAreaInsets = (safeAreaInsets, landscape) => {
|
||||
const orientation = landscape ? LANDSCAPE : PORTRAIT;
|
||||
setSafeAreaInsets = (safeAreaInsets, orientation) => {
|
||||
if (EphemeralStore.safeAreaInsets[orientation] === null) {
|
||||
EphemeralStore.safeAreaInsets[orientation] = safeAreaInsets;
|
||||
}
|
||||
|
|
@ -130,8 +128,8 @@ export default class SafeAreaIos extends PureComponent {
|
|||
this.getStatusBarHeight();
|
||||
|
||||
const {width, height} = Dimensions.get('window');
|
||||
const landscape = width > height;
|
||||
this.setSafeAreaInsets(safeAreaInsets, landscape);
|
||||
const orientation = width > height ? LANDSCAPE : PORTRAIT;
|
||||
this.setSafeAreaInsets(safeAreaInsets, orientation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -195,9 +195,9 @@ describe('SafeAreaIos', () => {
|
|||
expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null);
|
||||
expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null);
|
||||
|
||||
const landscape = false;
|
||||
const orientation = PORTRAIT;
|
||||
const instance = wrapper.instance();
|
||||
instance.setSafeAreaInsets(PORTRAIT_INSETS.safeAreaInsets, landscape);
|
||||
instance.setSafeAreaInsets(PORTRAIT_INSETS.safeAreaInsets, orientation);
|
||||
expect(wrapper.state().safeAreaInsets).toEqual(PORTRAIT_INSETS.safeAreaInsets);
|
||||
expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(PORTRAIT_INSETS.safeAreaInsets);
|
||||
expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null);
|
||||
|
|
@ -211,9 +211,9 @@ describe('SafeAreaIos', () => {
|
|||
EphemeralStore.safeAreaInsets[PORTRAIT] = PORTRAIT_INSETS.safeAreaInsets;
|
||||
expect(wrapper.state().safeAreaInsets).not.toEqual(PORTRAIT_INSETS.safeAreaInsets);
|
||||
|
||||
const landscape = false;
|
||||
const orientation = PORTRAIT;
|
||||
const instance = wrapper.instance();
|
||||
instance.setSafeAreaInsets(IGNORED_INSETS.safeAreaInsets, landscape);
|
||||
instance.setSafeAreaInsets(IGNORED_INSETS.safeAreaInsets, orientation);
|
||||
expect(wrapper.state().safeAreaInsets).toEqual(PORTRAIT_INSETS.safeAreaInsets);
|
||||
expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(PORTRAIT_INSETS.safeAreaInsets);
|
||||
expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null);
|
||||
|
|
@ -228,9 +228,9 @@ describe('SafeAreaIos', () => {
|
|||
expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null);
|
||||
expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null);
|
||||
|
||||
const landscape = true;
|
||||
const orientation = LANDSCAPE;
|
||||
const instance = wrapper.instance();
|
||||
instance.setSafeAreaInsets(LANDSCAPE_INSETS.safeAreaInsets, landscape);
|
||||
instance.setSafeAreaInsets(LANDSCAPE_INSETS.safeAreaInsets, orientation);
|
||||
expect(wrapper.state().safeAreaInsets).toEqual(LANDSCAPE_INSETS.safeAreaInsets);
|
||||
expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(LANDSCAPE_INSETS.safeAreaInsets);
|
||||
expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null);
|
||||
|
|
@ -244,9 +244,9 @@ describe('SafeAreaIos', () => {
|
|||
EphemeralStore.safeAreaInsets[LANDSCAPE] = LANDSCAPE_INSETS.safeAreaInsets;
|
||||
expect(wrapper.state().safeAreaInsets).not.toEqual(LANDSCAPE_INSETS.safeAreaInsets);
|
||||
|
||||
const landscape = true;
|
||||
const orientation = LANDSCAPE;
|
||||
const instance = wrapper.instance();
|
||||
instance.setSafeAreaInsets(IGNORED_INSETS.safeAreaInsets, landscape);
|
||||
instance.setSafeAreaInsets(IGNORED_INSETS.safeAreaInsets, orientation);
|
||||
expect(wrapper.state().safeAreaInsets).toEqual(LANDSCAPE_INSETS.safeAreaInsets);
|
||||
expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(LANDSCAPE_INSETS.safeAreaInsets);
|
||||
expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null);
|
||||
|
|
@ -302,27 +302,4 @@ describe('SafeAreaIos', () => {
|
|||
instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_1);
|
||||
expect(removeEventListener).toHaveBeenCalledWith('safeAreaInsetsForRootViewDidChange', instance.onSafeAreaInsetsForRootViewChange);
|
||||
});
|
||||
|
||||
test('getSafeAreaInsets should set safe area insets when not already in ephemeral store', async () => {
|
||||
const wrapper = shallow(
|
||||
<SafeAreaIos {...baseProps}/>
|
||||
);
|
||||
const instance = wrapper.instance();
|
||||
const setSafeAreaInsets = jest.spyOn(instance, 'setSafeAreaInsets');
|
||||
|
||||
expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null);
|
||||
expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null);
|
||||
await instance.getSafeAreaInsets();
|
||||
expect(setSafeAreaInsets).toHaveBeenCalled();
|
||||
setSafeAreaInsets.mockClear();
|
||||
|
||||
EphemeralStore.safeAreaInsets[PORTRAIT] = TEST_INSETS_1.safeAreaInsets; /* eslint-disable-line require-atomic-updates */
|
||||
await instance.getSafeAreaInsets();
|
||||
expect(setSafeAreaInsets).toHaveBeenCalled();
|
||||
setSafeAreaInsets.mockClear();
|
||||
|
||||
EphemeralStore.safeAreaInsets[LANDSCAPE] = TEST_INSETS_1.safeAreaInsets; /* eslint-disable-line require-atomic-updates */
|
||||
await instance.getSafeAreaInsets();
|
||||
expect(setSafeAreaInsets).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
7
app/constants/about_links.js
Normal file
7
app/constants/about_links.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export default {
|
||||
TERMS_OF_SERVICE: 'https://about.mattermost.com/default-terms/',
|
||||
PRIVACY_POLICY: 'https://about.mattermost.com/default-privacy-policy/',
|
||||
};
|
||||
|
|
@ -18,6 +18,7 @@ import {changeOpacity, makeStyleSheetFromTheme, setNavigatorStyles} from 'app/ut
|
|||
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
|
||||
import AppIcon from 'app/components/app_icon';
|
||||
import Config from 'assets/config';
|
||||
import AboutLinks from 'app/constants/about_links';
|
||||
|
||||
const MATTERMOST_BUNDLE_IDS = ['com.mattermost.rnbeta', 'com.mattermost.rn'];
|
||||
|
||||
|
|
@ -53,11 +54,11 @@ export default class About extends PureComponent {
|
|||
};
|
||||
|
||||
handleTermsOfService = () => {
|
||||
Linking.openURL(this.props.config.TermsOfServiceLink);
|
||||
Linking.openURL(AboutLinks.TERMS_OF_SERVICE);
|
||||
};
|
||||
|
||||
handlePrivacyPolicy = () => {
|
||||
Linking.openURL(this.props.config.PrivacyPolicyLink);
|
||||
Linking.openURL(AboutLinks.PRIVACY_POLICY);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,397 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`NotificationSettings should match snapshot 1`] = `
|
||||
NotificationSettings {
|
||||
"context": Object {
|
||||
"intl": Object {
|
||||
"defaultFormats": Object {},
|
||||
"defaultLocale": "en",
|
||||
"formatDate": [Function],
|
||||
"formatHTMLMessage": [Function],
|
||||
"formatMessage": [Function],
|
||||
"formatNumber": [Function],
|
||||
"formatPlural": [Function],
|
||||
"formatRelative": [Function],
|
||||
"formatTime": [Function],
|
||||
"formats": Object {},
|
||||
"formatters": Object {
|
||||
"getDateTimeFormat": [Function],
|
||||
"getMessageFormat": [Function],
|
||||
"getNumberFormat": [Function],
|
||||
"getPluralFormat": [Function],
|
||||
"getRelativeFormat": [Function],
|
||||
},
|
||||
"locale": "en",
|
||||
"messages": Object {},
|
||||
"now": [Function],
|
||||
"onError": [Function],
|
||||
"textComponent": "span",
|
||||
"timeZone": null,
|
||||
},
|
||||
},
|
||||
"goToNotificationSettingsAutoResponder": [Function],
|
||||
"goToNotificationSettingsEmail": [Function],
|
||||
"goToNotificationSettingsMentions": [Function],
|
||||
"goToNotificationSettingsMobile": [Function],
|
||||
"handlePress": [Function],
|
||||
"props": Object {
|
||||
"actions": Object {
|
||||
"updateMe": [MockFunction],
|
||||
},
|
||||
"componentId": "component-id",
|
||||
"currentUser": Object {
|
||||
"id": "current_user_id",
|
||||
},
|
||||
"currentUserStatus": "status",
|
||||
"enableAutoResponder": false,
|
||||
"intl": Object {
|
||||
"defaultFormats": Object {},
|
||||
"defaultLocale": "en",
|
||||
"formatDate": [Function],
|
||||
"formatHTMLMessage": [Function],
|
||||
"formatMessage": [Function],
|
||||
"formatNumber": [Function],
|
||||
"formatPlural": [Function],
|
||||
"formatRelative": [Function],
|
||||
"formatTime": [Function],
|
||||
"formats": Object {},
|
||||
"formatters": Object {
|
||||
"getDateTimeFormat": [Function],
|
||||
"getMessageFormat": [Function],
|
||||
"getNumberFormat": [Function],
|
||||
"getPluralFormat": [Function],
|
||||
"getRelativeFormat": [Function],
|
||||
},
|
||||
"locale": "en",
|
||||
"messages": Object {},
|
||||
"now": [Function],
|
||||
"onError": [Function],
|
||||
"textComponent": "span",
|
||||
"timeZone": null,
|
||||
},
|
||||
"isLandscape": false,
|
||||
"theme": Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBg": "#ffffff",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
},
|
||||
"updateMeRequest": Object {},
|
||||
},
|
||||
"refs": Object {},
|
||||
"saveAutoResponder": [Function],
|
||||
"saveNotificationProps": [Function],
|
||||
"setState": [Function],
|
||||
"shouldSaveAutoResponder": [Function],
|
||||
"state": null,
|
||||
"updater": Updater {
|
||||
"_callbacks": Array [],
|
||||
"_renderer": ReactShallowRenderer {
|
||||
"_context": Object {
|
||||
"intl": Object {
|
||||
"defaultFormats": Object {},
|
||||
"defaultLocale": "en",
|
||||
"formatDate": [Function],
|
||||
"formatHTMLMessage": [Function],
|
||||
"formatMessage": [Function],
|
||||
"formatNumber": [Function],
|
||||
"formatPlural": [Function],
|
||||
"formatRelative": [Function],
|
||||
"formatTime": [Function],
|
||||
"formats": Object {},
|
||||
"formatters": Object {
|
||||
"getDateTimeFormat": [Function],
|
||||
"getMessageFormat": [Function],
|
||||
"getNumberFormat": [Function],
|
||||
"getPluralFormat": [Function],
|
||||
"getRelativeFormat": [Function],
|
||||
},
|
||||
"locale": "en",
|
||||
"messages": Object {},
|
||||
"now": [Function],
|
||||
"onError": [Function],
|
||||
"textComponent": "span",
|
||||
"timeZone": null,
|
||||
},
|
||||
},
|
||||
"_didScheduleRenderPhaseUpdate": false,
|
||||
"_dispatcher": Object {
|
||||
"readContext": [Function],
|
||||
"useCallback": [Function],
|
||||
"useContext": [Function],
|
||||
"useDebugValue": [Function],
|
||||
"useEffect": [Function],
|
||||
"useImperativeHandle": [Function],
|
||||
"useLayoutEffect": [Function],
|
||||
"useMemo": [Function],
|
||||
"useReducer": [Function],
|
||||
"useRef": [Function],
|
||||
"useResponder": [Function],
|
||||
"useState": [Function],
|
||||
},
|
||||
"_element": <NotificationSettings
|
||||
actions={
|
||||
Object {
|
||||
"updateMe": [MockFunction],
|
||||
}
|
||||
}
|
||||
componentId="component-id"
|
||||
currentUser={
|
||||
Object {
|
||||
"id": "current_user_id",
|
||||
}
|
||||
}
|
||||
currentUserStatus="status"
|
||||
enableAutoResponder={false}
|
||||
intl={
|
||||
Object {
|
||||
"defaultFormats": Object {},
|
||||
"defaultLocale": "en",
|
||||
"formatDate": [Function],
|
||||
"formatHTMLMessage": [Function],
|
||||
"formatMessage": [Function],
|
||||
"formatNumber": [Function],
|
||||
"formatPlural": [Function],
|
||||
"formatRelative": [Function],
|
||||
"formatTime": [Function],
|
||||
"formats": Object {},
|
||||
"formatters": Object {
|
||||
"getDateTimeFormat": [Function],
|
||||
"getMessageFormat": [Function],
|
||||
"getNumberFormat": [Function],
|
||||
"getPluralFormat": [Function],
|
||||
"getRelativeFormat": [Function],
|
||||
},
|
||||
"locale": "en",
|
||||
"messages": Object {},
|
||||
"now": [Function],
|
||||
"onError": [Function],
|
||||
"textComponent": "span",
|
||||
"timeZone": null,
|
||||
}
|
||||
}
|
||||
isLandscape={false}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBg": "#ffffff",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
updateMeRequest={Object {}}
|
||||
/>,
|
||||
"_firstWorkInProgressHook": null,
|
||||
"_forcedUpdate": false,
|
||||
"_instance": [Circular],
|
||||
"_isReRender": false,
|
||||
"_newState": null,
|
||||
"_numberOfReRenders": 0,
|
||||
"_renderPhaseUpdates": null,
|
||||
"_rendered": <View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Connect(StatusBar) />
|
||||
<ScrollViewMock
|
||||
alwaysBounceVertical={false}
|
||||
contentContainerStyle={
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.06)",
|
||||
"paddingTop": 35,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.1)",
|
||||
"height": 1,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<SettingsItem
|
||||
defaultMessage="Mentions and Replies"
|
||||
i18nId="mobile.notification_settings.mentions_replies"
|
||||
iconName="md-at"
|
||||
iconType="ion"
|
||||
isDestructor={false}
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
separator={true}
|
||||
showArrow={true}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBg": "#ffffff",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<SettingsItem
|
||||
defaultMessage="Mobile"
|
||||
i18nId="mobile.notification_settings.mobile"
|
||||
iconName="md-phone-portrait"
|
||||
iconType="ion"
|
||||
isDestructor={false}
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
separator={true}
|
||||
showArrow={true}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBg": "#ffffff",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<SettingsItem
|
||||
defaultMessage="Email"
|
||||
i18nId="mobile.notification_settings.email"
|
||||
iconName="ios-mail"
|
||||
iconType="ion"
|
||||
isDestructor={false}
|
||||
isLandscape={false}
|
||||
onPress={[Function]}
|
||||
separator={false}
|
||||
showArrow={true}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBg": "#ffffff",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.1)",
|
||||
"height": 1,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</ScrollViewMock>
|
||||
</View>,
|
||||
"_rendering": false,
|
||||
"_updater": [Circular],
|
||||
"_workInProgressHook": null,
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {injectIntl, intlShape} from 'react-intl';
|
||||
import {intlShape} from 'react-intl';
|
||||
import {
|
||||
Alert,
|
||||
Platform,
|
||||
|
|
@ -23,14 +23,13 @@ import {changeOpacity, makeStyleSheetFromTheme, setNavigatorStyles} from 'app/ut
|
|||
import {t} from 'app/utils/i18n';
|
||||
import {goToScreen} from 'app/actions/navigation';
|
||||
|
||||
class NotificationSettings extends PureComponent {
|
||||
export default class NotificationSettings extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
updateMe: PropTypes.func.isRequired,
|
||||
}),
|
||||
componentId: PropTypes.string,
|
||||
currentUser: PropTypes.object.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
updateMeRequest: PropTypes.object.isRequired,
|
||||
currentUserStatus: PropTypes.string.isRequired,
|
||||
|
|
@ -38,12 +37,17 @@ class NotificationSettings extends PureComponent {
|
|||
isLandscape: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.theme !== nextProps.theme) {
|
||||
setNavigatorStyles(this.props.componentId, nextProps.theme);
|
||||
}
|
||||
|
||||
const {updateMeRequest, intl} = nextProps;
|
||||
const {updateMeRequest} = nextProps;
|
||||
const {intl} = this.context;
|
||||
if (this.props.updateMeRequest !== updateMeRequest && updateMeRequest.status === RequestStatus.FAILURE) {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
|
|
@ -63,7 +67,8 @@ class NotificationSettings extends PureComponent {
|
|||
});
|
||||
|
||||
goToNotificationSettingsAutoResponder = () => {
|
||||
const {currentUser, intl} = this.props;
|
||||
const {currentUser} = this.props;
|
||||
const {intl} = this.context;
|
||||
const screen = 'NotificationSettingsAutoResponder';
|
||||
const title = intl.formatMessage({
|
||||
id: 'mobile.notification_settings.auto_responder_short',
|
||||
|
|
@ -78,7 +83,7 @@ class NotificationSettings extends PureComponent {
|
|||
};
|
||||
|
||||
goToNotificationSettingsEmail = () => {
|
||||
const {intl} = this.props;
|
||||
const {intl} = this.context;
|
||||
const screen = 'NotificationSettingsEmail';
|
||||
const title = intl.formatMessage({
|
||||
id: 'mobile.notification_settings.email_title',
|
||||
|
|
@ -89,7 +94,8 @@ class NotificationSettings extends PureComponent {
|
|||
};
|
||||
|
||||
goToNotificationSettingsMentions = () => {
|
||||
const {currentUser, intl} = this.props;
|
||||
const {currentUser} = this.props;
|
||||
const {intl} = this.context;
|
||||
const screen = 'NotificationSettingsMentions';
|
||||
const title = intl.formatMessage({
|
||||
id: 'mobile.notification_settings.mentions_replies',
|
||||
|
|
@ -104,7 +110,8 @@ class NotificationSettings extends PureComponent {
|
|||
};
|
||||
|
||||
goToNotificationSettingsMobile = () => {
|
||||
const {currentUser, intl} = this.props;
|
||||
const {currentUser} = this.props;
|
||||
const {intl} = this.context;
|
||||
const screen = 'NotificationSettingsMobile';
|
||||
const title = intl.formatMessage({
|
||||
id: 'mobile.notification_settings.mobile_title',
|
||||
|
|
@ -127,14 +134,13 @@ class NotificationSettings extends PureComponent {
|
|||
|
||||
saveNotificationProps = (notifyProps) => {
|
||||
const {currentUser} = this.props;
|
||||
const {user_id: userId} = notifyProps;
|
||||
const previousProps = {
|
||||
const updatedProps = {
|
||||
...getNotificationProps(currentUser),
|
||||
user_id: userId,
|
||||
...notifyProps,
|
||||
};
|
||||
|
||||
if (!deepEqual(previousProps, notifyProps)) {
|
||||
this.props.actions.updateMe({notify_props: notifyProps});
|
||||
if (!deepEqual(updatedProps, notifyProps)) {
|
||||
this.props.actions.updateMe({notify_props: updatedProps});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -158,7 +164,7 @@ class NotificationSettings extends PureComponent {
|
|||
};
|
||||
|
||||
saveAutoResponder = (notifyProps) => {
|
||||
const {intl} = this.props;
|
||||
const {intl} = this.context;
|
||||
|
||||
if (!notifyProps.auto_responder_message || notifyProps.auto_responder_message === '') {
|
||||
notifyProps.auto_responder_message = intl.formatMessage({
|
||||
|
|
@ -265,5 +271,3 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default injectIntl(NotificationSettings);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Preferences from 'mattermost-redux/constants/preferences';
|
||||
|
||||
import {shallowWithIntl} from 'test/intl-test-helper';
|
||||
|
||||
import NotificationSettings from './notification_settings.js';
|
||||
|
||||
describe('NotificationSettings', () => {
|
||||
const baseProps = {
|
||||
actions: {
|
||||
updateMe: jest.fn(),
|
||||
},
|
||||
componentId: 'component-id',
|
||||
currentUser: {id: 'current_user_id'},
|
||||
theme: Preferences.THEMES.default,
|
||||
updateMeRequest: {},
|
||||
currentUserStatus: 'status',
|
||||
enableAutoResponder: false,
|
||||
isLandscape: false,
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<NotificationSettings {...baseProps}/>
|
||||
);
|
||||
|
||||
expect(wrapper.instance()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should include previous notification props when saving new ones', () => {
|
||||
baseProps.currentUser.notify_props = {previous: 'previous'};
|
||||
const wrapper = shallowWithIntl(
|
||||
<NotificationSettings {...baseProps}/>
|
||||
);
|
||||
|
||||
const instance = wrapper.instance();
|
||||
const newProps = {new: 'new'};
|
||||
instance.saveNotificationProps(newProps);
|
||||
expect(baseProps.actions.updateMe).toHaveBeenCalledWith({
|
||||
notify_props: {
|
||||
...baseProps.currentUser.notify_props,
|
||||
...newProps,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -4,6 +4,7 @@ exports[`thread should match snapshot, has root post 1`] = `
|
|||
<React.Fragment>
|
||||
<Connect(SafeAreaIos)
|
||||
excludeHeader={true}
|
||||
forceInsets={true}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
@ -74,6 +75,7 @@ exports[`thread should match snapshot, no root post, loading 1`] = `
|
|||
<React.Fragment>
|
||||
<Connect(SafeAreaIos)
|
||||
excludeHeader={true}
|
||||
forceInsets={true}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
@ -143,6 +145,7 @@ exports[`thread should match snapshot, render footer 3`] = `
|
|||
<React.Fragment>
|
||||
<Connect(SafeAreaIos)
|
||||
excludeHeader={true}
|
||||
forceInsets={true}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
|
|
|
|||
|
|
@ -92,7 +92,10 @@ export default class ThreadIOS extends ThreadBase {
|
|||
const style = getStyleSheet(theme);
|
||||
return (
|
||||
<React.Fragment>
|
||||
<SafeAreaView excludeHeader={true}>
|
||||
<SafeAreaView
|
||||
excludeHeader={true}
|
||||
forceInsets={true}
|
||||
>
|
||||
<View style={style.separator}/>
|
||||
<StatusBar/>
|
||||
{content}
|
||||
|
|
|
|||
|
|
@ -99,15 +99,20 @@ export const filterMembersNotInChannel = createSelector(
|
|||
let profiles;
|
||||
if (matchTerm) {
|
||||
profiles = profilesNotInChannel.filter((p) => {
|
||||
return ((p.id !== currentUserId && p.detele_at === 0) && (
|
||||
p.username.toLowerCase().includes(matchTerm) || p.email.toLowerCase().includes(matchTerm) ||
|
||||
p.first_name.toLowerCase().includes(matchTerm) || p.last_name.toLowerCase().includes(matchTerm)));
|
||||
return (
|
||||
p.username.toLowerCase().includes(matchTerm) ||
|
||||
p.email.toLowerCase().includes(matchTerm) ||
|
||||
p.first_name.toLowerCase().includes(matchTerm) ||
|
||||
p.last_name.toLowerCase().includes(matchTerm)
|
||||
) && (p.delete_at === 0 && p.id !== currentUserId);
|
||||
});
|
||||
} else {
|
||||
profiles = profilesNotInChannel.filter((p) => p.delete_at === 0);
|
||||
}
|
||||
|
||||
return profiles.map((p) => p.id);
|
||||
return profiles.map((p) => {
|
||||
return p.id;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import assert from 'assert';
|
|||
|
||||
import {
|
||||
getMatchTermForAtMention,
|
||||
filterMembersNotInChannel,
|
||||
} from 'app/selectors/autocomplete';
|
||||
|
||||
/* eslint-disable max-nested-callbacks */
|
||||
|
|
@ -56,4 +57,42 @@ describe('Selectors.Autocomplete', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Should return profiles not in channel', () => {
|
||||
const state = {
|
||||
entities: {
|
||||
channels: {
|
||||
currentChannelId: 'current-channel-id',
|
||||
},
|
||||
users: {
|
||||
currentUserId: 'current-user-id',
|
||||
profiles: {
|
||||
'current-user-id': {id: 'current-user-id', username: 'current', delete_at: 0},
|
||||
'test-user-id': {id: 'test-user-id', username: 'test', first_name: 'Test', last_name: 'User', email: 'test@example.com', delete_at: 0},
|
||||
'another-user-id': {id: 'another-user-id', username: 'another', first_name: 'Another', last_name: 'One', email: 'another@example.com', delete_at: 0},
|
||||
'deleted-user-id': {id: 'deleted-user-id', username: 'deleted', first_name: 'Remvoed', last_name: 'Friend', email: 'deleted@example.com', delete_at: 123},
|
||||
},
|
||||
profilesNotInChannel: {
|
||||
'current-channel-id': new Set(['test-user-id', 'another-user-id', 'deleted-user-id']),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let profiles = filterMembersNotInChannel(state, '');
|
||||
expect(profiles.length).toBe(2);
|
||||
|
||||
// filter to get the current user, should return zero results
|
||||
profiles = filterMembersNotInChannel(state, 'current');
|
||||
expect(profiles.length).toBe(0);
|
||||
|
||||
profiles = filterMembersNotInChannel(state, 'tes');
|
||||
expect(profiles.length).toBe(1);
|
||||
|
||||
profiles = filterMembersNotInChannel(state, 'one');
|
||||
expect(profiles.length).toBe(1);
|
||||
|
||||
profiles = filterMembersNotInChannel(state, 'example');
|
||||
expect(profiles.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -7778,8 +7778,8 @@
|
|||
}
|
||||
},
|
||||
"mattermost-redux": {
|
||||
"version": "github:mattermost/mattermost-redux#ad9a13e34dfbae9981eddda27711c5c14134d009",
|
||||
"from": "github:mattermost/mattermost-redux#ad9a13e34dfbae9981eddda27711c5c14134d009",
|
||||
"version": "github:mattermost/mattermost-redux#edaa6ebc4077ec65e51c2864db0abbd04e1d8db9",
|
||||
"from": "github:mattermost/mattermost-redux#edaa6ebc4077ec65e51c2864db0abbd04e1d8db9",
|
||||
"requires": {
|
||||
"gfycat-sdk": "1.4.18",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
"intl": "1.2.5",
|
||||
"jail-monkey": "2.3.0",
|
||||
"jsc-android": "241213.1.0",
|
||||
"mattermost-redux": "github:mattermost/mattermost-redux#ad9a13e34dfbae9981eddda27711c5c14134d009",
|
||||
"mattermost-redux": "github:mattermost/mattermost-redux#edaa6ebc4077ec65e51c2864db0abbd04e1d8db9",
|
||||
"mime-db": "1.42.0",
|
||||
"moment-timezone": "0.5.27",
|
||||
"prop-types": "15.7.2",
|
||||
|
|
|
|||
Loading…
Reference in a new issue