Feat: add copy to clipboard button in "about" mattermost page (#7134)
* feat: add copy to clip board button in about page * add intl format text * make suggested changes. - fix: wrap copyToClipBoard function in useCallBack - remove annonymous function onPress, provide function pointer - make code readable in copyToClipBoard function * formatting * small fix * change copy to clipboard position - created a custom button eith icon and text - usd button theme color * button styling * divider color * use predefined btn element * Add e2e test for copy info button * feat: refactor the styles for thin lines - fix: change touchable opacity to view - add margin top to footer text * change icon size to 15 * remove unnecessary view * add config to dependency of callback * suggeste changes on onClick func * modified en.json file after running i18-extract * Improve translations * Address feedback * Fix non updated default messages --------- Co-authored-by: Daniel Espino García <larkox@gmail.com>
This commit is contained in:
parent
871e3964ea
commit
37b245d461
4 changed files with 73 additions and 37 deletions
|
|
@ -1,21 +1,23 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import React, {useCallback, useMemo} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Alert, Text, View} from 'react-native';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
|
||||
import Config from '@assets/config.json';
|
||||
import Button from '@components/button';
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import SettingContainer from '@components/settings/container';
|
||||
import SettingSeparator from '@components/settings/separator';
|
||||
import AboutLinks from '@constants/about_links';
|
||||
import {useTheme} from '@context/theme';
|
||||
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
|
||||
import {t} from '@i18n';
|
||||
import {popTopScreen} from '@screens/navigation';
|
||||
import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
|
@ -80,7 +82,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
footerText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.64),
|
||||
...typography('Body', 50),
|
||||
marginBottom: 10,
|
||||
marginVertical: 10,
|
||||
},
|
||||
copyrightText: {
|
||||
marginBottom: 0,
|
||||
|
|
@ -92,6 +94,17 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
group: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
copyInfoButtonContainer: {
|
||||
width: 120,
|
||||
marginTop: 10,
|
||||
position: 'relative',
|
||||
},
|
||||
thinLine: {
|
||||
height: 0.2,
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.2),
|
||||
alignSelf: 'stretch',
|
||||
marginVertical: 20,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -146,31 +159,31 @@ const About = ({componentId, config, license}: AboutProps) => {
|
|||
const buildNumber = config.BuildNumber;
|
||||
const version = config.Version;
|
||||
|
||||
let id = t('settings.about.server.version.value');
|
||||
let defaultMessage = '{version} (Build {number})';
|
||||
let values: {version: string; number?: string} = {
|
||||
version,
|
||||
number: buildNumber,
|
||||
};
|
||||
|
||||
if (buildNumber === version) {
|
||||
id = t('settings.about.serverVersionNoBuild');
|
||||
defaultMessage = '{version}';
|
||||
values = {
|
||||
version,
|
||||
number: undefined,
|
||||
};
|
||||
return version;
|
||||
}
|
||||
|
||||
return {
|
||||
id, defaultMessage, values,
|
||||
};
|
||||
}, [config]);
|
||||
return intl.formatMessage({id: 'settings.about.server.version.value', defaultMessage: '{version} (Build {buildNumber})'}, {version, buildNumber});
|
||||
}, [config, intl]);
|
||||
|
||||
useAndroidHardwareBackHandler(componentId, () => {
|
||||
popTopScreen(componentId);
|
||||
});
|
||||
|
||||
const copyToClipboard = useCallback(
|
||||
() => {
|
||||
const appVersion = intl.formatMessage({id: 'settings.about.app.version', defaultMessage: 'App Version: {version} (Build {number})'}, {version: DeviceInfo.getVersion(), number: DeviceInfo.getBuildNumber()});
|
||||
const buildNumber = config.BuildNumber;
|
||||
const version = config.Version;
|
||||
const server = buildNumber === version ? intl.formatMessage({id: 'settings.about.server.version.noBuild', defaultMessage: 'Server Version: {version}'}, {version}) : intl.formatMessage({id: 'settings.about.server.version', defaultMessage: 'Server Version: {version} (Build {buildNumber})'}, {version, buildNumber});
|
||||
const database = intl.formatMessage({id: 'settings.about.database', defaultMessage: 'Database: {driverName}'}, {driverName: config.SQLDriverName});
|
||||
const databaseSchemaVersion = intl.formatMessage({id: 'settings.about.database.schema', defaultMessage: 'Database Schema Version: {version}'}, {version: config.SchemaVersion});
|
||||
const copiedString = `${appVersion}\n${server}\n${database}\n${databaseSchemaVersion}`;
|
||||
Clipboard.setString(copiedString);
|
||||
},
|
||||
[intl, config],
|
||||
);
|
||||
|
||||
return (
|
||||
<SettingContainer testID='about'>
|
||||
<View style={styles.logoContainer}>
|
||||
|
|
@ -185,21 +198,24 @@ const About = ({componentId, config, license}: AboutProps) => {
|
|||
license={license}
|
||||
/>
|
||||
<Subtitle config={config}/>
|
||||
<SettingSeparator lineStyles={styles.lineStyles}/>
|
||||
<View
|
||||
style={styles.thinLine}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.infoContainer}>
|
||||
<View style={styles.group}>
|
||||
<Text
|
||||
style={styles.leftHeading}
|
||||
testID='about.app_version.title'
|
||||
>
|
||||
{intl.formatMessage({id: 'settings.about.version', defaultMessage: 'App Version:'})}
|
||||
{intl.formatMessage({id: 'settings.about.app.version.title', defaultMessage: 'App Version:'})}
|
||||
</Text>
|
||||
<Text
|
||||
style={styles.rightHeading}
|
||||
testID='about.app_version.value'
|
||||
>
|
||||
{intl.formatMessage({id: 'settings.about.build', defaultMessage: '{version} (Build {number})'},
|
||||
{intl.formatMessage({id: 'settings.about.app.version.value', defaultMessage: '{version} (Build {number})'},
|
||||
{version: DeviceInfo.getVersion(), number: DeviceInfo.getBuildNumber()})}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
@ -208,13 +224,13 @@ const About = ({componentId, config, license}: AboutProps) => {
|
|||
style={styles.leftHeading}
|
||||
testID='about.server_version.title'
|
||||
>
|
||||
{intl.formatMessage({id: 'settings.about.server.version.desc', defaultMessage: 'Server Version:'})}
|
||||
{intl.formatMessage({id: 'settings.about.server.version.title', defaultMessage: 'Server Version:'})}
|
||||
</Text>
|
||||
<Text
|
||||
style={styles.rightHeading}
|
||||
testID='about.server_version.value'
|
||||
>
|
||||
{intl.formatMessage({id: serverVersion.id, defaultMessage: serverVersion.defaultMessage}, serverVersion.values)}
|
||||
{serverVersion}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.group}>
|
||||
|
|
@ -222,13 +238,13 @@ const About = ({componentId, config, license}: AboutProps) => {
|
|||
style={styles.leftHeading}
|
||||
testID='about.database.title'
|
||||
>
|
||||
{intl.formatMessage({id: 'settings.about.database', defaultMessage: 'Database:'})}
|
||||
{intl.formatMessage({id: 'settings.about.database.title', defaultMessage: 'Database:'})}
|
||||
</Text>
|
||||
<Text
|
||||
style={styles.rightHeading}
|
||||
testID='about.database.value'
|
||||
>
|
||||
{intl.formatMessage({id: 'settings.about.database.value', defaultMessage: `${config.SQLDriverName}`})}
|
||||
{config.SQLDriverName}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.group}>
|
||||
|
|
@ -236,18 +252,26 @@ const About = ({componentId, config, license}: AboutProps) => {
|
|||
style={styles.leftHeading}
|
||||
testID='about.database_schema_version.title'
|
||||
>
|
||||
{intl.formatMessage({id: 'settings.about.database.schema', defaultMessage: 'Database Schema Version:'})}
|
||||
{intl.formatMessage({id: 'settings.about.database.schema.title', defaultMessage: 'Database Schema Version:'})}
|
||||
</Text>
|
||||
<Text
|
||||
style={styles.rightHeading}
|
||||
testID='about.database_schema_version.value'
|
||||
>
|
||||
{intl.formatMessage({
|
||||
id: 'settings.about.database.schema.value',
|
||||
defaultMessage: `${config.SchemaVersion}`,
|
||||
})}
|
||||
{config.SchemaVersion}
|
||||
</Text>
|
||||
</View>
|
||||
<Button
|
||||
theme={theme}
|
||||
backgroundStyle={[buttonBackgroundStyle(theme, 'm', 'tertiary'), styles.copyInfoButtonContainer]}
|
||||
onPress={copyToClipboard}
|
||||
textStyle={buttonTextStyle(theme, 'm', 'tertiary', 'default')}
|
||||
text={intl.formatMessage({id: 'settings.about.button.copyInfo', defaultMessage: 'Copy info'})}
|
||||
testID={'about.copy_info'}
|
||||
iconName='content-copy'
|
||||
iconSize={15}
|
||||
buttonType={'default'}
|
||||
/>
|
||||
{license.IsLicensed === 'true' && (
|
||||
<View style={styles.licenseContainer}>
|
||||
<FormattedText
|
||||
|
|
@ -272,6 +296,9 @@ const About = ({componentId, config, license}: AboutProps) => {
|
|||
values={{site: config.SiteName}}
|
||||
/>
|
||||
}
|
||||
<View
|
||||
style={styles.thinLine}
|
||||
/>
|
||||
<FormattedText
|
||||
defaultMessage='Copyright 2015-{currentYear} Mattermost, Inc. All rights reserved'
|
||||
id={t('settings.about.copyright')}
|
||||
|
|
|
|||
|
|
@ -928,16 +928,21 @@
|
|||
"settings_display.timezone.off": "Off",
|
||||
"settings_display.timezone.select": "Select Timezone",
|
||||
"settings.about": "About {appTitle}",
|
||||
"settings.about.build": "{version} (Build {number})",
|
||||
"settings.about.app.version": "App Version: {version} (Build {number})",
|
||||
"settings.about.app.version.title": "App Version:",
|
||||
"settings.about.app.version.value": "{version} (Build {number})",
|
||||
"settings.about.button.copyInfo": "Copy info",
|
||||
"settings.about.copyright": "Copyright 2015-{currentYear} Mattermost, Inc. All rights reserved",
|
||||
"settings.about.database": "Database:",
|
||||
"settings.about.database.schema": "Database Schema Version:",
|
||||
"settings.about.database": "Database: {driverName}",
|
||||
"settings.about.database.schema": "Database Schema Version: {version}",
|
||||
"settings.about.database.schema.title": "Database Schema Version:",
|
||||
"settings.about.database.title": "Database:",
|
||||
"settings.about.licensed": "Licensed to: {company}",
|
||||
"settings.about.powered_by": "{site} is powered by Mattermost",
|
||||
"settings.about.server.version.desc": "Server Version:",
|
||||
"settings.about.server.version": "Server Version: {version} (Build {buildNumber}",
|
||||
"settings.about.server.version.noBuild": "Server Version: {version}",
|
||||
"settings.about.server.version.title": "Server Version:",
|
||||
"settings.about.server.version.value": "{version} (Build {number})",
|
||||
"settings.about.serverVersionNoBuild": "{version}",
|
||||
"settings.about.version": "App Version:",
|
||||
"settings.advanced_settings": "Advanced Settings",
|
||||
"settings.advanced.cancel": "Cancel",
|
||||
"settings.advanced.delete": "Delete",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class AboutScreen {
|
|||
databaseValue: 'about.database.value',
|
||||
databaseSchemaVersionTitle: 'about.database_schema_version.title',
|
||||
databaseSchemaVersionValue: 'about.database_schema_version.value',
|
||||
copInfoButton: 'about.copy_info',
|
||||
licensee: 'about.licensee',
|
||||
learnMoreText: 'about.learn_more.text',
|
||||
learnMoreUrl: 'about.learn_more.url',
|
||||
|
|
@ -51,6 +52,7 @@ class AboutScreen {
|
|||
serverVersionValue = element(by.id(this.testID.serverVersionValue));
|
||||
databaseTitle = element(by.id(this.testID.databaseTitle));
|
||||
databaseValue = element(by.id(this.testID.databaseValue));
|
||||
copyInfoButton = element(by.id(this.testID.copInfoButton));
|
||||
databaseSchemaVersionTitle = element(by.id(this.testID.databaseSchemaVersionTitle));
|
||||
databaseSchemaVersionValue = element(by.id(this.testID.databaseSchemaVersionValue));
|
||||
licensee = element(by.id(this.testID.licensee));
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ describe('Account - Settings - About', () => {
|
|||
await expect(AboutScreen.databaseValue).toBeVisible();
|
||||
await expect(AboutScreen.databaseSchemaVersionTitle).toHaveText('Database Schema Version:');
|
||||
await expect(AboutScreen.databaseSchemaVersionValue).toBeVisible();
|
||||
await expect(AboutScreen.copyInfoButton).toBeVisible();
|
||||
await expect(AboutScreen.copyInfoButton).toHaveText('Copy info');
|
||||
if (isLicensed) {
|
||||
await expect(AboutScreen.licensee).toBeVisible();
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue