forked from Ivasoft/mattermost-mobile
MM-45344 Gekidou Remove <MenuItem/> (#6522)
* added MENU_ITEM_HEIGHT to constant/view * fix user presence and your profile * added MENU_ITEM_HEIGHT to constant/view * fix user presence and your profile * UI Polish - Custom Status * UI Polish - Settings * UI Polish - logout * refactored styles * removed 'throws DataOperatorException' from './database/` * fix for copy link option * fix autoresponder 1. user should be allowed to enter paragraph 2. the OOO was not immediately being updated on the notification main screen. The fix is to cal fetchStatusInBatch after the updateMe operation * About Screen - code clean up * removed MenuItem component from common_post_options * removed MenuItem from Settings * refactored show_more and recent_item * removed menu_item component * Update setting_container.tsx * PR review correction * Update setting_container.tsx * Update recent_item.tsx
This commit is contained in:
@@ -1,64 +1,38 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useMemo} from 'react';
|
||||
import React from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import MenuItem from '@components/menu_item';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
destructive: {
|
||||
color: theme.dndIndicator,
|
||||
},
|
||||
label: {
|
||||
color: theme.centerChannelColor,
|
||||
...typography('Body', 200),
|
||||
},
|
||||
iconContainerStyle: {
|
||||
marginLeft: 0,
|
||||
},
|
||||
}));
|
||||
import OptionItem from '@components/option_item';
|
||||
|
||||
type BaseOptionType = {
|
||||
i18nId: string;
|
||||
defaultMessage: string;
|
||||
i18nId: string;
|
||||
iconName: string;
|
||||
isDestructive?: boolean;
|
||||
onPress: () => void;
|
||||
testID: string;
|
||||
isDestructive?: boolean;
|
||||
}
|
||||
|
||||
const BaseOption = ({
|
||||
i18nId,
|
||||
defaultMessage,
|
||||
i18nId,
|
||||
iconName,
|
||||
isDestructive = false,
|
||||
onPress,
|
||||
testID,
|
||||
isDestructive = false,
|
||||
}: BaseOptionType) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
const label = useMemo(() => (
|
||||
<FormattedText
|
||||
id={i18nId}
|
||||
defaultMessage={defaultMessage}
|
||||
style={[styles.label, isDestructive && styles.destructive]}
|
||||
/>
|
||||
), [i18nId, defaultMessage, theme]);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
iconContainerStyle={styles.iconContainerStyle}
|
||||
iconName={iconName}
|
||||
isDestructor={isDestructive}
|
||||
labelComponent={label}
|
||||
onPress={onPress}
|
||||
separator={false}
|
||||
<OptionItem
|
||||
action={onPress}
|
||||
destructive={isDestructive}
|
||||
icon={iconName}
|
||||
label={intl.formatMessage({id: i18nId, defaultMessage})}
|
||||
testID={testID}
|
||||
type='default'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`DrawerItem should match snapshot 1`] = `
|
||||
<View
|
||||
onMoveShouldSetResponder={[Function]}
|
||||
onMoveShouldSetResponderCapture={[Function]}
|
||||
onResponderEnd={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderReject={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderStart={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onStartShouldSetResponderCapture={[Function]}
|
||||
testID="test-id"
|
||||
>
|
||||
<View
|
||||
accessible={true}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "column",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"minHeight": 50,
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"height": 50,
|
||||
"justifyContent": "center",
|
||||
"marginLeft": 5,
|
||||
"width": 45,
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
name="icon-name"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"color": "rgba(63,67,80,0.64)",
|
||||
"fontSize": 24,
|
||||
},
|
||||
Object {
|
||||
"color": "#d24b4e",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flex": 1,
|
||||
"justifyContent": "center",
|
||||
"paddingVertical": 14,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"color": "rgba(63,67,80,0.5)",
|
||||
"fontSize": 17,
|
||||
"includeFontPadding": false,
|
||||
"textAlignVertical": "center",
|
||||
},
|
||||
undefined,
|
||||
Object {
|
||||
"color": "#d24b4e",
|
||||
},
|
||||
Object {
|
||||
"textAlign": "center",
|
||||
"textAlignVertical": "center",
|
||||
},
|
||||
false,
|
||||
]
|
||||
}
|
||||
>
|
||||
default message
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "rgba(63,67,80,0.12)",
|
||||
"height": 1,
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`DrawerItem should match snapshot without separator and centered false 1`] = `
|
||||
<View
|
||||
onMoveShouldSetResponder={[Function]}
|
||||
onMoveShouldSetResponderCapture={[Function]}
|
||||
onResponderEnd={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderReject={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderStart={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onStartShouldSetResponderCapture={[Function]}
|
||||
testID="test-id"
|
||||
>
|
||||
<View
|
||||
accessible={true}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "column",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"minHeight": 50,
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"height": 50,
|
||||
"justifyContent": "center",
|
||||
"marginLeft": 5,
|
||||
"width": 45,
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
name="icon-name"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"color": "rgba(63,67,80,0.64)",
|
||||
"fontSize": 24,
|
||||
},
|
||||
Object {
|
||||
"color": "#d24b4e",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flex": 1,
|
||||
"justifyContent": "center",
|
||||
"paddingVertical": 14,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"color": "rgba(63,67,80,0.5)",
|
||||
"fontSize": 17,
|
||||
"includeFontPadding": false,
|
||||
"textAlignVertical": "center",
|
||||
},
|
||||
undefined,
|
||||
Object {
|
||||
"color": "#d24b4e",
|
||||
},
|
||||
Object {},
|
||||
false,
|
||||
]
|
||||
}
|
||||
>
|
||||
default message
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
`;
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {Preferences} from '@constants';
|
||||
import {renderWithIntl} from '@test/intl-test-helper';
|
||||
|
||||
import MenuItem from '.';
|
||||
|
||||
describe('DrawerItem', () => {
|
||||
const baseProps = {
|
||||
onPress: () => null,
|
||||
testID: 'test-id',
|
||||
centered: true,
|
||||
defaultMessage: 'default message',
|
||||
i18nId: 'i18-id',
|
||||
iconName: 'icon-name',
|
||||
isDestructor: true,
|
||||
separator: true,
|
||||
theme: Preferences.THEMES.denim,
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = renderWithIntl(<MenuItem {...baseProps}/>);
|
||||
|
||||
expect(wrapper.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot without separator and centered false', () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
centered: false,
|
||||
separator: false,
|
||||
};
|
||||
const wrapper = renderWithIntl(
|
||||
<MenuItem {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -1,173 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {ReactNode} from 'react';
|
||||
import {Platform, StyleProp, TextStyle, View, ViewStyle} from 'react-native';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import TouchableWithFeedback from '@components/touchable_with_feedback';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
export const ITEM_HEIGHT = 50;
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
minHeight: ITEM_HEIGHT,
|
||||
},
|
||||
iconContainer: {
|
||||
width: 45,
|
||||
height: ITEM_HEIGHT,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginLeft: 5,
|
||||
},
|
||||
icon: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.64),
|
||||
fontSize: 24,
|
||||
},
|
||||
labelContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
paddingVertical: 14,
|
||||
},
|
||||
centerLabel: {
|
||||
textAlign: 'center',
|
||||
textAlignVertical: 'center',
|
||||
},
|
||||
label: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 17,
|
||||
textAlignVertical: 'center',
|
||||
includeFontPadding: false,
|
||||
},
|
||||
divider: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.12),
|
||||
height: 1,
|
||||
},
|
||||
chevron: {
|
||||
alignSelf: 'center',
|
||||
color: changeOpacity(theme.centerChannelColor, 0.64),
|
||||
fontSize: 24,
|
||||
marginRight: 8,
|
||||
},
|
||||
linkContainer: {
|
||||
marginHorizontal: 15,
|
||||
color: theme.linkColor,
|
||||
},
|
||||
mainContainer: {
|
||||
flexDirection: 'column',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export type MenuItemProps = {
|
||||
centered?: boolean;
|
||||
chevronStyle?: StyleProp<ViewStyle>;
|
||||
containerStyle?: StyleProp<ViewStyle>;
|
||||
defaultMessage?: string;
|
||||
i18nId?: string;
|
||||
iconContainerStyle?: StyleProp<ViewStyle>;
|
||||
iconName?: string;
|
||||
isDestructor?: boolean;
|
||||
isLink?: boolean;
|
||||
labelComponent?: ReactNode;
|
||||
labelStyle?: StyleProp<TextStyle>;
|
||||
leftComponent?: ReactNode;
|
||||
messageValues?: Record<string, any>;
|
||||
onPress: () => void;
|
||||
rightComponent?: ReactNode;
|
||||
separator?: boolean;
|
||||
separatorStyle?: StyleProp<ViewStyle>;
|
||||
showArrow?: boolean;
|
||||
testID: string;
|
||||
};
|
||||
const MenuItem = ({
|
||||
centered,
|
||||
chevronStyle,
|
||||
containerStyle,
|
||||
defaultMessage = '',
|
||||
i18nId,
|
||||
iconContainerStyle,
|
||||
iconName,
|
||||
isDestructor = false,
|
||||
isLink = false,
|
||||
labelComponent,
|
||||
labelStyle,
|
||||
leftComponent,
|
||||
messageValues,
|
||||
onPress,
|
||||
rightComponent,
|
||||
separator = true,
|
||||
separatorStyle,
|
||||
showArrow = false,
|
||||
testID,
|
||||
}: MenuItemProps) => {
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
let icon;
|
||||
if (leftComponent) {
|
||||
icon = leftComponent;
|
||||
} else if (iconName) {
|
||||
icon = (
|
||||
<CompassIcon
|
||||
name={iconName}
|
||||
style={[style.icon, isDestructor && {color: theme.errorTextColor}]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
let label;
|
||||
if (labelComponent) {
|
||||
label = labelComponent;
|
||||
} else if (i18nId) {
|
||||
label = (
|
||||
<FormattedText
|
||||
id={i18nId}
|
||||
defaultMessage={defaultMessage}
|
||||
style={[
|
||||
style.label,
|
||||
labelStyle,
|
||||
isDestructor && {color: theme.errorTextColor},
|
||||
centered ? style.centerLabel : {},
|
||||
isLink && style.linkContainer,
|
||||
]}
|
||||
values={messageValues}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableWithFeedback
|
||||
testID={testID}
|
||||
onPress={onPress}
|
||||
underlayColor={changeOpacity(theme.centerChannelColor, Platform.select({android: 0.1, ios: 0.3}) || 0.3)}
|
||||
>
|
||||
<View style={style.mainContainer}>
|
||||
<View style={[style.container, containerStyle]}>
|
||||
{icon && (
|
||||
<View style={[style.iconContainer, iconContainerStyle]}>
|
||||
{icon}
|
||||
</View>
|
||||
)}
|
||||
<View style={style.labelContainer}>
|
||||
{label}
|
||||
</View>
|
||||
{rightComponent}
|
||||
{Boolean(showArrow) && (
|
||||
<CompassIcon
|
||||
name='chevron-right'
|
||||
style={[style.chevron, chevronStyle]}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
{Boolean(separator) && (<View style={[style.divider, separatorStyle]}/>)}
|
||||
</View>
|
||||
</TouchableWithFeedback>
|
||||
);
|
||||
};
|
||||
|
||||
export default MenuItem;
|
||||
@@ -98,6 +98,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
|
||||
export type OptionItemProps = {
|
||||
action?: (React.Dispatch<React.SetStateAction<string | boolean>>)|((value: string | boolean) => void);
|
||||
arrowStyle?: StyleProp<ViewStyle>;
|
||||
containerStyle?: StyleProp<ViewStyle>;
|
||||
description?: string;
|
||||
destructive?: boolean;
|
||||
@@ -117,6 +118,7 @@ export type OptionItemProps = {
|
||||
|
||||
const OptionItem = ({
|
||||
action,
|
||||
arrowStyle,
|
||||
containerStyle,
|
||||
description,
|
||||
destructive,
|
||||
@@ -197,6 +199,7 @@ const OptionItem = ({
|
||||
color={changeOpacity(theme.centerChannelColor, 0.32)}
|
||||
name='chevron-right'
|
||||
size={24}
|
||||
style={arrowStyle}
|
||||
/>
|
||||
);
|
||||
} else if (type === OptionType.REMOVE) {
|
||||
@@ -239,14 +242,14 @@ const OptionItem = ({
|
||||
{type === OptionType.RADIO && radioComponent}
|
||||
<View style={labelStyle}>
|
||||
<Text
|
||||
style={[optionLabelTextStyle, labelTextStyle]}
|
||||
style={[labelTextStyle, optionLabelTextStyle]}
|
||||
testID={`${testID}.label`}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
{Boolean(description) &&
|
||||
<Text
|
||||
style={[optionDescriptionTextStyle, descriptionTextStyle]}
|
||||
style={[descriptionTextStyle, optionDescriptionTextStyle]}
|
||||
testID={`${testID}.description`}
|
||||
>
|
||||
{description}
|
||||
|
||||
@@ -2,24 +2,25 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {TextStyle} from 'react-native';
|
||||
import {StyleProp, TextStyle} from 'react-native';
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {General} from '@constants';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {t} from '@i18n';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
type StatusLabelProps = {
|
||||
status?: string;
|
||||
labelStyle?: TextStyle;
|
||||
labelStyle?: StyleProp<TextStyle>;
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
label: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 17,
|
||||
...typography('Body', 200),
|
||||
textAlignVertical: 'center',
|
||||
includeFontPadding: false,
|
||||
},
|
||||
|
||||
@@ -93,8 +93,6 @@ export default class BaseDataOperator {
|
||||
|
||||
// We found a record in the database that matches this element; hence, we'll proceed for an UPDATE operation
|
||||
if (existingRecord) {
|
||||
// const existingRecord = createOrUpdateRaws[findIndex];
|
||||
|
||||
// Some raw value has an update_at field. We'll proceed to update only if the update_at value is different from the record's value in database
|
||||
const updateRecords = getValidRecordsForUpdate({
|
||||
tableName,
|
||||
@@ -125,8 +123,7 @@ export default class BaseDataOperator {
|
||||
* @param {RawValue[]} prepareRecord.createRaws
|
||||
* @param {RawValue[]} prepareRecord.updateRaws
|
||||
* @param {Model[]} prepareRecord.deleteRaws
|
||||
* @param {(TransformerArgs) => Promise<Model>;} prepareRecord.composer
|
||||
* @throws {DataOperatorException}
|
||||
* @param {(TransformerArgs) => Promise<Model>;} transformer
|
||||
* @returns {Promise<Model[]>}
|
||||
*/
|
||||
prepareRecords = async ({tableName, createRaws, deleteRaws, updateRaws, transformer}: OperationArgs): Promise<Model[]> => {
|
||||
@@ -184,7 +181,6 @@ export default class BaseDataOperator {
|
||||
* batchRecords: Accepts an instance of Database (either Default or Server) and an array of
|
||||
* prepareCreate/prepareUpdate 'models' and executes the actions on the database.
|
||||
* @param {Array} models
|
||||
* @throws {DataOperatorException}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async batchRecords(models: Model[]): Promise<void> {
|
||||
|
||||
@@ -28,7 +28,6 @@ const GroupHandler = (superclass: any) => class extends superclass implements Gr
|
||||
* handleGroups: Handler responsible for the Create/Update operations occurring on the Group table from the 'Server' schema
|
||||
*
|
||||
* @param {HandleGroupArgs}
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<GroupModel[]>}
|
||||
*/
|
||||
handleGroups = async ({groups, prepareRecordsOnly = true}: HandleGroupArgs): Promise<GroupModel[]> => {
|
||||
@@ -111,7 +110,6 @@ const GroupHandler = (superclass: any) => class extends superclass implements Gr
|
||||
* handleGroupMembershipsForMember: Handler responsible for the Create/Update operations occurring on the GroupMembership table from the 'Server' schema
|
||||
*
|
||||
* @param {HandleGroupMembershipForMemberArgs}
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<GroupMembershipModel[]>}
|
||||
*/
|
||||
handleGroupMembershipsForMember = async ({userId, groups, prepareRecordsOnly = true}: HandleGroupMembershipForMemberArgs): Promise<GroupMembershipModel[]> => {
|
||||
@@ -169,7 +167,6 @@ const GroupHandler = (superclass: any) => class extends superclass implements Gr
|
||||
* handleGroupTeamsForTeam: Handler responsible for the Create/Update operations occurring on the GroupTeam table from the 'Server' schema
|
||||
*
|
||||
* @param {HandleGroupTeamsForTeamArgs}
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<GroupTeamModel[]>}
|
||||
*/
|
||||
handleGroupTeamsForTeam = async ({teamId, groups, prepareRecordsOnly = true}: HandleGroupTeamsForTeamArgs): Promise<GroupTeamModel[]> => {
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
// 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';
|
||||
|
||||
type ServerVersionProps = {
|
||||
config: ClientConfig;
|
||||
}
|
||||
|
||||
const ServerVersion = ({config}: ServerVersionProps) => {
|
||||
const buildNumber = config.BuildNumber;
|
||||
const version = config.Version;
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
let id = t('mobile.about.serverVersion');
|
||||
let defaultMessage = 'Server Version: {version} (Build {number})';
|
||||
let values: {version: string; number?: string} = {
|
||||
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;
|
||||
@@ -8,6 +8,7 @@ import {View} from 'react-native';
|
||||
import ClearButton from '@components/custom_status/clear_button';
|
||||
import CustomStatusExpiry from '@components/custom_status/custom_status_expiry';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import CustomStatusText from './custom_status_text';
|
||||
@@ -16,9 +17,8 @@ type CustomLabelProps = {
|
||||
customStatus: UserCustomStatus;
|
||||
isCustomStatusExpirySupported: boolean;
|
||||
isStatusSet: boolean;
|
||||
showRetryMessage: boolean;
|
||||
theme: Theme;
|
||||
onClearCustomStatus: () => void;
|
||||
showRetryMessage: boolean;
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
@@ -30,6 +30,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
},
|
||||
customStatusTextContainer: {
|
||||
width: '70%',
|
||||
marginLeft: 16,
|
||||
},
|
||||
customStatusExpiryText: {
|
||||
paddingTop: 3,
|
||||
@@ -43,14 +44,14 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
};
|
||||
});
|
||||
|
||||
const CustomLabel = ({customStatus, isCustomStatusExpirySupported, isStatusSet, onClearCustomStatus, showRetryMessage, theme}: CustomLabelProps) => {
|
||||
const style = getStyleSheet(theme);
|
||||
const CustomLabel = ({customStatus, isCustomStatusExpirySupported, isStatusSet, onClearCustomStatus, showRetryMessage}: CustomLabelProps) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={style.customStatusTextContainer}>
|
||||
<View style={styles.customStatusTextContainer}>
|
||||
<CustomStatusText
|
||||
theme={theme}
|
||||
isStatusSet={Boolean(isStatusSet)}
|
||||
customStatus={customStatus}
|
||||
/>
|
||||
@@ -58,7 +59,7 @@ const CustomLabel = ({customStatus, isCustomStatusExpirySupported, isStatusSet,
|
||||
<CustomStatusExpiry
|
||||
time={moment(customStatus?.expires_at)}
|
||||
theme={theme}
|
||||
textStyles={style.customStatusExpiryText}
|
||||
textStyles={styles.customStatusExpiryText}
|
||||
withinBrackets={true}
|
||||
showPrefix={true}
|
||||
testID={'custom_status.expiry'}
|
||||
@@ -69,11 +70,11 @@ const CustomLabel = ({customStatus, isCustomStatusExpirySupported, isStatusSet,
|
||||
<FormattedText
|
||||
id={'custom_status.failure_message'}
|
||||
defaultMessage='Failed to update status. Try again'
|
||||
style={style.retryMessage}
|
||||
style={styles.retryMessage}
|
||||
/>
|
||||
)}
|
||||
{isStatusSet && (
|
||||
<View style={style.clearButton}>
|
||||
<View style={styles.clearButton}>
|
||||
<ClearButton
|
||||
handlePress={onClearCustomStatus}
|
||||
theme={theme}
|
||||
|
||||
@@ -6,12 +6,12 @@ import {View} from 'react-native';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import Emoji from '@components/emoji';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
type CustomStatusEmojiProps = {
|
||||
emoji?: string;
|
||||
isStatusSet: boolean;
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
@@ -22,7 +22,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
};
|
||||
});
|
||||
|
||||
const CustomStatusEmoji = ({emoji, isStatusSet, theme}: CustomStatusEmojiProps) => {
|
||||
const CustomStatusEmoji = ({emoji, isStatusSet}: CustomStatusEmojiProps) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
return (
|
||||
|
||||
@@ -5,27 +5,33 @@ import React from 'react';
|
||||
|
||||
import CustomText from '@components/custom_status/custom_status_text';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
type CustomStatusTextProps = {
|
||||
customStatus?: UserCustomStatus;
|
||||
isStatusSet: boolean;
|
||||
theme: Theme;
|
||||
};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
text: {
|
||||
color: theme.centerChannelColor,
|
||||
...typography('Body', 200),
|
||||
},
|
||||
}));
|
||||
|
||||
const CustomStatusText = ({isStatusSet, customStatus, theme}: CustomStatusTextProps) => {
|
||||
const CustomStatusText = ({isStatusSet, customStatus}: CustomStatusTextProps) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
let text: React.ReactNode | string;
|
||||
|
||||
text = (
|
||||
<FormattedText
|
||||
id='mobile.routes.custom_status'
|
||||
defaultMessage='Set a Status'
|
||||
style={styles.text}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -33,7 +39,6 @@ const CustomStatusText = ({isStatusSet, customStatus, theme}: CustomStatusTextPr
|
||||
text = customStatus.text;
|
||||
}
|
||||
|
||||
const styles = getStyleSheet(theme);
|
||||
return (
|
||||
<CustomText
|
||||
text={text}
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
|
||||
import React, {useCallback, useEffect, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {DeviceEventEmitter} from 'react-native';
|
||||
import {DeviceEventEmitter, TouchableOpacity, View} from 'react-native';
|
||||
|
||||
import {updateLocalCustomStatus} from '@actions/local/user';
|
||||
import {unsetCustomStatus} from '@actions/remote/user';
|
||||
import MenuItem from '@components/menu_item';
|
||||
import {Events, Screens} from '@constants';
|
||||
import {SET_CUSTOM_STATUS_FAILURE} from '@constants/custom_status';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {showModal} from '@screens/navigation';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
import {getUserCustomStatus, isCustomStatusExpired as checkCustomStatusIsExpired} from '@utils/user';
|
||||
|
||||
import CustomLabel from './custom_label';
|
||||
@@ -21,6 +22,21 @@ import CustomStatusEmoji from './custom_status_emoji';
|
||||
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
label: {
|
||||
color: theme.centerChannelColor,
|
||||
...typography('Body', 200),
|
||||
textAlignVertical: 'center',
|
||||
includeFontPadding: false,
|
||||
},
|
||||
body: {
|
||||
flexDirection: 'row',
|
||||
marginVertical: 18,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
type CustomStatusProps = {
|
||||
isCustomStatusExpirySupported: boolean;
|
||||
isTablet: boolean;
|
||||
@@ -35,6 +51,7 @@ const CustomStatus = ({isCustomStatusExpirySupported, isTablet, currentUser}: Cu
|
||||
const customStatus = getUserCustomStatus(currentUser);
|
||||
const isCustomStatusExpired = checkCustomStatusIsExpired(currentUser);
|
||||
const isStatusSet = !isCustomStatusExpired && (customStatus?.text || customStatus?.emoji);
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
useEffect(() => {
|
||||
const onSetCustomStatusError = () => {
|
||||
@@ -68,27 +85,23 @@ const CustomStatus = ({isCustomStatusExpirySupported, isTablet, currentUser}: Cu
|
||||
}), [isTablet]);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
testID='settings.sidebar.custom_status.action'
|
||||
labelComponent={
|
||||
<TouchableOpacity
|
||||
onPress={goToCustomStatusScreen}
|
||||
>
|
||||
<View style={styles.body}>
|
||||
<CustomStatusEmoji
|
||||
emoji={customStatus?.emoji}
|
||||
isStatusSet={Boolean(isStatusSet)}
|
||||
/>
|
||||
<CustomLabel
|
||||
theme={theme}
|
||||
customStatus={customStatus!}
|
||||
isCustomStatusExpirySupported={isCustomStatusExpirySupported}
|
||||
isStatusSet={Boolean(isStatusSet)}
|
||||
onClearCustomStatus={clearCustomStatus}
|
||||
showRetryMessage={showRetryMessage}
|
||||
/>
|
||||
}
|
||||
leftComponent={
|
||||
<CustomStatusEmoji
|
||||
emoji={customStatus?.emoji}
|
||||
isStatusSet={Boolean(isStatusSet)}
|
||||
theme={theme}
|
||||
/>}
|
||||
separator={false}
|
||||
onPress={goToCustomStatusScreen}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -36,13 +36,12 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
divider: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.2),
|
||||
height: 1,
|
||||
marginHorizontal: 15,
|
||||
width: '90%',
|
||||
alignSelf: 'center',
|
||||
marginVertical: 8,
|
||||
},
|
||||
menuLabel: {
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 16,
|
||||
lineHeight: 24,
|
||||
fontFamily: 'OpenSans',
|
||||
group: {
|
||||
paddingLeft: 16,
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -64,37 +63,29 @@ const AccountOptions = ({user, enableCustomUserStatuses, isCustomStatusExpirySup
|
||||
}}
|
||||
>
|
||||
<View style={styles.container}>
|
||||
<UserPresence
|
||||
currentUser={user}
|
||||
style={styles.menuLabel}
|
||||
theme={theme}
|
||||
/>
|
||||
{enableCustomUserStatuses &&
|
||||
<CustomStatus
|
||||
isCustomStatusExpirySupported={isCustomStatusExpirySupported}
|
||||
isTablet={isTablet}
|
||||
currentUser={user}
|
||||
/>}
|
||||
<View style={styles.group}>
|
||||
<UserPresence
|
||||
currentUser={user}
|
||||
/>
|
||||
{enableCustomUserStatuses &&
|
||||
<CustomStatus
|
||||
isCustomStatusExpirySupported={isCustomStatusExpirySupported}
|
||||
isTablet={isTablet}
|
||||
currentUser={user}
|
||||
/>}
|
||||
</View>
|
||||
<View style={styles.divider}/>
|
||||
<YourProfile
|
||||
isTablet={isTablet}
|
||||
style={styles.menuLabel}
|
||||
theme={theme}
|
||||
/>
|
||||
{/* <SavedMessages
|
||||
isTablet={isTablet}
|
||||
style={styles.menuLabel}
|
||||
theme={theme}
|
||||
/> */}
|
||||
<Settings
|
||||
isTablet={isTablet}
|
||||
style={styles.menuLabel}
|
||||
/>
|
||||
<View style={styles.group}>
|
||||
<YourProfile
|
||||
isTablet={isTablet}
|
||||
theme={theme}
|
||||
/>
|
||||
<Settings/>
|
||||
</View>
|
||||
<View style={styles.divider}/>
|
||||
<Logout
|
||||
style={styles.menuLabel}
|
||||
theme={theme}
|
||||
/>
|
||||
<View style={styles.group}>
|
||||
<Logout/>
|
||||
</View>
|
||||
</View>
|
||||
</Shadow>
|
||||
);
|
||||
|
||||
@@ -3,75 +3,48 @@
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {TextStyle, View} from 'react-native';
|
||||
|
||||
import {logout} from '@actions/remote/session';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import MenuItem from '@components/menu_item';
|
||||
import OptionItem from '@components/option_item';
|
||||
import {useServerDisplayName, useServerUrl} from '@context/server';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {alertServerLogout} from '@utils/server';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
type Props = {
|
||||
style: TextStyle;
|
||||
theme: Theme;
|
||||
}
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
desc: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.64),
|
||||
...typography('Body', 75),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
label: {
|
||||
color: theme.dndIndicator,
|
||||
marginTop: 5,
|
||||
},
|
||||
logOutFrom: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.64),
|
||||
fontSize: 12,
|
||||
height: 30,
|
||||
lineHeight: 16,
|
||||
fontFamily: 'OpenSans',
|
||||
},
|
||||
}));
|
||||
|
||||
const Settings = ({style, theme}: Props) => {
|
||||
const LogOut = () => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
const intl = useIntl();
|
||||
const serverUrl = useServerUrl();
|
||||
const serverDisplayName = useServerDisplayName();
|
||||
|
||||
const onLogout = useCallback(preventDoubleTap(() => {
|
||||
alertServerLogout(
|
||||
serverDisplayName,
|
||||
() => {
|
||||
logout(serverUrl);
|
||||
},
|
||||
intl,
|
||||
);
|
||||
alertServerLogout(serverDisplayName, () => logout(serverUrl), intl);
|
||||
}), [serverDisplayName, serverUrl, intl]);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
iconName='exit-to-app'
|
||||
isDestructor={true}
|
||||
labelComponent={(
|
||||
<View>
|
||||
<FormattedText
|
||||
id='account.logout'
|
||||
defaultMessage='Log out'
|
||||
style={[style, styles.label]}
|
||||
/>
|
||||
<FormattedText
|
||||
id={'account.logout_from'}
|
||||
defaultMessage={'Log out of {serverName}'}
|
||||
values={{serverName: serverDisplayName}}
|
||||
style={styles.logOutFrom}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
onPress={onLogout}
|
||||
separator={false}
|
||||
<OptionItem
|
||||
action={onLogout}
|
||||
description={intl.formatMessage({id: 'account.logout_from', defaultMessage: 'Log out from'}, {serverName: serverDisplayName})}
|
||||
destructive={true}
|
||||
icon='exit-to-app'
|
||||
label={intl.formatMessage({id: 'account.logout', defaultMessage: 'Log out'})}
|
||||
optionDescriptionTextStyle={styles.desc}
|
||||
testID='account.logout.action'
|
||||
type='default'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
export default LogOut;
|
||||
|
||||
@@ -3,47 +3,29 @@
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {TextStyle} from 'react-native';
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import MenuItem from '@components/menu_item';
|
||||
import OptionItem from '@components/option_item';
|
||||
import Screens from '@constants/screens';
|
||||
import {showModal} from '@screens/navigation';
|
||||
import {logInfo} from '@utils/log';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
type Props = {
|
||||
isTablet: boolean;
|
||||
style: TextStyle;
|
||||
}
|
||||
|
||||
const Settings = ({isTablet, style}: Props) => {
|
||||
const Settings = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
const openSettings = useCallback(preventDoubleTap(() => {
|
||||
if (isTablet) {
|
||||
//todo: https://mattermost.atlassian.net/browse/MM-39711
|
||||
logInfo('Settings on tablets need to be figured out and implemented - @Avinash');
|
||||
}
|
||||
showModal(
|
||||
Screens.SETTINGS,
|
||||
intl.formatMessage({id: 'mobile.screen.settings', defaultMessage: 'Settings'}),
|
||||
);
|
||||
}), [isTablet]);
|
||||
}), []);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
iconName='settings-outline'
|
||||
labelComponent={
|
||||
<FormattedText
|
||||
id='account.settings'
|
||||
defaultMessage='Settings'
|
||||
style={style}
|
||||
/>
|
||||
}
|
||||
onPress={openSettings}
|
||||
separator={false}
|
||||
<OptionItem
|
||||
action={openSettings}
|
||||
icon='settings-outline'
|
||||
label={intl.formatMessage({id: 'account.settings', defaultMessage: 'Settings'})}
|
||||
testID='account.settings.action'
|
||||
type='default'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,36 +3,54 @@
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {TextStyle} from 'react-native';
|
||||
import {TouchableOpacity, View} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
|
||||
import {setStatus} from '@actions/remote/user';
|
||||
import MenuItem from '@components/menu_item';
|
||||
import SlideUpPanelItem, {ITEM_HEIGHT} from '@components/slide_up_panel_item';
|
||||
import StatusLabel from '@components/status_label';
|
||||
import UserStatusIndicator from '@components/user_status';
|
||||
import General from '@constants/general';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {bottomSheet, dismissBottomSheet, dismissModal} from '@screens/navigation';
|
||||
import {bottomSheetSnapPoint} from '@utils/helpers';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {changeOpacity} from '@utils/theme';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
import {confirmOutOfOfficeDisabled} from '@utils/user';
|
||||
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
type Props = {
|
||||
currentUser: UserModel;
|
||||
style: TextStyle;
|
||||
theme: Theme;
|
||||
};
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
label: {
|
||||
color: theme.centerChannelColor,
|
||||
...typography('Body', 200),
|
||||
textAlignVertical: 'center',
|
||||
includeFontPadding: false,
|
||||
},
|
||||
body: {
|
||||
flexDirection: 'row',
|
||||
marginTop: 18,
|
||||
},
|
||||
spacer: {
|
||||
marginLeft: 16,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const {OUT_OF_OFFICE, OFFLINE, AWAY, ONLINE, DND} = General;
|
||||
|
||||
const UserStatus = ({currentUser, style, theme}: Props) => {
|
||||
type Props = {
|
||||
currentUser: UserModel;
|
||||
};
|
||||
const UserStatus = ({currentUser}: Props) => {
|
||||
const intl = useIntl();
|
||||
const insets = useSafeAreaInsets();
|
||||
const serverUrl = useServerUrl();
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
const handleSetStatus = useCallback(preventDoubleTap(() => {
|
||||
const renderContent = () => {
|
||||
@@ -47,7 +65,7 @@ const UserStatus = ({currentUser, style, theme}: Props) => {
|
||||
id: 'mobile.set_status.online',
|
||||
defaultMessage: 'Online',
|
||||
})}
|
||||
textStyles={style}
|
||||
textStyles={styles.label}
|
||||
/>
|
||||
<SlideUpPanelItem
|
||||
icon='clock'
|
||||
@@ -58,7 +76,7 @@ const UserStatus = ({currentUser, style, theme}: Props) => {
|
||||
id: 'mobile.set_status.away',
|
||||
defaultMessage: 'Away',
|
||||
})}
|
||||
textStyles={style}
|
||||
textStyles={styles.label}
|
||||
/>
|
||||
<SlideUpPanelItem
|
||||
icon='minus-circle'
|
||||
@@ -69,7 +87,7 @@ const UserStatus = ({currentUser, style, theme}: Props) => {
|
||||
id: 'mobile.set_status.dnd',
|
||||
defaultMessage: 'Do Not Disturb',
|
||||
})}
|
||||
textStyles={style}
|
||||
textStyles={styles.label}
|
||||
/>
|
||||
<SlideUpPanelItem
|
||||
icon='circle-outline'
|
||||
@@ -80,7 +98,7 @@ const UserStatus = ({currentUser, style, theme}: Props) => {
|
||||
id: 'mobile.set_status.offline',
|
||||
defaultMessage: 'Offline',
|
||||
})}
|
||||
textStyles={style}
|
||||
textStyles={styles.label}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
@@ -119,23 +137,20 @@ const UserStatus = ({currentUser, style, theme}: Props) => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
labelComponent={
|
||||
<StatusLabel
|
||||
labelStyle={style}
|
||||
status={currentUser.status}
|
||||
/>
|
||||
}
|
||||
leftComponent={
|
||||
<TouchableOpacity
|
||||
onPress={handleSetStatus}
|
||||
>
|
||||
<View style={styles.body}>
|
||||
<UserStatusIndicator
|
||||
size={24}
|
||||
status={currentUser.status}
|
||||
/>
|
||||
}
|
||||
onPress={handleSetStatus}
|
||||
separator={false}
|
||||
testID='account.status.action'
|
||||
/>
|
||||
<StatusLabel
|
||||
labelStyle={[styles.label, styles.spacer]}
|
||||
status={currentUser.status}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {DeviceEventEmitter, TextStyle} from 'react-native';
|
||||
import {DeviceEventEmitter} from 'react-native';
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import MenuItem from '@components/menu_item';
|
||||
import OptionItem from '@components/option_item';
|
||||
import {Events, Screens} from '@constants';
|
||||
import {ACCOUNT_OUTLINE_IMAGE} from '@constants/profile';
|
||||
import {showModal} from '@screens/navigation';
|
||||
@@ -14,11 +13,10 @@ import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
type Props = {
|
||||
isTablet: boolean;
|
||||
style: TextStyle;
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
const YourProfile = ({isTablet, style, theme}: Props) => {
|
||||
const YourProfile = ({isTablet, theme}: Props) => {
|
||||
const intl = useIntl();
|
||||
const openProfile = useCallback(preventDoubleTap(() => {
|
||||
if (isTablet) {
|
||||
@@ -32,18 +30,12 @@ const YourProfile = ({isTablet, style, theme}: Props) => {
|
||||
}), [isTablet, theme]);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
iconName={ACCOUNT_OUTLINE_IMAGE}
|
||||
labelComponent={
|
||||
<FormattedText
|
||||
id='account.your_profile'
|
||||
defaultMessage='Your Profile'
|
||||
style={style}
|
||||
/>
|
||||
}
|
||||
onPress={openProfile}
|
||||
separator={false}
|
||||
<OptionItem
|
||||
icon={ACCOUNT_OUTLINE_IMAGE}
|
||||
label={intl.formatMessage({id: 'account.your_profile', defaultMessage: 'Your Profile'})}
|
||||
testID='account.your_profile.action'
|
||||
type='default'
|
||||
action={openProfile}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import MenuItem from '@components/menu_item';
|
||||
import OptionItem from '@components/option_item';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {t} from '@i18n';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
@@ -26,7 +26,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
|
||||
const ShowMoreButton = ({onPress, showMore}: ShowMoreButtonProps) => {
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
const intl = useIntl();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
let id = t('mobile.search.show_more');
|
||||
let defaultMessage = 'Show more';
|
||||
@@ -36,17 +37,12 @@ const ShowMoreButton = ({onPress, showMore}: ShowMoreButtonProps) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
labelComponent={
|
||||
<FormattedText
|
||||
id={id}
|
||||
defaultMessage={defaultMessage}
|
||||
style={style.showMore}
|
||||
/>
|
||||
}
|
||||
onPress={onPress}
|
||||
separator={false}
|
||||
<OptionItem
|
||||
action={onPress}
|
||||
testID={'mobile.search.show_more'}
|
||||
type='default'
|
||||
label={intl.formatMessage({id, defaultMessage})}
|
||||
optionLabelTextStyle={styles.showMore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ import {useManagedConfig} from '@mattermost/react-native-emm';
|
||||
import React from 'react';
|
||||
|
||||
import {CopyPermalinkOption, FollowThreadOption, ReplyOption, SaveOption} from '@components/common_post_options';
|
||||
import {ITEM_HEIGHT} from '@components/menu_item';
|
||||
import {ITEM_HEIGHT} from '@components/option_item';
|
||||
import {Screens} from '@constants';
|
||||
import useNavButtonPressed from '@hooks/navigation_button_pressed';
|
||||
import BottomSheet from '@screens/bottom_sheet';
|
||||
|
||||
@@ -8,18 +8,37 @@ import FormattedText from '@components/formatted_text';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {t} from '@i18n';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
noticeLink: {
|
||||
color: theme.linkColor,
|
||||
...typography('Body', 50),
|
||||
},
|
||||
footerText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
...typography('Body', 50),
|
||||
marginBottom: 10,
|
||||
},
|
||||
hyphenText: {
|
||||
marginBottom: 0,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
type TosPrivacyContainerProps = {
|
||||
config: ClientConfig;
|
||||
onPressTOS: () => void;
|
||||
onPressPrivacyPolicy: () => void;
|
||||
}
|
||||
|
||||
const TosPrivacyContainer = ({config, onPressTOS, onPressPrivacyPolicy}: TosPrivacyContainerProps) => {
|
||||
const hasTermsOfServiceLink = config.TermsOfServiceLink;
|
||||
const hasPrivacyPolicyLink = config.PrivacyPolicyLink;
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
const hasTermsOfServiceLink = Boolean(config.TermsOfServiceLink);
|
||||
const hasPrivacyPolicyLink = Boolean(config.PrivacyPolicyLink);
|
||||
|
||||
return (
|
||||
<>
|
||||
{hasTermsOfServiceLink && (
|
||||
@@ -49,23 +68,4 @@ const TosPrivacyContainer = ({config, onPressTOS, onPressPrivacyPolicy}: TosPriv
|
||||
);
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
@@ -16,81 +16,87 @@ export const getSaveButton = (buttonId: string, intl: IntlShape, color: string)
|
||||
...typography('Body', 100, 'SemiBold'),
|
||||
});
|
||||
|
||||
export const SettingOptionConfig = {
|
||||
type SettingConfigDetails = {
|
||||
defaultMessage?: string;
|
||||
i18nId?: string;
|
||||
icon?: string;
|
||||
testID?: string;
|
||||
}
|
||||
|
||||
export const SettingOptionConfig: Record<string, SettingConfigDetails> = {
|
||||
notification: {
|
||||
defaultMessage: 'Notifications',
|
||||
i18nId: t('general_settings.notifications'),
|
||||
iconName: 'bell-outline',
|
||||
icon: 'bell-outline',
|
||||
testID: 'general_settings.notifications',
|
||||
},
|
||||
display: {
|
||||
defaultMessage: 'Display',
|
||||
i18nId: t('general_settings.display'),
|
||||
iconName: 'layers-outline',
|
||||
icon: 'layers-outline',
|
||||
testID: 'general_settings.display',
|
||||
},
|
||||
advanced_settings: {
|
||||
defaultMessage: 'Advanced Settings',
|
||||
i18nId: t('general_settings.advanced_settings'),
|
||||
iconName: 'tune',
|
||||
icon: 'tune',
|
||||
testID: 'general_settings.advanced',
|
||||
},
|
||||
about: {
|
||||
defaultMessage: 'About {appTitle}',
|
||||
i18nId: t('general_settings.about'),
|
||||
iconName: 'information-outline',
|
||||
icon: 'information-outline',
|
||||
testID: 'general_settings.about',
|
||||
},
|
||||
help: {
|
||||
defaultMessage: 'Help',
|
||||
i18nId: t('general_settings.help'),
|
||||
testID: 'general_settings.help',
|
||||
showArrow: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const NotificationsOptionConfig = {
|
||||
export const NotificationsOptionConfig: Record<string, SettingConfigDetails> = {
|
||||
mentions: {
|
||||
iconName: 'at',
|
||||
icon: 'at',
|
||||
testID: 'notification_settings.mentions_replies',
|
||||
},
|
||||
push_notification: {
|
||||
defaultMessage: 'Push Notifications',
|
||||
i18nId: t('notification_settings.mobile'),
|
||||
iconName: 'cellphone',
|
||||
icon: 'cellphone',
|
||||
testID: 'notification_settings.push_notification',
|
||||
},
|
||||
email: {
|
||||
defaultMessage: 'Email',
|
||||
i18nId: t('notification_settings.email'),
|
||||
iconName: 'email-outline',
|
||||
icon: 'email-outline',
|
||||
testID: 'notification_settings.email',
|
||||
},
|
||||
automatic_dm_replies: {
|
||||
defaultMessage: 'Automatic replies',
|
||||
i18nId: t('notification_settings.ooo_auto_responder'),
|
||||
iconName: 'reply-outline',
|
||||
icon: 'reply-outline',
|
||||
testID: 'notification_settings.automatic_dm_replies',
|
||||
},
|
||||
};
|
||||
|
||||
export const DisplayOptionConfig = {
|
||||
export const DisplayOptionConfig: Record<string, SettingConfigDetails> = {
|
||||
clock: {
|
||||
defaultMessage: 'Clock Display',
|
||||
i18nId: t('mobile.display_settings.clockDisplay'),
|
||||
iconName: 'clock-outline',
|
||||
icon: 'clock-outline',
|
||||
testID: 'display_settings.clock',
|
||||
},
|
||||
theme: {
|
||||
defaultMessage: 'Theme',
|
||||
i18nId: t('mobile.display_settings.theme'),
|
||||
iconName: 'palette-outline',
|
||||
icon: 'palette-outline',
|
||||
testID: 'display_settings.theme',
|
||||
},
|
||||
timezone: {
|
||||
defaultMessage: 'Timezone',
|
||||
i18nId: t('mobile.display_settings.timezone'),
|
||||
iconName: 'globe',
|
||||
icon: 'globe',
|
||||
testID: 'display_settings.timezone',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
import React, {useMemo} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {StyleSheet} from 'react-native';
|
||||
|
||||
import {Screens} from '@constants';
|
||||
import {useTheme} from '@context/theme';
|
||||
@@ -14,7 +13,6 @@ import {getUserTimezoneProps} from '@utils/user';
|
||||
|
||||
import SettingContainer from '../setting_container';
|
||||
import SettingItem from '../setting_item';
|
||||
import SettingRowLabel from '../setting_row_label';
|
||||
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
@@ -40,12 +38,6 @@ const TIMEZONE_FORMAT = [
|
||||
},
|
||||
];
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
title: {
|
||||
textTransform: 'capitalize',
|
||||
},
|
||||
});
|
||||
|
||||
type DisplayProps = {
|
||||
currentUser: UserModel;
|
||||
hasMilitaryTimeFormat: boolean;
|
||||
@@ -83,32 +75,19 @@ const Display = ({currentUser, hasMilitaryTimeFormat, isThemeSwitchingEnabled, i
|
||||
<SettingItem
|
||||
optionName='theme'
|
||||
onPress={goToThemeSettings}
|
||||
rightComponent={Boolean(theme.type) &&
|
||||
<SettingRowLabel
|
||||
text={theme.type!}
|
||||
textStyle={styles.title}
|
||||
/>
|
||||
}
|
||||
info={theme.type!}
|
||||
/>
|
||||
)}
|
||||
<SettingItem
|
||||
optionName='clock'
|
||||
onPress={goToClockDisplaySettings}
|
||||
rightComponent={
|
||||
<SettingRowLabel
|
||||
text={intl.formatMessage(hasMilitaryTimeFormat ? TIME_FORMAT[1] : TIME_FORMAT[0])}
|
||||
/>
|
||||
}
|
||||
info={intl.formatMessage(hasMilitaryTimeFormat ? TIME_FORMAT[1] : TIME_FORMAT[0])}
|
||||
/>
|
||||
{isTimezoneEnabled && (
|
||||
<SettingItem
|
||||
optionName='timezone'
|
||||
onPress={goToTimezoneSettings}
|
||||
rightComponent={
|
||||
<SettingRowLabel
|
||||
text={intl.formatMessage(timezone.useAutomaticTimezone ? TIMEZONE_FORMAT[0] : TIMEZONE_FORMAT[1])}
|
||||
/>
|
||||
}
|
||||
info={intl.formatMessage(timezone.useAutomaticTimezone ? TIMEZONE_FORMAT[0] : TIMEZONE_FORMAT[1])}
|
||||
/>
|
||||
)}
|
||||
</SettingContainer>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React, {useCallback, useEffect, useMemo, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
|
||||
import {updateMe} from '@actions/remote/user';
|
||||
import {fetchStatusInBatch, updateMe} from '@actions/remote/user';
|
||||
import FloatingTextInput from '@components/floating_text_input_label';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {General} from '@constants';
|
||||
@@ -88,8 +88,9 @@ const NotificationAutoResponder = ({currentUser, componentId}: NotificationAutoR
|
||||
auto_responder_message: autoResponderMessage,
|
||||
},
|
||||
});
|
||||
fetchStatusInBatch(serverUrl, currentUser.id);
|
||||
close();
|
||||
}, [serverUrl, autoResponderActive, autoResponderMessage, notifyProps]);
|
||||
}, [serverUrl, autoResponderActive, autoResponderMessage, notifyProps, currentUser.id]);
|
||||
|
||||
useEffect(() => {
|
||||
const enabled = initialAutoResponderActive !== autoResponderActive || initialOOOMsg !== autoResponderMessage;
|
||||
@@ -120,7 +121,6 @@ const NotificationAutoResponder = ({currentUser, componentId}: NotificationAutoR
|
||||
allowFontScaling={true}
|
||||
autoCapitalize='none'
|
||||
autoCorrect={false}
|
||||
blurOnSubmit={true}
|
||||
containerStyle={styles.textInputContainer}
|
||||
keyboardAppearance={getKeyboardAppearanceFromTheme(theme)}
|
||||
label={intl.formatMessage(label)}
|
||||
@@ -128,7 +128,7 @@ const NotificationAutoResponder = ({currentUser, componentId}: NotificationAutoR
|
||||
onChangeText={setAutoResponderMessage}
|
||||
placeholder={intl.formatMessage(label)}
|
||||
placeholderTextColor={changeOpacity(theme.centerChannelColor, 0.4)}
|
||||
returnKeyType='done'
|
||||
returnKeyType='default'
|
||||
textAlignVertical='top'
|
||||
textInputStyle={styles.input}
|
||||
theme={theme}
|
||||
|
||||
@@ -7,7 +7,6 @@ import {useIntl} from 'react-intl';
|
||||
import {General, Screens} from '@constants';
|
||||
import {t} from '@i18n';
|
||||
import {goToScreen} from '@screens/navigation';
|
||||
import SettingRowLabel from '@screens/settings/setting_row_label';
|
||||
import {getEmailInterval, getEmailIntervalTexts, getNotificationProps} from '@utils/user';
|
||||
|
||||
import SettingContainer from '../setting_container';
|
||||
@@ -91,10 +90,12 @@ const Notifications = ({
|
||||
return (
|
||||
<SettingContainer>
|
||||
<SettingItem
|
||||
defaultMessage={isCRTEnabled ? mentionTexts.crtOn.defaultMessage : mentionTexts.crtOff.defaultMessage}
|
||||
i18nId={isCRTEnabled ? mentionTexts.crtOn.id : mentionTexts.crtOff.id}
|
||||
onPress={goToNotificationSettingsMentions}
|
||||
optionName='mentions'
|
||||
label={intl.formatMessage({
|
||||
id: isCRTEnabled ? mentionTexts.crtOn.id : mentionTexts.crtOff.id,
|
||||
defaultMessage: isCRTEnabled ? mentionTexts.crtOn.defaultMessage : mentionTexts.crtOff.defaultMessage,
|
||||
})}
|
||||
/>
|
||||
<SettingItem
|
||||
optionName='push_notification'
|
||||
@@ -103,21 +104,13 @@ const Notifications = ({
|
||||
<SettingItem
|
||||
optionName='email'
|
||||
onPress={goToEmailSettings}
|
||||
rightComponent={
|
||||
<SettingRowLabel
|
||||
text={intl.formatMessage(getEmailIntervalTexts(emailIntervalPref))}
|
||||
/>
|
||||
}
|
||||
info={intl.formatMessage(getEmailIntervalTexts(emailIntervalPref))}
|
||||
/>
|
||||
{enableAutoResponder && (
|
||||
<SettingItem
|
||||
onPress={goToNotificationAutoResponder}
|
||||
optionName='automatic_dm_replies'
|
||||
rightComponent={
|
||||
<SettingRowLabel
|
||||
text={currentUser.status === General.OUT_OF_OFFICE && notifyProps.auto_responder_active === 'true' ? 'On' : 'Off'}
|
||||
/>
|
||||
}
|
||||
info={currentUser.status === General.OUT_OF_OFFICE && notifyProps.auto_responder_active === 'true' ? 'On' : 'Off'}
|
||||
/>
|
||||
)}
|
||||
</SettingContainer>
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Platform} from 'react-native';
|
||||
|
||||
import MenuItem, {MenuItemProps} from '@components/menu_item';
|
||||
import OptionItem, {OptionItemProps} from '@components/option_item';
|
||||
import {useTheme} from '@context/theme';
|
||||
import SettingSeparator from '@screens/settings/settings_separator';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
@@ -15,7 +17,8 @@ type SettingsConfig = keyof typeof SettingOptionConfig | keyof typeof Notificati
|
||||
type SettingOptionProps = {
|
||||
optionName: SettingsConfig;
|
||||
onPress: () => void;
|
||||
} & Omit<MenuItemProps, 'testID'| 'theme'>;
|
||||
separator?: boolean;
|
||||
} & Partial<OptionItemProps>;
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
return {
|
||||
@@ -23,10 +26,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
color: theme.centerChannelColor,
|
||||
...typography('Body', 200, 'Regular'),
|
||||
},
|
||||
separatorStyle: {
|
||||
width: '91%',
|
||||
alignSelf: 'center',
|
||||
},
|
||||
chevronStyle: {
|
||||
marginRight: 14,
|
||||
color: changeOpacity(theme.centerChannelColor, 0.32),
|
||||
@@ -34,21 +33,35 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
};
|
||||
});
|
||||
|
||||
const SettingItem = ({onPress, optionName, ...rest}: SettingOptionProps) => {
|
||||
const SettingItem = ({
|
||||
info,
|
||||
onPress,
|
||||
optionName,
|
||||
separator = true,
|
||||
...props
|
||||
}: SettingOptionProps) => {
|
||||
const theme = useTheme();
|
||||
const intl = useIntl();
|
||||
const styles = getStyleSheet(theme);
|
||||
const props = {...rest, ...Options[optionName]} as unknown as Omit<MenuItemProps, 'onPress'| 'theme'>;
|
||||
const config = Options[optionName];
|
||||
|
||||
const label = props.label || intl.formatMessage({id: config.i18nId, defaultMessage: config.defaultMessage});
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
chevronStyle={styles.chevronStyle}
|
||||
labelStyle={styles.menuLabel}
|
||||
onPress={onPress}
|
||||
separator={Platform.OS === 'ios'}
|
||||
separatorStyle={styles.separatorStyle}
|
||||
showArrow={Platform.select({ios: true, default: false})}
|
||||
{...props}
|
||||
/>
|
||||
<>
|
||||
<OptionItem
|
||||
action={onPress}
|
||||
arrowStyle={styles.chevronStyle}
|
||||
containerStyle={{marginLeft: 16}}
|
||||
icon={config.icon}
|
||||
info={info}
|
||||
label={label}
|
||||
optionLabelTextStyle={[styles.menuLabel, props.optionLabelTextStyle]}
|
||||
type={Platform.select({ios: 'arrow', default: 'default'})}
|
||||
{...props}
|
||||
/>
|
||||
{separator && <SettingSeparator/>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Platform, StyleProp, Text, TextStyle} from 'react-native';
|
||||
|
||||
import {useTheme} from '@context/theme';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
rightLabel: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.56),
|
||||
...typography('Body', 100, 'Regular'),
|
||||
alignSelf: 'center',
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginRight: 20,
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
type SettingRowLabelProps = {
|
||||
text: string;
|
||||
textStyle?: StyleProp<TextStyle>;
|
||||
}
|
||||
const SettingRowLabel = ({text, textStyle}: SettingRowLabelProps) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
return (
|
||||
<Text
|
||||
style={[styles.rightLabel, textStyle]}
|
||||
>
|
||||
{text}
|
||||
</Text>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingRowLabel;
|
||||
@@ -135,18 +135,20 @@ const Settings = ({componentId, helpLink, showHelp, siteName}: SettingsProps) =>
|
||||
optionName='advanced_settings'
|
||||
/>
|
||||
<SettingItem
|
||||
messageValues={{appTitle: serverName}}
|
||||
icon='information-outline'
|
||||
label={intl.formatMessage({id: 'settings.about', defaultMessage: 'About {appTitle}'}, {appTitle: serverName})}
|
||||
onPress={goToAbout}
|
||||
optionName='about'
|
||||
testID='general_settings.about'
|
||||
/>
|
||||
{Platform.OS === 'android' && <View style={styles.helpGroup}/>}
|
||||
{showHelp &&
|
||||
<SettingItem
|
||||
containerStyle={styles.containerStyle}
|
||||
isLink={true}
|
||||
optionLabelTextStyle={{color: theme.linkColor}}
|
||||
onPress={openHelp}
|
||||
optionName='help'
|
||||
separator={false}
|
||||
type='default'
|
||||
/>
|
||||
}
|
||||
</SettingContainer>
|
||||
|
||||
@@ -234,10 +234,10 @@ const SnackBar = ({barType, componentId, onAction, sourceScreen}: SnackBarProps)
|
||||
>
|
||||
<Toast
|
||||
animatedStyle={snackBarStyle}
|
||||
message={intl.formatMessage({id: config.id, defaultMessage: config.defaultMessage})}
|
||||
iconName={config.iconName}
|
||||
message={intl.formatMessage({id: config.id, defaultMessage: config.defaultMessage})}
|
||||
style={[styles.toast, barType === SNACK_BAR_TYPE.LINK_COPIED && {backgroundColor: theme.onlineIndicator}]}
|
||||
textStyle={styles.text}
|
||||
style={styles.toast}
|
||||
>
|
||||
{config.canUndo && onAction && (
|
||||
<TouchableOpacity onPress={onUndoPressHandler}>
|
||||
|
||||
@@ -7,7 +7,7 @@ import {View} from 'react-native';
|
||||
|
||||
import {CopyPermalinkOption, FollowThreadOption, ReplyOption, SaveOption} from '@components/common_post_options';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {ITEM_HEIGHT} from '@components/menu_item';
|
||||
import {ITEM_HEIGHT} from '@components/option_item';
|
||||
import {Screens} from '@constants';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
|
||||
Reference in New Issue
Block a user