Unverified Commit bd09cd32 authored by Gerzon Z's avatar Gerzon Z Committed by GitHub
Browse files

[FIX] Wrong styling on E2E encryption banner (#2767)



* [FIX] Wrong styling on E2E encryption banner

* [FIX] Wrong styling on E2E encryption banner

* [FIX] Wrong styling on E2E encryption banner

* [FIX] Wrong styling on E2E encryption banner (#2767)

* Updated SortDropdown, ListHeader, ListItem and added stories for List.Item

* Updated SortDropdown

* Removed unused component

* Updated List.Item and stories

* Reverted unnecessary changes and updated ListItem stories

* Fix minor indentation

* Stop breaking Touch's default underlay color

* Fix indentation

* Remove falsy comparison from render

* Fix left icon

* Use List.Item on OmnichannelStatus

* Add missing separator

* Lint

* Fix sort dropdown

* Remove unnecessary styles

* Fix detox
Co-authored-by: default avatarDiego Mello <diegolmello@gmail.com>
parent 0fdb8f2e
......@@ -6796,7 +6796,7 @@ exports[`Storyshots List with black theme 1`] = `
</RNCSafeAreaView>
`;
 
exports[`Storyshots List with custom color 1`] = `
exports[`Storyshots List with custom colors 1`] = `
<RCTScrollView
contentContainerStyle={
Object {
......@@ -6893,6 +6893,65 @@ exports[`Storyshots List with custom color 1`] = `
]
}
/>
<View
style={
Array [
Object {
"alignItems": "center",
"flex": 1,
"flexDirection": "row",
"justifyContent": "center",
"paddingHorizontal": 12,
},
false,
Object {
"height": 92,
},
]
}
>
<View
style={
Object {
"flex": 1,
"justifyContent": "center",
}
}
>
<Text
numberOfLines={1}
style={
Array [
Object {
"backgroundColor": "transparent",
"fontFamily": "System",
"fontSize": 16,
"fontWeight": "400",
"textAlign": "left",
},
Object {
"color": "white",
},
]
}
>
Press me!
</Text>
</View>
</View>
<View
style={
Array [
Object {
"height": 0.5,
},
undefined,
Object {
"backgroundColor": "#cbcbcc",
},
]
}
/>
</View>
</RCTScrollView>
`;
......@@ -35,6 +35,7 @@ export const themes = {
auxiliaryText: '#9ca2a8',
infoText: '#6d6d72',
tintColor: '#1d74f5',
tintActive: '#549df9',
auxiliaryTintColor: '#6C727A',
actionTintColor: '#1d74f5',
separatorColor: '#cbcbcc',
......@@ -80,6 +81,7 @@ export const themes = {
auxiliaryText: '#9297a2',
infoText: '#6D6D72',
tintColor: '#1d74f5',
tintActive: '#549df9',
auxiliaryTintColor: '#f9f9f9',
actionTintColor: '#1d74f5',
separatorColor: '#2b2b2d',
......@@ -125,6 +127,7 @@ export const themes = {
auxiliaryText: '#b2b8c6',
infoText: '#6d6d72',
tintColor: '#1e9bfe',
tintActive: '#76b7fc',
auxiliaryTintColor: '#f9f9f9',
actionTintColor: '#1e9bfe',
separatorColor: '#272728',
......
import React from 'react';
import {
View,
Text,
StyleSheet,
I18nManager
View, Text, StyleSheet, I18nManager
} from 'react-native';
import PropTypes from 'prop-types';
......@@ -82,11 +79,12 @@ const Content = React.memo(({
));
const Button = React.memo(({
onPress, ...props
onPress, backgroundColor, underlayColor, ...props
}) => (
<Touch
onPress={() => onPress(props.title)}
style={{ backgroundColor: themes[props.theme].backgroundColor }}
style={{ backgroundColor: backgroundColor || themes[props.theme].backgroundColor }}
underlayColor={underlayColor}
enabled={!props.disabled}
theme={props.theme}
>
......@@ -99,7 +97,7 @@ const ListItem = React.memo(({ ...props }) => {
return <Button {...props} />;
}
return (
<View style={{ backgroundColor: themes[props.theme].backgroundColor }}>
<View style={{ backgroundColor: props.backgroundColor || themes[props.theme].backgroundColor }}>
<Content {...props} />
</View>
);
......@@ -107,7 +105,8 @@ const ListItem = React.memo(({ ...props }) => {
ListItem.propTypes = {
onPress: PropTypes.func,
theme: PropTypes.string
theme: PropTypes.string,
backgroundColor: PropTypes.string
};
ListItem.displayName = 'List.Item';
......@@ -137,7 +136,9 @@ Button.propTypes = {
title: PropTypes.string,
onPress: PropTypes.func,
disabled: PropTypes.bool,
theme: PropTypes.string
theme: PropTypes.string,
backgroundColor: PropTypes.string,
underlayColor: PropTypes.string
};
Button.defaultProps = {
......
import React, { memo, useState, useEffect } from 'react';
import {
View, Text, StyleSheet, Switch
} from 'react-native';
import { View, Switch } from 'react-native';
import PropTypes from 'prop-types';
import Touch from '../../../utils/touch';
import { CustomIcon } from '../../../lib/Icons';
import I18n from '../../../i18n';
import * as List from '../../../containers/List';
import styles from '../../../views/RoomsListView/styles';
import { themes, SWITCH_TRACK_COLOR } from '../../../constants/colors';
import { withTheme } from '../../../theme';
......@@ -36,35 +32,32 @@ const OmnichannelStatus = memo(({
};
return (
<Touch
onPress={goQueue}
theme={theme}
style={{ backgroundColor: themes[theme].headerSecondaryBackground }}
>
<View
style={[
styles.dropdownContainerHeader,
{ borderBottomWidth: StyleSheet.hairlineWidth, borderColor: themes[theme].separatorColor }
]}
>
<CustomIcon style={[styles.queueIcon, { color: themes[theme].auxiliaryText }]} size={22} name='omnichannel' />
<Text style={[styles.queueToggleText, { color: themes[theme].auxiliaryText }]}>{I18n.t('Omnichannel')}</Text>
{inquiryEnabled
? (
<UnreadBadge
style={styles.queueIcon}
unread={queueSize}
<>
<List.Item
title='Omnichannel'
left={() => <List.Icon name='omnichannel' />}
color={themes[theme].auxiliaryText}
onPress={goQueue}
right={() => (
<View style={styles.omnichannelRightContainer}>
{inquiryEnabled
? (
<UnreadBadge
style={styles.queueIcon}
unread={queueSize}
/>
)
: null}
<Switch
value={status}
trackColor={SWITCH_TRACK_COLOR}
onValueChange={toggleLivechat}
/>
)
: null}
<Switch
style={styles.omnichannelToggle}
value={status}
trackColor={SWITCH_TRACK_COLOR}
onValueChange={toggleLivechat}
/>
</View>
</Touch>
</View>
)}
/>
<List.Separator />
</>
);
});
......
......@@ -15,7 +15,7 @@ class Touch extends React.Component {
render() {
const {
children, onPress, theme, ...props
children, onPress, theme, underlayColor, ...props
} = this.props;
return (
......@@ -23,7 +23,7 @@ class Touch extends React.Component {
ref={this.getRef}
onPress={onPress}
activeOpacity={1}
underlayColor={themes[theme].bannerBackground}
underlayColor={underlayColor || themes[theme].bannerBackground}
rippleColor={themes[theme].bannerBackground}
{...props}
>
......@@ -36,7 +36,8 @@ class Touch extends React.Component {
Touch.propTypes = {
children: PropTypes.node,
onPress: PropTypes.func,
theme: PropTypes.string
theme: PropTypes.string,
underlayColor: PropTypes.string
};
export default Touch;
import React from 'react';
import { Text } from 'react-native';
import PropTypes from 'prop-types';
import { BorderlessButton } from 'react-native-gesture-handler';
import { withTheme } from '../../../theme';
import { CustomIcon } from '../../../lib/Icons';
import { themes } from '../../../constants/colors';
import I18n from '../../../i18n';
import styles from '../styles';
import { E2E_BANNER_TYPE } from '../../../lib/encryption/constants';
const Encryption = React.memo(({
searching,
goEncryption,
encryptionBanner,
theme
}) => {
if (searching > 0 || !encryptionBanner) {
return null;
}
let text = I18n.t('Save_Your_Encryption_Password');
if (encryptionBanner === E2E_BANNER_TYPE.REQUEST_PASSWORD) {
text = I18n.t('Enter_Your_E2E_Password');
}
return (
<BorderlessButton
style={[styles.encryptionButton, { backgroundColor: themes[theme].actionTintColor }]}
theme={theme}
onPress={goEncryption}
testID='listheader-encryption'
accessibilityLabel={text}
>
<CustomIcon name='encrypted' size={24} color={themes[theme].buttonText} style={styles.encryptionIcon} />
<Text style={[styles.encryptionText, { color: themes[theme].buttonText }]}>{text}</Text>
</BorderlessButton>
);
});
Encryption.propTypes = {
searching: PropTypes.bool,
goEncryption: PropTypes.func,
encryptionBanner: PropTypes.string,
theme: PropTypes.string
};
export default withTheme(Encryption);
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
import Touch from '../../../utils/touch';
import { CustomIcon } from '../../../lib/Icons';
import I18n from '../../../i18n';
import styles from '../styles';
import { themes } from '../../../constants/colors';
import { withTheme } from '../../../theme';
const Sort = React.memo(({
searching, sortBy, toggleSort, theme
}) => {
if (searching > 0) {
return null;
}
return (
<Touch
onPress={toggleSort}
theme={theme}
style={{ backgroundColor: themes[theme].headerSecondaryBackground }}
>
<View
style={[
styles.dropdownContainerHeader,
{ borderBottomWidth: StyleSheet.hairlineWidth, borderColor: themes[theme].separatorColor }
]}
>
<CustomIcon style={[styles.sortIcon, { color: themes[theme].auxiliaryText }]} size={22} name='sort' />
<Text style={[styles.sortToggleText, { color: themes[theme].auxiliaryText }]}>{I18n.t('Sorting_by', { key: I18n.t(sortBy === 'alphabetical' ? 'name' : 'activity') })}</Text>
</View>
</Touch>
);
});
Sort.propTypes = {
searching: PropTypes.bool,
sortBy: PropTypes.string,
theme: PropTypes.string,
toggleSort: PropTypes.func
};
export default withTheme(Sort);
import React from 'react';
import PropTypes from 'prop-types';
import Sort from './Sort';
import Encryption from './Encryption';
import { withTheme } from '../../../theme';
import I18n from '../../../i18n';
import * as List from '../../../containers/List';
import { E2E_BANNER_TYPE } from '../../../lib/encryption/constants';
import { themes } from '../../../constants/colors';
import OmnichannelStatus from '../../../ee/omnichannel/containers/OmnichannelStatus';
......@@ -15,14 +18,55 @@ const ListHeader = React.memo(({
queueSize,
inquiryEnabled,
encryptionBanner,
user
}) => (
<>
<Encryption searching={searching} goEncryption={goEncryption} encryptionBanner={encryptionBanner} />
<Sort searching={searching} sortBy={sortBy} toggleSort={toggleSort} />
<OmnichannelStatus searching={searching} goQueue={goQueue} inquiryEnabled={inquiryEnabled} queueSize={queueSize} user={user} />
</>
));
user,
theme
}) => {
const sortTitle = I18n.t('Sorting_by', { key: I18n.t(sortBy === 'alphabetical' ? 'name' : 'activity') });
if (searching) {
return null;
}
return (
<>
{encryptionBanner
? (
<>
<List.Item
title={
encryptionBanner === E2E_BANNER_TYPE.REQUEST_PASSWORD
? 'Enter_Your_E2E_Password'
: 'Save_Your_Encryption_Password'
}
left={() => <List.Icon name='encrypted' color={themes[theme].buttonText} />}
underlayColor={themes[theme].tintActive}
backgroundColor={themes[theme].actionTintColor}
color={themes[theme].buttonText}
onPress={goEncryption}
testID='listheader-encryption'
/>
<List.Separator />
</>
)
: null}
<List.Item
title={sortTitle}
left={() => <List.Icon name='sort' />}
color={themes[theme].auxiliaryText}
onPress={toggleSort}
translateTitle={false}
/>
<List.Separator />
<OmnichannelStatus
searching={searching}
goQueue={goQueue}
inquiryEnabled={inquiryEnabled}
queueSize={queueSize}
user={user}
/>
</>
);
});
ListHeader.propTypes = {
searching: PropTypes.bool,
......@@ -33,7 +77,8 @@ ListHeader.propTypes = {
queueSize: PropTypes.number,
inquiryEnabled: PropTypes.bool,
encryptionBanner: PropTypes.string,
user: PropTypes.object
user: PropTypes.object,
theme: PropTypes.string
};
export default ListHeader;
export default withTheme(ListHeader);
import React from 'react';
import { View, Text, Image } from 'react-native';
import PropTypes from 'prop-types';
import styles from '../styles';
import Touch from '../../../utils/touch';
import I18n from '../../../i18n';
import { CustomIcon } from '../../../lib/Icons';
import Check from '../../../containers/Check';
import { themes } from '../../../constants/colors';
export const SortItemButton = ({ children, onPress, theme }) => (
<Touch
style={styles.sortItemButton}
onPress={onPress}
theme={theme}
>
{children}
</Touch>
);
SortItemButton.propTypes = {
theme: PropTypes.string,
children: PropTypes.node,
onPress: PropTypes.func
};
export const SortItemContent = ({
label, icon, imageUri, checked, theme
}) => (
<View style={styles.sortItemContainer}>
{icon && <CustomIcon style={[styles.sortIcon, { color: themes[theme].controlText }]} size={22} name={icon} />}
{imageUri && <Image style={[styles.sortIcon, { tintColor: themes[theme].controlText }]} source={{ uri: imageUri }} />}
<Text style={[styles.sortItemText, { color: themes[theme].controlText }]}>{I18n.t(label)}</Text>
{checked ? <Check theme={theme} /> : null}
</View>
);
SortItemContent.propTypes = {
theme: PropTypes.string,
label: PropTypes.string,
icon: PropTypes.string,
imageUri: PropTypes.string,
checked: PropTypes.bool
};
import React, { PureComponent } from 'react';
import {
View, Text, Animated, Easing, TouchableWithoutFeedback
Animated, Easing, TouchableWithoutFeedback
} from 'react-native';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { withSafeAreaInsets } from 'react-native-safe-area-context';
import styles from '../styles';
import Touch from '../../../utils/touch';
import * as List from '../../../containers/List';
import RocketChat from '../../../lib/rocketchat';
import { setPreference } from '../../../actions/sortPreferences';
import log, { logEvent, events } from '../../../utils/log';
import I18n from '../../../i18n';
import { CustomIcon } from '../../../lib/Icons';
import { withTheme } from '../../../theme';
import { themes } from '../../../constants/colors';
import { SortItemButton, SortItemContent } from './Item';
import { headerHeight } from '../../../containers/Header';
const ANIMATION_DURATION = 200;
......@@ -113,6 +111,11 @@ class Sort extends PureComponent {
).start(() => close());
}
renderCheck = () => {
const { theme } = this.props;
return <List.Icon name='check' color={themes[theme].tintColor} />;
}
render() {
const { isMasterDetail, insets } = this.props;
const statusBarHeight = insets?.top ?? 0;
......@@ -150,58 +153,50 @@ class Sort extends PureComponent {
}
]}
>
<Touch
<List.Item
title={I18n.t('Sorting_by', { key: I18n.t(sortBy === 'alphabetical' ? 'name' : 'activity') })}
left={() => <List.Icon name='sort' />}
color={themes[theme].auxiliaryText}
onPress={this.close}
theme={theme}
>
<View style={[styles.dropdownContainerHeader, { borderColor: themes[theme].separatorColor }]}>
<View style={styles.sortItemContainer}>
<CustomIcon style={[styles.sortIcon, { color: themes[theme].auxiliaryText }]} size={22} name='sort' />
<Text style={[styles.sortToggleText, { color: themes[theme].auxiliaryText }]}>{I18n.t('Sorting_by', { key: I18n.t(sortBy === 'alphabetical' ? 'name' : 'activity') })}</Text>
</View>
</View>
</Touch>
<SortItemButton onPress={this.sortByName} theme={theme}>
<SortItemContent
icon='sort-az'
label='Alphabetical'
checked={sortBy === 'alphabetical'}
theme={theme}
/>
</SortItemButton>
<SortItemButton onPress={this.sortByActivity} theme={theme}>
<SortItemContent
icon='clock'
label='Activity'
checked={sortBy === 'activity'}
theme={theme}
/>
</SortItemButton>
<View style={[styles.sortSeparator, { backgroundColor: themes[theme].separatorColor }]} />
<SortItemButton onPress={this.toggleGroupByType} theme={theme}>
<SortItemContent
icon='group-by-type'
label='Group_by_type'
checked={groupByType}
theme={theme}
/>
</SortItemButton>
<SortItemButton onPress={this.toggleGroupByFavorites} theme={theme}>
<SortItemContent
icon='star'
label='Group_by_favorites'
checked={showFavorites}
theme={theme}
/>
</SortItemButton>
<SortItemButton onPress={this.toggleUnread} theme={theme}>
<SortItemContent
icon='unread-on-top-disabled'
label='Unread_on_top'
checked={showUnread}
theme={theme}
/>
</SortItemButton>
translateTitle={false}
/>
<List.Separator />
<List.Item
title='Alphabetical'
left={() => <List.Icon name='sort-az' />}
color={themes[theme].auxiliaryText}
onPress={this.sortByName}
right={() => (sortBy === 'alphabetical' ? this.renderCheck() : null)}
/>
<List.Item