RN-246 include NOTICE links in about screen (#777)
* RN-246 include NOTICE links in about screen * Feedback review
This commit is contained in:
parent
8a7840b58a
commit
8a3e410995
4 changed files with 114 additions and 7 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {Component, createElement, isValidElement} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {Text} from 'react-native';
|
||||
import {injectIntl, intlShape} from 'react-intl';
|
||||
|
|
@ -27,11 +27,67 @@ class FormattedText extends Component {
|
|||
...props
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Text {...props}>
|
||||
{intl.formatMessage({id, defaultMessage}, values)}
|
||||
</Text>
|
||||
);
|
||||
let tokenDelimiter;
|
||||
let tokenizedValues;
|
||||
let elements;
|
||||
const hasValues = values && Object.keys(values).length > 0;
|
||||
if (hasValues) {
|
||||
// Creates a token with a random UID that should not be guessable or
|
||||
// conflict with other parts of the `message` string.
|
||||
const uid = Math.floor(Math.random() * 0x10000000000).toString(16);
|
||||
|
||||
const generateToken = (() => {
|
||||
let counter = 0;
|
||||
return () => {
|
||||
const elementId = `ELEMENT-${uid}-${counter += 1}`;
|
||||
return elementId;
|
||||
};
|
||||
})();
|
||||
|
||||
// Splitting with a delimiter to support IE8. When using a regex
|
||||
// with a capture group IE8 does not include the capture group in
|
||||
// the resulting array.
|
||||
tokenDelimiter = `@__${uid}__@`;
|
||||
tokenizedValues = {};
|
||||
elements = {};
|
||||
|
||||
// Iterates over the `props` to keep track of any React Element
|
||||
// values so they can be represented by the `token` as a placeholder
|
||||
// when the `message` is formatted. This allows the formatted
|
||||
// message to then be broken-up into parts with references to the
|
||||
// React Elements inserted back in.
|
||||
Object.keys(values).forEach((name) => {
|
||||
const value = values[name];
|
||||
|
||||
if (isValidElement(value)) {
|
||||
const token = generateToken();
|
||||
tokenizedValues[name] = tokenDelimiter + token + tokenDelimiter;
|
||||
elements[token] = value;
|
||||
} else {
|
||||
tokenizedValues[name] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const descriptor = {id, defaultMessage};
|
||||
const formattedMessage = intl.formatMessage(descriptor, tokenizedValues || values);
|
||||
const hasElements = elements && Object.keys(elements).length > 0;
|
||||
|
||||
let nodes;
|
||||
if (hasElements) {
|
||||
// Split the message into parts so the React Element values captured
|
||||
// above can be inserted back into the rendered message. This
|
||||
// approach allows messages to render with React Elements while
|
||||
// keeping React's virtual diffing working properly.
|
||||
nodes = formattedMessage.
|
||||
split(tokenDelimiter).
|
||||
filter((part) => Boolean(part)).
|
||||
map((part) => elements[part] || part);
|
||||
} else {
|
||||
nodes = [formattedMessage];
|
||||
}
|
||||
|
||||
return createElement(Text, props, ...nodes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import StatusBar from 'app/components/status_bar';
|
|||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
import MattermostIcon from 'app/components/mattermost_icon';
|
||||
import Config from 'assets/config';
|
||||
|
||||
export default class About extends PureComponent {
|
||||
static propTypes = {
|
||||
|
|
@ -34,6 +35,14 @@ export default class About extends PureComponent {
|
|||
Linking.openURL('http://about.mattermost.com/');
|
||||
};
|
||||
|
||||
handlePlatformNotice = () => {
|
||||
Linking.openURL(Config.PlatformNoticeURL);
|
||||
};
|
||||
|
||||
handleMobileNotice = () => {
|
||||
Linking.openURL(Config.MobileNoticeURL);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {theme, config, license} = this.props;
|
||||
const style = getStyleSheet(theme);
|
||||
|
|
@ -206,6 +215,33 @@ export default class About extends PureComponent {
|
|||
currentYear: new Date().getFullYear()
|
||||
}}
|
||||
/>
|
||||
<View style={style.noticeContainer}>
|
||||
<View style={style.footerGroup}>
|
||||
<FormattedText
|
||||
id='mobile.notice_text'
|
||||
defaultMessage='Mattermost is made possible by the open source software in our {platform} and {mobile}.'
|
||||
style={style.footerText}
|
||||
values={{
|
||||
platform: (
|
||||
<FormattedText
|
||||
id='mobile.notice_platform_link'
|
||||
defaultMessage='platform'
|
||||
style={style.noticeLink}
|
||||
onPress={this.handlePlatformNotice}
|
||||
/>
|
||||
),
|
||||
mobile: (
|
||||
<FormattedText
|
||||
id='mobile.notice_mobile_link'
|
||||
defaultMessage='mobile apps'
|
||||
style={[style.noticeLink, {marginLeft: 5}]}
|
||||
onPress={this.handleMobileNotice}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={style.hashContainer}>
|
||||
<View style={style.footerGroup}>
|
||||
<FormattedText
|
||||
|
|
@ -306,6 +342,16 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
flexDirection: 'row',
|
||||
marginVertical: 20
|
||||
},
|
||||
noticeContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
marginTop: 10
|
||||
},
|
||||
noticeLink: {
|
||||
color: theme.linkColor,
|
||||
fontSize: 11,
|
||||
lineHeight: 13
|
||||
},
|
||||
hashContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"TestServerUrl": "http://localhost:8065",
|
||||
"DefaultTheme": "default",
|
||||
"ShowErrorsList": false,
|
||||
"MinServerVersion": "3.10.0"
|
||||
"MinServerVersion": "3.10.0",
|
||||
"PlatformNoticeURL": "https://about.mattermost.com/platform-notice-txt/",
|
||||
"MobileNoticeURL": "https://about.mattermost.com/mobile-notice-txt/"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1768,6 +1768,9 @@
|
|||
"mobile.login_options.choose_title": "Choose your login method",
|
||||
"mobile.more_dms.start": "Start",
|
||||
"mobile.more_dms.title": "New Conversation",
|
||||
"mobile.notice_text": "Mattermost is made possible by the open source software in our {platform} and {mobile}.",
|
||||
"mobile.notice_mobile_link": "mobile apps",
|
||||
"mobile.notice_platform_link": "platform",
|
||||
"mobile.notification.in": " in ",
|
||||
"mobile.offlineIndicator.connected": "Connected",
|
||||
"mobile.offlineIndicator.connecting": "Connecting...",
|
||||
|
|
|
|||
Loading…
Reference in a new issue