Gekidou about screen (#5591)
* Added about screen * Remove TS error * Needs clean up * Testing login flow * Converted About screen to functional component * Improvements * Sort imports * Prevents double tapping * Apply suggestions from code review Co-authored-by: Elias Nahum <nahumhbl@gmail.com> * Code clean up * Adding translation keys * Added some keys * Updated AppVersion component * Missed translation key Co-authored-by: Avinash Lingaloo <> Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
parent
7c5b3a1574
commit
0ef1dd44ea
18 changed files with 742 additions and 38 deletions
|
|
@ -2,9 +2,10 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
import {StyleSheet, TextStyle, View} from 'react-native';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
|
||||
import {t} from '@i18n';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
|
||||
const style = StyleSheet.create({
|
||||
|
|
@ -17,19 +18,32 @@ const style = StyleSheet.create({
|
|||
},
|
||||
});
|
||||
|
||||
const AppVersion = () => {
|
||||
type AppVersionProps = {
|
||||
isWrapped?: boolean;
|
||||
textStyle?: TextStyle;
|
||||
}
|
||||
|
||||
const AppVersion = ({isWrapped = true, textStyle = {}}: AppVersionProps) => {
|
||||
const appVersion = (
|
||||
<FormattedText
|
||||
id={t('mobile.about.appVersion')}
|
||||
defaultMessage='App Version: {version} (Build {number})'
|
||||
style={StyleSheet.flatten([style.version, textStyle])}
|
||||
values={{
|
||||
version: DeviceInfo.getVersion(),
|
||||
number: DeviceInfo.getBuildNumber(),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
if (!isWrapped) {
|
||||
return appVersion;
|
||||
}
|
||||
|
||||
return (
|
||||
<View pointerEvents='none'>
|
||||
<View style={style.info}>
|
||||
<FormattedText
|
||||
id='mobile.about.appVersion'
|
||||
defaultMessage='App Version: {version} (Build {number})'
|
||||
style={style.version}
|
||||
values={{
|
||||
version: DeviceInfo.getVersion(),
|
||||
number: DeviceInfo.getBuildNumber(),
|
||||
}}
|
||||
/>
|
||||
{appVersion}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export const ABOUT = 'About';
|
||||
export const CHANNEL = 'Channel';
|
||||
export const FORGOT_PASSWORD = 'ForgotPassword';
|
||||
export const LOGIN = 'Login';
|
||||
|
|
@ -13,6 +14,7 @@ export const SSO = 'SSO';
|
|||
export const THREAD = 'Thread';
|
||||
|
||||
export default {
|
||||
ABOUT,
|
||||
CHANNEL,
|
||||
FORGOT_PASSWORD,
|
||||
LOGIN,
|
||||
|
|
|
|||
347
app/screens/about/index.tsx
Normal file
347
app/screens/about/index.tsx
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Alert, ScrollView, Text, View} from 'react-native';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import {SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import Config from '@assets/config.json';
|
||||
import AppVersion from '@components/app_version';
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import StatusBar from '@components/status_bar';
|
||||
import AboutLinks from '@constants/about_links';
|
||||
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {t} from '@i18n';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {tryOpenURL} from '@utils/url';
|
||||
|
||||
import LearnMore from './learn_more';
|
||||
import ServerVersion from './server_version';
|
||||
import Subtitle from './subtitle';
|
||||
import Title from './title';
|
||||
import TosPrivacyContainer from './tos_privacy';
|
||||
|
||||
import type {WithDatabaseArgs} from '@typings/database/database';
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
|
||||
const MATTERMOST_BUNDLE_IDS = ['com.mattermost.rnbeta', 'com.mattermost.rn'];
|
||||
|
||||
type ConnectedAboutProps = {
|
||||
config: SystemModel;
|
||||
license: SystemModel;
|
||||
}
|
||||
|
||||
const ConnectedAbout = ({config, license}: ConnectedAboutProps) => {
|
||||
const intl = useIntl();
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
const openURL = useCallback((url: string) => {
|
||||
const onError = () => {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'mobile.link.error.title',
|
||||
defaultMessage: 'Error',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'mobile.link.error.text',
|
||||
defaultMessage: 'Unable to open the link.',
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
tryOpenURL(url, onError);
|
||||
}, []);
|
||||
|
||||
const handleAboutTeam = useCallback(preventDoubleTap(() => {
|
||||
return openURL(Config.AboutTeamURL);
|
||||
}), []);
|
||||
|
||||
const handleAboutEnterprise = useCallback(preventDoubleTap(() => {
|
||||
return openURL(Config.AboutEnterpriseURL);
|
||||
}), []);
|
||||
|
||||
const handlePlatformNotice = useCallback(preventDoubleTap(() => {
|
||||
return openURL(Config.PlatformNoticeURL);
|
||||
}), []);
|
||||
|
||||
const handleMobileNotice = useCallback(preventDoubleTap(() => {
|
||||
return openURL(Config.MobileNoticeURL);
|
||||
}), []);
|
||||
|
||||
const handleTermsOfService = useCallback(preventDoubleTap(() => {
|
||||
return openURL(AboutLinks.TERMS_OF_SERVICE);
|
||||
}), []);
|
||||
|
||||
const handlePrivacyPolicy = useCallback(preventDoubleTap(() => {
|
||||
return openURL(AboutLinks.PRIVACY_POLICY);
|
||||
}), []);
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
edges={['left', 'right']}
|
||||
style={style.container}
|
||||
testID='about.screen'
|
||||
>
|
||||
<StatusBar theme={theme}/>
|
||||
<ScrollView
|
||||
style={style.scrollView}
|
||||
contentContainerStyle={style.scrollViewContent}
|
||||
testID='about.scroll_view'
|
||||
>
|
||||
<View style={style.logoContainer}>
|
||||
<CompassIcon
|
||||
name='mattermost'
|
||||
color={theme.centerChannelColor}
|
||||
size={120}
|
||||
testID='about.logo'
|
||||
/>
|
||||
</View>
|
||||
<View style={style.infoContainer}>
|
||||
<View style={style.titleContainer}>
|
||||
<Text
|
||||
style={style.title}
|
||||
testID='about.site_name'
|
||||
>
|
||||
{`${config.value.SiteName} `}
|
||||
</Text>
|
||||
<Title
|
||||
config={config}
|
||||
license={license}
|
||||
/>
|
||||
</View>
|
||||
<Subtitle config={config}/>
|
||||
<AppVersion
|
||||
isWrapped={false}
|
||||
textStyle={style.info}
|
||||
/>
|
||||
<ServerVersion config={config}/>
|
||||
<FormattedText
|
||||
id={t('mobile.about.database')}
|
||||
defaultMessage='Database: {type}'
|
||||
style={style.info}
|
||||
values={{
|
||||
type: config.value.SQLDriverName,
|
||||
}}
|
||||
testID='about.database'
|
||||
/>
|
||||
{license.value.IsLicensed === 'true' && (
|
||||
<View style={style.licenseContainer}>
|
||||
<FormattedText
|
||||
id={t('mobile.about.licensed')}
|
||||
defaultMessage='Licensed to: {company}'
|
||||
style={style.info}
|
||||
values={{
|
||||
company: license.value.Company,
|
||||
}}
|
||||
testID='about.licensee'
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
<LearnMore
|
||||
config={config}
|
||||
onHandleAboutEnterprise={handleAboutEnterprise}
|
||||
onHandleAboutTeam={handleAboutTeam}
|
||||
/>
|
||||
{!MATTERMOST_BUNDLE_IDS.includes(DeviceInfo.getBundleId()) &&
|
||||
<FormattedText
|
||||
id={t('mobile.about.powered_by')}
|
||||
defaultMessage='{site} is powered by Mattermost'
|
||||
style={style.footerText}
|
||||
values={{
|
||||
site: config.value.SiteName,
|
||||
}}
|
||||
testID='about.powered_by'
|
||||
/>
|
||||
}
|
||||
<FormattedText
|
||||
id={t('mobile.about.copyright')}
|
||||
defaultMessage='Copyright 2015-{currentYear} Mattermost, Inc. All rights reserved'
|
||||
style={[style.footerText, style.copyrightText]}
|
||||
values={{
|
||||
currentYear: new Date().getFullYear(),
|
||||
}}
|
||||
testID='about.copyright'
|
||||
/>
|
||||
<View style={style.tosPrivacyContainer}>
|
||||
<TosPrivacyContainer
|
||||
config={config}
|
||||
onPressTOS={handleTermsOfService}
|
||||
onPressPrivacyPolicy={handlePrivacyPolicy}
|
||||
/>
|
||||
</View>
|
||||
<View style={style.noticeContainer}>
|
||||
<View style={style.footerGroup}>
|
||||
<FormattedText
|
||||
id={t('mobile.notice_text')}
|
||||
defaultMessage='Mattermost is made possible by the open source software used in our {platform} and {mobile}.'
|
||||
style={style.footerText}
|
||||
values={{
|
||||
platform: (
|
||||
<FormattedText
|
||||
id={t('mobile.notice_platform_link')}
|
||||
defaultMessage='server'
|
||||
style={style.noticeLink}
|
||||
onPress={handlePlatformNotice}
|
||||
/>
|
||||
),
|
||||
mobile: (
|
||||
<FormattedText
|
||||
id={t('mobile.notice_mobile_link')}
|
||||
defaultMessage='mobile apps'
|
||||
style={[style.noticeLink, {marginLeft: 5}]}
|
||||
onPress={handleMobileNotice}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
testID='about.notice_text'
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={style.hashContainer}>
|
||||
<View style={style.footerGroup}>
|
||||
<FormattedText
|
||||
id={t('about.hash')}
|
||||
defaultMessage='Build Hash:'
|
||||
style={style.footerTitleText}
|
||||
testID='about.build_hash.title'
|
||||
/>
|
||||
<Text
|
||||
style={style.footerText}
|
||||
testID='about.build_hash.value'
|
||||
>
|
||||
{config.value.BuildHash}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={style.footerGroup}>
|
||||
<FormattedText
|
||||
id={t('about.hashee')}
|
||||
defaultMessage='EE Build Hash:'
|
||||
style={style.footerTitleText}
|
||||
testID='about.build_hash_enterprise.title'
|
||||
/>
|
||||
<Text
|
||||
style={style.footerText}
|
||||
testID='about.build_hash_enterprise.value'
|
||||
>
|
||||
{config.value.BuildHashEnterprise}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={style.footerGroup}>
|
||||
<FormattedText
|
||||
id={t('about.date')}
|
||||
defaultMessage='Build Date:'
|
||||
style={style.footerTitleText}
|
||||
testID='about.build_date.title'
|
||||
/>
|
||||
<Text
|
||||
style={style.footerText}
|
||||
testID='about.build_date.value'
|
||||
>
|
||||
{config.value.BuildDate}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.06),
|
||||
},
|
||||
scrollViewContent: {
|
||||
paddingBottom: 30,
|
||||
},
|
||||
logoContainer: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
height: 200,
|
||||
paddingVertical: 40,
|
||||
},
|
||||
infoContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
paddingHorizontal: 20,
|
||||
},
|
||||
titleContainer: {
|
||||
flex: 1,
|
||||
marginBottom: 20,
|
||||
},
|
||||
title: {
|
||||
fontSize: 22,
|
||||
color: theme.centerChannelColor,
|
||||
},
|
||||
subtitle: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 19,
|
||||
marginBottom: 15,
|
||||
},
|
||||
info: {
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 16,
|
||||
lineHeight: 19,
|
||||
},
|
||||
licenseContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginTop: 20,
|
||||
},
|
||||
noticeContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
},
|
||||
noticeLink: {
|
||||
color: theme.linkColor,
|
||||
fontSize: 11,
|
||||
lineHeight: 13,
|
||||
},
|
||||
hashContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
},
|
||||
footerGroup: {
|
||||
flex: 1,
|
||||
},
|
||||
footerTitleText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 11,
|
||||
fontWeight: '600',
|
||||
lineHeight: 13,
|
||||
},
|
||||
footerText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 11,
|
||||
lineHeight: 13,
|
||||
marginBottom: 10,
|
||||
},
|
||||
copyrightText: {
|
||||
marginBottom: 0,
|
||||
},
|
||||
tosPrivacyContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginBottom: 10,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default withDatabase(withObservables([], ({database}: WithDatabaseArgs) => ({
|
||||
config: database.collections.get(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CONFIG),
|
||||
license: database.collections.get(MM_TABLES.SERVER.SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.LICENSE),
|
||||
}))(ConnectedAbout));
|
||||
|
||||
75
app/screens/about/learn_more.tsx
Normal file
75
app/screens/about/learn_more.tsx
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Text, TouchableOpacity, View} from 'react-native';
|
||||
|
||||
import Config from '@assets/config.json';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {t} from '@i18n';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
|
||||
type LearnMoreProps = {
|
||||
config: SystemModel;
|
||||
onHandleAboutEnterprise: () => void;
|
||||
onHandleAboutTeam: () => void;
|
||||
};
|
||||
|
||||
const LearnMore = ({config, onHandleAboutEnterprise, onHandleAboutTeam}: LearnMoreProps) => {
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
let id = t('about.teamEditionLearn');
|
||||
let defaultMessage = 'Join the Mattermost community at ';
|
||||
let onPress = onHandleAboutTeam;
|
||||
let url = Config.TeamEditionLearnURL;
|
||||
|
||||
if (config.value?.BuildEnterpriseReady === 'true') {
|
||||
id = t('about.enterpriseEditionLearn');
|
||||
defaultMessage = 'Learn more about Enterprise Edition at ';
|
||||
onPress = onHandleAboutEnterprise;
|
||||
url = Config.EELearnURL;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={style.learnContainer}>
|
||||
<FormattedText
|
||||
id={id}
|
||||
defaultMessage={defaultMessage}
|
||||
style={style.learn}
|
||||
testID='about.learn_more'
|
||||
/>
|
||||
<TouchableOpacity onPress={onPress}>
|
||||
<Text
|
||||
style={style.learnLink}
|
||||
testID='about.learn_more.url'
|
||||
>
|
||||
{url}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
learnContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
marginVertical: 20,
|
||||
},
|
||||
learn: {
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 16,
|
||||
},
|
||||
learnLink: {
|
||||
color: theme.linkColor,
|
||||
fontSize: 16,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default LearnMore;
|
||||
59
app/screens/about/server_version.tsx
Normal file
59
app/screens/about/server_version.tsx
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {t} from '@i18n';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
|
||||
type ServerVersionProps = {
|
||||
config: SystemModel;
|
||||
}
|
||||
|
||||
const ServerVersion = ({config}: ServerVersionProps) => {
|
||||
const buildNumber = config.value.BuildNumber;
|
||||
const version = config.value.Version;
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
let id = t('mobile.about.serverVersion');
|
||||
let defaultMessage = 'Server Version: {version} (Build {number})';
|
||||
let values = {
|
||||
version,
|
||||
number: buildNumber,
|
||||
};
|
||||
|
||||
if (buildNumber === version) {
|
||||
id = t('mobile.about.serverVersionNoBuild');
|
||||
defaultMessage = 'Server Version: {version}';
|
||||
values = {
|
||||
version,
|
||||
number: undefined,
|
||||
};
|
||||
}
|
||||
return (
|
||||
<FormattedText
|
||||
id={id}
|
||||
defaultMessage={defaultMessage}
|
||||
style={style.info}
|
||||
values={values}
|
||||
testID='about.server_version'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
info: {
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 16,
|
||||
lineHeight: 19,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default ServerVersion;
|
||||
49
app/screens/about/subtitle.tsx
Normal file
49
app/screens/about/subtitle.tsx
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {t} from '@i18n';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
|
||||
type SubtitleProps = {
|
||||
config: SystemModel;
|
||||
}
|
||||
|
||||
const Subtitle = ({config}: SubtitleProps) => {
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
let id = t('about.teamEditionSt');
|
||||
let defaultMessage = 'All your team communication in one place, instantly searchable and accessible anywhere.';
|
||||
|
||||
if (config.value.BuildEnterpriseReady === 'true') {
|
||||
id = t('about.enterpriseEditionSt');
|
||||
defaultMessage = 'Modern communication from behind your firewall.';
|
||||
}
|
||||
|
||||
return (
|
||||
<FormattedText
|
||||
id={id}
|
||||
defaultMessage={defaultMessage}
|
||||
style={style.subtitle}
|
||||
testID='about.subtitle'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
subtitle: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 19,
|
||||
marginBottom: 15,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default Subtitle;
|
||||
53
app/screens/about/title.tsx
Normal file
53
app/screens/about/title.tsx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import React from 'react';
|
||||
|
||||
import {useTheme} from '@context/theme';
|
||||
import {t} from '@i18n';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
|
||||
type TitleProps = {
|
||||
config: SystemModel;
|
||||
license: SystemModel;
|
||||
}
|
||||
|
||||
const Title = ({config, license}: TitleProps) => {
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
let id = t('about.teamEditiont0');
|
||||
let defaultMessage = 'Team Edition';
|
||||
|
||||
if (config.value.BuildEnterpriseReady === 'true') {
|
||||
id = t('about.teamEditiont1');
|
||||
defaultMessage = 'Enterprise Edition';
|
||||
|
||||
if (license.value.IsLicensed === 'true') {
|
||||
id = t('about.enterpriseEditione1');
|
||||
defaultMessage = 'Enterprise Edition';
|
||||
}
|
||||
}
|
||||
return (
|
||||
<FormattedText
|
||||
id={id}
|
||||
defaultMessage={defaultMessage}
|
||||
style={style.title}
|
||||
testID='about.title'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
title: {
|
||||
fontSize: 22,
|
||||
color: theme.centerChannelColor,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default Title;
|
||||
73
app/screens/about/tos_privacy.tsx
Normal file
73
app/screens/about/tos_privacy.tsx
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Text} from 'react-native';
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {t} from '@i18n';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
|
||||
type TosPrivacyContainerProps = {
|
||||
config: SystemModel;
|
||||
onPressTOS: () => void;
|
||||
onPressPrivacyPolicy: () => void;
|
||||
}
|
||||
|
||||
const TosPrivacyContainer = ({config, onPressTOS, onPressPrivacyPolicy}: TosPrivacyContainerProps) => {
|
||||
const hasTermsOfServiceLink = config.value?.TermsOfServiceLink;
|
||||
const hasPrivacyPolicyLink = config.value?.PrivacyPolicyLink;
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
return (
|
||||
<>
|
||||
{hasTermsOfServiceLink && (
|
||||
<FormattedText
|
||||
id={t('mobile.tos_link')}
|
||||
defaultMessage='Terms of Service'
|
||||
style={style.noticeLink}
|
||||
onPress={onPressTOS}
|
||||
testID='about.terms_of_service'
|
||||
/>
|
||||
)}
|
||||
{hasTermsOfServiceLink && hasPrivacyPolicyLink && (
|
||||
<Text style={[style.footerText, style.hyphenText]}>
|
||||
{' - '}
|
||||
</Text>
|
||||
)}
|
||||
{hasPrivacyPolicyLink && (
|
||||
<FormattedText
|
||||
id={t('mobile.privacy_link')}
|
||||
defaultMessage='Privacy Policy'
|
||||
style={style.noticeLink}
|
||||
onPress={onPressPrivacyPolicy}
|
||||
testID='about.privacy_policy'
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
noticeLink: {
|
||||
color: theme.linkColor,
|
||||
fontSize: 11,
|
||||
lineHeight: 13,
|
||||
},
|
||||
footerText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 11,
|
||||
lineHeight: 13,
|
||||
marginBottom: 10,
|
||||
},
|
||||
hyphenText: {
|
||||
marginBottom: 0,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default TosPrivacyContainer;
|
||||
|
|
@ -6,7 +6,7 @@ import {View} from 'react-native';
|
|||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {General} from '@constants';
|
||||
import {t} from '@utils/i18n';
|
||||
import {t} from '@i18n';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
type ChannelGuestLabelProps = {
|
||||
|
|
|
|||
|
|
@ -3,32 +3,32 @@
|
|||
|
||||
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import {goToScreen} from '@screens/navigation';
|
||||
import React, {useMemo, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Text, View, ScrollView} from 'react-native';
|
||||
import {SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import {logout} from '@actions/remote/session';
|
||||
import Markdown from '@components/markdown';
|
||||
import JumboEmoji from '@components/jumbo_emoji';
|
||||
import ProgressiveImage from '@components/progressive_image';
|
||||
import ServerVersion from '@components/server_version';
|
||||
import StatusBar from '@components/status_bar';
|
||||
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
|
||||
import {Screens, Database} from '@constants';
|
||||
import {useServerUrl} from '@context/server_url';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {getMarkdownBlockStyles, getMarkdownTextStyles} from '@utils/markdown';
|
||||
|
||||
import ChannelNavBar from './channel_nav_bar';
|
||||
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
import type {LaunchProps} from '@typings/launch';
|
||||
import type {WithDatabaseArgs} from '@typings/database/database';
|
||||
|
||||
import FailedChannels from './failed_channels';
|
||||
import FailedTeams from './failed_teams';
|
||||
|
||||
import Markdown from '@components/markdown';
|
||||
import {getMarkdownBlockStyles, getMarkdownTextStyles} from '@utils/markdown';
|
||||
import md from './md.json';
|
||||
import ProgressiveImage from '@components/progressive_image';
|
||||
import JumboEmoji from '@components/jumbo_emoji';
|
||||
|
||||
import type {WithDatabaseArgs} from '@typings/database/database';
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
import type {LaunchProps} from '@typings/launch';
|
||||
|
||||
type ChannelProps = WithDatabaseArgs & LaunchProps & {
|
||||
currentChannelId: SystemModel;
|
||||
|
|
@ -36,6 +36,7 @@ type ChannelProps = WithDatabaseArgs & LaunchProps & {
|
|||
time?: number;
|
||||
};
|
||||
|
||||
const {MM_TABLES, SYSTEM_IDENTIFIERS} = Database;
|
||||
const {SERVER: {SYSTEM}} = MM_TABLES;
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
|
|
@ -69,6 +70,7 @@ const Channel = ({currentChannelId, currentTeamId, time}: ChannelProps) => {
|
|||
//todo: https://mattermost.atlassian.net/browse/MM-37266
|
||||
|
||||
const theme = useTheme();
|
||||
const intl = useIntl();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
const serverUrl = useServerUrl();
|
||||
|
|
@ -77,6 +79,11 @@ const Channel = ({currentChannelId, currentTeamId, time}: ChannelProps) => {
|
|||
logout(serverUrl!);
|
||||
};
|
||||
|
||||
const goToAbout = () => {
|
||||
const title = intl.formatMessage({id: 'about.title', defaultMessage: 'About {appTitle}'}, {appTitle: 'Mattermost'});
|
||||
goToScreen(Screens.ABOUT, title);
|
||||
};
|
||||
|
||||
const renderComponent = useMemo(() => {
|
||||
if (!currentTeamId.value) {
|
||||
return <FailedTeams/>;
|
||||
|
|
@ -140,6 +147,14 @@ const Channel = ({currentChannelId, currentTeamId, time}: ChannelProps) => {
|
|||
{`Loaded in: ${time || 0}ms. Logout from ${serverUrl}`}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text
|
||||
onPress={goToAbout}
|
||||
style={styles.sectionTitle}
|
||||
>
|
||||
{'Go to About Screen'}
|
||||
</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</>
|
||||
);
|
||||
|
|
@ -147,8 +162,9 @@ const Channel = ({currentChannelId, currentTeamId, time}: ChannelProps) => {
|
|||
|
||||
const [inViewport, setInViewport] = useState(false);
|
||||
|
||||
setTimeout(async () => {
|
||||
const viewPortTimer = setTimeout(async () => {
|
||||
setInViewport(true);
|
||||
clearTimeout(viewPortTimer);
|
||||
}, 3000);
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@ Navigation.setLazyComponentRegistrator((screenName) => {
|
|||
let screen: any|undefined;
|
||||
let extraStyles: StyleProp<ViewStyle>;
|
||||
switch (screenName) {
|
||||
// case 'About':
|
||||
// screen = require('@screens/about').default;
|
||||
// break;
|
||||
case 'About':
|
||||
screen = withServerDatabase(require('@screens/about').default);
|
||||
break;
|
||||
// case 'AddReaction':
|
||||
// screen = require('@screens/add_reaction').default;
|
||||
// break;
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ import {FORGOT_PASSWORD, MFA} from '@constants/screens';
|
|||
import FormattedText from '@components/formatted_text';
|
||||
import {useManagedConfig} from '@mattermost/react-native-emm';
|
||||
import {login} from '@actions/remote/session';
|
||||
import {t} from '@i18n';
|
||||
import {goToScreen, resetToChannel} from '@screens/navigation';
|
||||
import {t} from '@utils/i18n';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import {SafeAreaView} from 'react-native-safe-area-context';
|
|||
import ErrorText from '@components/error_text';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {login} from '@actions/remote/session';
|
||||
import {t} from '@utils/i18n';
|
||||
import {t} from '@i18n';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {Alert, AlertButton} from 'react-native';
|
|||
|
||||
import type {IntlShape} from 'react-intl';
|
||||
|
||||
import {t} from '@utils/i18n';
|
||||
import {t} from '@i18n';
|
||||
|
||||
export function errorBadChannel(intl: IntlShape) {
|
||||
const message = {
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export function t(v: string) {
|
||||
return v;
|
||||
}
|
||||
|
|
@ -1,4 +1,15 @@
|
|||
{
|
||||
"about.date": "Build Date:",
|
||||
"about.enterpriseEditione1": "Enterprise Edition",
|
||||
"about.enterpriseEditionLearn": "Learn more about Enterprise Edition at ",
|
||||
"about.enterpriseEditionSt": "Modern communication from behind your firewall.",
|
||||
"about.hash": "Build Hash:",
|
||||
"about.hashee": "EE Build Hash:",
|
||||
"about.teamEditionLearn": "Join the Mattermost community at ",
|
||||
"about.teamEditionSt": "All your team communication in one place, instantly searchable and accessible anywhere.",
|
||||
"about.teamEditiont0": "Team Edition",
|
||||
"about.teamEditiont1": "Enterprise Edition",
|
||||
"about.title": "About {appTitle}",
|
||||
"channel_header.directchannel.you": "{displayname} (you)",
|
||||
"channel_loader.someone": "Someone",
|
||||
"channel.channelHasGuests": "This channel has guests",
|
||||
|
|
@ -48,6 +59,12 @@
|
|||
"login.username": "Username",
|
||||
"login.userNotFound": "We couldn't find an account matching your login credentials.",
|
||||
"mobile.about.appVersion": "App Version: {version} (Build {number})",
|
||||
"mobile.about.copyright": "Copyright 2015-{currentYear} Mattermost, Inc. All rights reserved",
|
||||
"mobile.about.database": "Database: {type}",
|
||||
"mobile.about.licensed": "Licensed to: {company}",
|
||||
"mobile.about.powered_by": "{site} is powered by Mattermost",
|
||||
"mobile.about.serverVersion": "Server Version: {version} (Build {number})",
|
||||
"mobile.about.serverVersionNoBuild": "Server Version: {version}",
|
||||
"mobile.components.select_server_view.connect": "Connect",
|
||||
"mobile.components.select_server_view.connecting": "Connecting...",
|
||||
"mobile.components.select_server_view.enterServerUrl": "Enter Server URL",
|
||||
|
|
@ -74,6 +91,9 @@
|
|||
"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",
|
||||
"mobile.notice_mobile_link": "mobile apps",
|
||||
"mobile.notice_platform_link": "server",
|
||||
"mobile.notice_text": "Mattermost is made possible by the open source software used in our {platform} and {mobile}.",
|
||||
"mobile.oauth.failed_to_login": "Your login attempt failed. Please try again.",
|
||||
"mobile.oauth.failed_to_open_link": "The link failed to open. Please try again.",
|
||||
"mobile.oauth.failed_to_open_link_no_browser": "The link failed to open. Please verify if a browser is installed in the current space.",
|
||||
|
|
@ -82,6 +102,7 @@
|
|||
"mobile.oauth.switch_to_browser": "Please use your browser to complete the login",
|
||||
"mobile.oauth.try_again": "Try again",
|
||||
"mobile.post.cancel": "Cancel",
|
||||
"mobile.privacy_link": "Privacy Policy",
|
||||
"mobile.push_notification_reply.button": "Send",
|
||||
"mobile.push_notification_reply.placeholder": "Write a reply...",
|
||||
"mobile.push_notification_reply.title": "Reply",
|
||||
|
|
@ -107,6 +128,7 @@
|
|||
"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": "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.tos_link": "Terms of Service",
|
||||
"mobile.unsupported_server.message": "Attachments, link previews, reactions and embed data may not be displayed correctly. If this issue persists contact your System Administrator to upgrade your Mattermost server.",
|
||||
"mobile.unsupported_server.ok": "OK",
|
||||
"mobile.unsupported_server.title": "Unsupported server version",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ module.exports = {
|
|||
alias: {
|
||||
'@actions': './app/actions',
|
||||
'@app': './app/',
|
||||
'@assets': './dist/assets',
|
||||
'@assets': './dist/assets/',
|
||||
'@client': './app/client',
|
||||
'@components': './app/components',
|
||||
'@constants': './app/constants',
|
||||
|
|
|
|||
|
|
@ -710,7 +710,7 @@ SPEC CHECKSUMS:
|
|||
EXFileSystem: 0a04aba8da751b9ac954065911bcf166503f8267
|
||||
ExpoModulesCore: 2734852616127a6c1fc23012197890a6f3763dc7
|
||||
FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b
|
||||
FBReactNativeSpec: cef0cc6d50abc92e8cf52f140aa22b5371cfec0b
|
||||
FBReactNativeSpec: d35931295aacfe996e833c01a3701d4aa7a80cb4
|
||||
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
|
||||
jail-monkey: 07b83767601a373db876e939b8dbf3f5eb15f073
|
||||
libwebp: e90b9c01d99205d03b6bb8f2c8c415e5a4ef66f0
|
||||
|
|
|
|||
Loading…
Reference in a new issue