[IMPROVEMENT] Support badge number on header buttons (#2566)
* Beginning header buttons refactor * Add HeaderButtons * item with title * Refactor * Remove lib * Refactor * Update snapshot * Refactor * Update tests * Lint
This commit is contained in:
parent
7cccd02cb3
commit
81bb89da6c
File diff suppressed because it is too large
Load Diff
|
@ -12,6 +12,7 @@ export const SWITCH_TRACK_COLOR = {
|
||||||
|
|
||||||
const mentions = {
|
const mentions = {
|
||||||
unreadBackground: '#6C727A',
|
unreadBackground: '#6C727A',
|
||||||
|
tunreadBackground: '#1d74f5',
|
||||||
mentionMeColor: '#DB0C27',
|
mentionMeColor: '#DB0C27',
|
||||||
mentionMeBackground: '#F5455C',
|
mentionMeBackground: '#F5455C',
|
||||||
mentionGroupColor: '#E26D0E',
|
mentionGroupColor: '#E26D0E',
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { View, StyleSheet } from 'react-native';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
import { themedHeader } from '../../utils/navigation';
|
import { themedHeader } from '../../utils/navigation';
|
||||||
import { isIOS, isTablet } from '../../utils/deviceInfo';
|
import { isIOS, isTablet } from '../../utils/deviceInfo';
|
||||||
|
import { withTheme } from '../../theme';
|
||||||
|
|
||||||
// Get from https://github.com/react-navigation/react-navigation/blob/master/packages/stack/src/views/Header/HeaderSegment.tsx#L69
|
// Get from https://github.com/react-navigation/react-navigation/blob/master/packages/stack/src/views/Header/HeaderSegment.tsx#L69
|
||||||
export const headerHeight = isIOS ? 44 : 56;
|
export const headerHeight = isIOS ? 44 : 56;
|
||||||
|
@ -53,4 +54,4 @@ Header.propTypes = {
|
||||||
headerRight: PropTypes.element
|
headerRight: PropTypes.element
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Header;
|
export default withTheme(Header);
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { HeaderButtons, HeaderButton, Item } from 'react-navigation-header-buttons';
|
|
||||||
|
|
||||||
import { CustomIcon } from '../lib/Icons';
|
|
||||||
import { isIOS } from '../utils/deviceInfo';
|
|
||||||
import { themes } from '../constants/colors';
|
|
||||||
import I18n from '../i18n';
|
|
||||||
import { withTheme } from '../theme';
|
|
||||||
|
|
||||||
export const headerIconSize = 23;
|
|
||||||
|
|
||||||
const CustomHeaderButton = React.memo(withTheme(({ theme, ...props }) => (
|
|
||||||
<HeaderButton
|
|
||||||
{...props}
|
|
||||||
IconComponent={CustomIcon}
|
|
||||||
iconSize={headerIconSize}
|
|
||||||
color={themes[theme].headerTintColor}
|
|
||||||
/>
|
|
||||||
)));
|
|
||||||
|
|
||||||
export const CustomHeaderButtons = React.memo(props => (
|
|
||||||
<HeaderButtons
|
|
||||||
HeaderButtonComponent={CustomHeaderButton}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
|
|
||||||
export const DrawerButton = React.memo(({ navigation, testID, ...otherProps }) => (
|
|
||||||
<CustomHeaderButtons left>
|
|
||||||
<Item title='drawer' iconName='hamburguer' onPress={navigation.toggleDrawer} testID={testID} {...otherProps} />
|
|
||||||
</CustomHeaderButtons>
|
|
||||||
));
|
|
||||||
|
|
||||||
export const CloseModalButton = React.memo(({
|
|
||||||
navigation, testID, onPress = () => navigation.pop(), ...props
|
|
||||||
}) => (
|
|
||||||
<CustomHeaderButtons left>
|
|
||||||
<Item title='close' iconName='close' onPress={onPress} testID={testID} {...props} />
|
|
||||||
</CustomHeaderButtons>
|
|
||||||
));
|
|
||||||
|
|
||||||
export const CancelModalButton = React.memo(({ onPress, testID }) => (
|
|
||||||
<CustomHeaderButtons left>
|
|
||||||
{isIOS
|
|
||||||
? <Item title={I18n.t('Cancel')} onPress={onPress} testID={testID} />
|
|
||||||
: <Item title='close' iconName='close' onPress={onPress} testID={testID} />
|
|
||||||
}
|
|
||||||
</CustomHeaderButtons>
|
|
||||||
));
|
|
||||||
|
|
||||||
export const MoreButton = React.memo(({ onPress, testID }) => (
|
|
||||||
<CustomHeaderButtons>
|
|
||||||
<Item title='more' iconName='kebab' onPress={onPress} testID={testID} />
|
|
||||||
</CustomHeaderButtons>
|
|
||||||
));
|
|
||||||
|
|
||||||
export const SaveButton = React.memo(({ onPress, testID, ...props }) => (
|
|
||||||
<CustomHeaderButtons>
|
|
||||||
<Item title='save' iconName='download' onPress={onPress} testID={testID} {...props} />
|
|
||||||
</CustomHeaderButtons>
|
|
||||||
));
|
|
||||||
|
|
||||||
export const PreferencesButton = React.memo(({ onPress, testID, ...props }) => (
|
|
||||||
<CustomHeaderButtons>
|
|
||||||
<Item title='preferences' iconName='settings' onPress={onPress} testID={testID} {...props} />
|
|
||||||
</CustomHeaderButtons>
|
|
||||||
));
|
|
||||||
|
|
||||||
export const LegalButton = React.memo(({ navigation, testID }) => (
|
|
||||||
<MoreButton onPress={() => navigation.navigate('LegalView')} testID={testID} />
|
|
||||||
));
|
|
||||||
|
|
||||||
CustomHeaderButton.propTypes = {
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
DrawerButton.propTypes = {
|
|
||||||
navigation: PropTypes.object.isRequired,
|
|
||||||
testID: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
CloseModalButton.propTypes = {
|
|
||||||
navigation: PropTypes.object.isRequired,
|
|
||||||
testID: PropTypes.string.isRequired,
|
|
||||||
onPress: PropTypes.func
|
|
||||||
};
|
|
||||||
CancelModalButton.propTypes = {
|
|
||||||
onPress: PropTypes.func.isRequired,
|
|
||||||
testID: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
MoreButton.propTypes = {
|
|
||||||
onPress: PropTypes.func.isRequired,
|
|
||||||
testID: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
SaveButton.propTypes = {
|
|
||||||
onPress: PropTypes.func.isRequired,
|
|
||||||
testID: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
PreferencesButton.propTypes = {
|
|
||||||
onPress: PropTypes.func.isRequired,
|
|
||||||
testID: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
LegalButton.propTypes = {
|
|
||||||
navigation: PropTypes.object.isRequired,
|
|
||||||
testID: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export { Item };
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import { isIOS } from '../../utils/deviceInfo';
|
||||||
|
import I18n from '../../i18n';
|
||||||
|
import Container from './HeaderButtonContainer';
|
||||||
|
import Item from './HeaderButtonItem';
|
||||||
|
|
||||||
|
// Left
|
||||||
|
export const Drawer = React.memo(({ navigation, testID, ...props }) => (
|
||||||
|
<Container left>
|
||||||
|
<Item iconName='hamburguer' onPress={() => navigation.toggleDrawer()} testID={testID} {...props} />
|
||||||
|
</Container>
|
||||||
|
));
|
||||||
|
|
||||||
|
export const CloseModal = React.memo(({
|
||||||
|
navigation, testID, onPress = () => navigation.pop(), ...props
|
||||||
|
}) => (
|
||||||
|
<Container left>
|
||||||
|
<Item iconName='close' onPress={onPress} testID={testID} {...props} />
|
||||||
|
</Container>
|
||||||
|
));
|
||||||
|
|
||||||
|
export const CancelModal = React.memo(({ onPress, testID }) => (
|
||||||
|
<Container left>
|
||||||
|
{isIOS
|
||||||
|
? <Item title={I18n.t('Cancel')} onPress={onPress} testID={testID} />
|
||||||
|
: <Item iconName='close' onPress={onPress} testID={testID} />
|
||||||
|
}
|
||||||
|
</Container>
|
||||||
|
));
|
||||||
|
|
||||||
|
// Right
|
||||||
|
export const More = React.memo(({ onPress, testID }) => (
|
||||||
|
<Container>
|
||||||
|
<Item iconName='kebab' onPress={onPress} testID={testID} />
|
||||||
|
</Container>
|
||||||
|
));
|
||||||
|
|
||||||
|
export const Download = React.memo(({ onPress, testID, ...props }) => (
|
||||||
|
<Container>
|
||||||
|
<Item iconName='download' onPress={onPress} testID={testID} {...props} />
|
||||||
|
</Container>
|
||||||
|
));
|
||||||
|
|
||||||
|
export const Preferences = React.memo(({ onPress, testID, ...props }) => (
|
||||||
|
<Container>
|
||||||
|
<Item iconName='settings' onPress={onPress} testID={testID} {...props} />
|
||||||
|
</Container>
|
||||||
|
));
|
||||||
|
|
||||||
|
export const Legal = React.memo(({ navigation, testID }) => (
|
||||||
|
<More onPress={() => navigation.navigate('LegalView')} testID={testID} />
|
||||||
|
));
|
||||||
|
|
||||||
|
Drawer.propTypes = {
|
||||||
|
navigation: PropTypes.object.isRequired,
|
||||||
|
testID: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
CloseModal.propTypes = {
|
||||||
|
navigation: PropTypes.object.isRequired,
|
||||||
|
testID: PropTypes.string.isRequired,
|
||||||
|
onPress: PropTypes.func
|
||||||
|
};
|
||||||
|
CancelModal.propTypes = {
|
||||||
|
onPress: PropTypes.func.isRequired,
|
||||||
|
testID: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
More.propTypes = {
|
||||||
|
onPress: PropTypes.func.isRequired,
|
||||||
|
testID: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
Download.propTypes = {
|
||||||
|
onPress: PropTypes.func.isRequired,
|
||||||
|
testID: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
Preferences.propTypes = {
|
||||||
|
onPress: PropTypes.func.isRequired,
|
||||||
|
testID: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
Legal.propTypes = {
|
||||||
|
navigation: PropTypes.object.isRequired,
|
||||||
|
testID: PropTypes.string.isRequired
|
||||||
|
};
|
|
@ -0,0 +1,36 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { View, StyleSheet } from 'react-native';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
marginLeft: 5
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
marginRight: 5
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const Container = ({ children, left }) => (
|
||||||
|
<View style={[styles.container, left ? styles.left : styles.right]}>
|
||||||
|
{children}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
Container.propTypes = {
|
||||||
|
children: PropTypes.arrayOf(PropTypes.element),
|
||||||
|
left: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
Container.defaultProps = {
|
||||||
|
left: false
|
||||||
|
};
|
||||||
|
|
||||||
|
Container.displayName = 'HeaderButton.Container';
|
||||||
|
|
||||||
|
export default Container;
|
|
@ -0,0 +1,58 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text, StyleSheet, Platform } from 'react-native';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
|
||||||
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
|
import { withTheme } from '../../theme';
|
||||||
|
import { themes } from '../../constants/colors';
|
||||||
|
import sharedStyles from '../../views/Styles';
|
||||||
|
|
||||||
|
export const BUTTON_HIT_SLOP = {
|
||||||
|
top: 5, right: 5, bottom: 5, left: 5
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
marginHorizontal: 6
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
...Platform.select({
|
||||||
|
android: {
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
default: {
|
||||||
|
fontSize: 17
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
...sharedStyles.textRegular
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const Item = ({
|
||||||
|
title, iconName, onPress, testID, theme, badge
|
||||||
|
}) => (
|
||||||
|
<Touchable onPress={onPress} testID={testID} hitSlop={BUTTON_HIT_SLOP} style={styles.container}>
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
iconName
|
||||||
|
? <CustomIcon name={iconName} size={24} color={themes[theme].headerTintColor} />
|
||||||
|
: <Text style={[styles.title, { color: themes[theme].headerTintColor }]}>{title}</Text>
|
||||||
|
}
|
||||||
|
{badge ? badge() : null}
|
||||||
|
</>
|
||||||
|
</Touchable>
|
||||||
|
);
|
||||||
|
|
||||||
|
Item.propTypes = {
|
||||||
|
onPress: PropTypes.func.isRequired,
|
||||||
|
title: PropTypes.string,
|
||||||
|
iconName: PropTypes.string,
|
||||||
|
testID: PropTypes.string,
|
||||||
|
theme: PropTypes.string,
|
||||||
|
badge: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
Item.displayName = 'HeaderButton.Item';
|
||||||
|
|
||||||
|
export default withTheme(Item);
|
|
@ -0,0 +1,26 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
import UnreadBadge from '../../presentation/UnreadBadge';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
badgeContainer: {
|
||||||
|
padding: 2,
|
||||||
|
position: 'absolute',
|
||||||
|
right: -3,
|
||||||
|
top: -3,
|
||||||
|
borderRadius: 10,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Badge = ({ ...props }) => (
|
||||||
|
<UnreadBadge
|
||||||
|
{...props}
|
||||||
|
style={styles.badgeContainer}
|
||||||
|
small
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Badge;
|
|
@ -0,0 +1,4 @@
|
||||||
|
export { default as Container } from './HeaderButtonContainer';
|
||||||
|
export { default as Item } from './HeaderButtonItem';
|
||||||
|
export { default as Badge } from './HeaderButtonItemBadge';
|
||||||
|
export * from './Common';
|
|
@ -15,7 +15,7 @@ import SafeAreaView from '../../../containers/SafeAreaView';
|
||||||
import { themes } from '../../../constants/colors';
|
import { themes } from '../../../constants/colors';
|
||||||
import StatusBar from '../../../containers/StatusBar';
|
import StatusBar from '../../../containers/StatusBar';
|
||||||
import { goRoom } from '../../../utils/goRoom';
|
import { goRoom } from '../../../utils/goRoom';
|
||||||
import { CloseModalButton } from '../../../containers/HeaderButton';
|
import * as HeaderButton from '../../../containers/HeaderButton';
|
||||||
import RocketChat from '../../../lib/rocketchat';
|
import RocketChat from '../../../lib/rocketchat';
|
||||||
import { logEvent, events } from '../../../utils/log';
|
import { logEvent, events } from '../../../utils/log';
|
||||||
import { getInquiryQueueSelector } from '../selectors/inquiry';
|
import { getInquiryQueueSelector } from '../selectors/inquiry';
|
||||||
|
@ -34,7 +34,7 @@ class QueueListView extends React.Component {
|
||||||
title: I18n.t('Queued_chats')
|
title: I18n.t('Queued_chats')
|
||||||
};
|
};
|
||||||
if (isMasterDetail) {
|
if (isMasterDetail) {
|
||||||
options.headerLeft = () => <CloseModalButton navigation={navigation} testID='directory-view-close' />;
|
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} testID='directory-view-close' />;
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ const RoomItem = ({
|
||||||
alert,
|
alert,
|
||||||
hideUnreadStatus,
|
hideUnreadStatus,
|
||||||
unread,
|
unread,
|
||||||
|
tunread,
|
||||||
userMentions,
|
userMentions,
|
||||||
groupMentions,
|
groupMentions,
|
||||||
roomUpdatedAt,
|
roomUpdatedAt,
|
||||||
|
@ -112,6 +113,7 @@ const RoomItem = ({
|
||||||
/>
|
/>
|
||||||
<UnreadBadge
|
<UnreadBadge
|
||||||
unread={unread}
|
unread={unread}
|
||||||
|
tunread={tunread}
|
||||||
userMentions={userMentions}
|
userMentions={userMentions}
|
||||||
groupMentions={groupMentions}
|
groupMentions={groupMentions}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
@ -136,6 +138,7 @@ const RoomItem = ({
|
||||||
/>
|
/>
|
||||||
<UnreadBadge
|
<UnreadBadge
|
||||||
unread={unread}
|
unread={unread}
|
||||||
|
tunread={tunread}
|
||||||
userMentions={userMentions}
|
userMentions={userMentions}
|
||||||
groupMentions={groupMentions}
|
groupMentions={groupMentions}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
@ -174,6 +177,7 @@ RoomItem.propTypes = {
|
||||||
alert: PropTypes.bool,
|
alert: PropTypes.bool,
|
||||||
hideUnreadStatus: PropTypes.bool,
|
hideUnreadStatus: PropTypes.bool,
|
||||||
unread: PropTypes.number,
|
unread: PropTypes.number,
|
||||||
|
tunread: PropTypes.array,
|
||||||
userMentions: PropTypes.number,
|
userMentions: PropTypes.number,
|
||||||
groupMentions: PropTypes.number,
|
groupMentions: PropTypes.number,
|
||||||
roomUpdatedAt: PropTypes.instanceOf(Date),
|
roomUpdatedAt: PropTypes.instanceOf(Date),
|
||||||
|
|
|
@ -228,6 +228,7 @@ class RoomItemContainer extends React.Component {
|
||||||
username={username}
|
username={username}
|
||||||
useRealName={useRealName}
|
useRealName={useRealName}
|
||||||
unread={item.unread}
|
unread={item.unread}
|
||||||
|
tunread={item.tunread}
|
||||||
groupMentions={item.groupMentions}
|
groupMentions={item.groupMentions}
|
||||||
avatarETag={avatarETag || item.avatarETag}
|
avatarETag={avatarETag || item.avatarETag}
|
||||||
swipeEnabled={swipeEnabled}
|
swipeEnabled={swipeEnabled}
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { View, Text, StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import sharedStyles from '../views/Styles';
|
|
||||||
import { themes } from '../constants/colors';
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
unreadNumberContainer: {
|
|
||||||
minWidth: 21,
|
|
||||||
height: 21,
|
|
||||||
paddingVertical: 3,
|
|
||||||
paddingHorizontal: 5,
|
|
||||||
borderRadius: 10.5,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
marginLeft: 10
|
|
||||||
},
|
|
||||||
unreadText: {
|
|
||||||
overflow: 'hidden',
|
|
||||||
fontSize: 13,
|
|
||||||
...sharedStyles.textMedium,
|
|
||||||
letterSpacing: 0.56,
|
|
||||||
textAlign: 'center'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const UnreadBadge = React.memo(({
|
|
||||||
theme, unread, userMentions, groupMentions, style
|
|
||||||
}) => {
|
|
||||||
if (!unread || unread <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (unread >= 1000) {
|
|
||||||
unread = '999+';
|
|
||||||
}
|
|
||||||
|
|
||||||
let backgroundColor = themes[theme].unreadBackground;
|
|
||||||
const color = themes[theme].buttonText;
|
|
||||||
if (userMentions > 0) {
|
|
||||||
backgroundColor = themes[theme].mentionMeBackground;
|
|
||||||
} else if (groupMentions > 0) {
|
|
||||||
backgroundColor = themes[theme].mentionGroupBackground;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
styles.unreadNumberContainer,
|
|
||||||
{ backgroundColor },
|
|
||||||
style
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={[
|
|
||||||
styles.unreadText,
|
|
||||||
{ color }
|
|
||||||
]}
|
|
||||||
>{unread}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
UnreadBadge.propTypes = {
|
|
||||||
theme: PropTypes.string,
|
|
||||||
unread: PropTypes.number,
|
|
||||||
userMentions: PropTypes.number,
|
|
||||||
groupMentions: PropTypes.number,
|
|
||||||
style: PropTypes.object
|
|
||||||
};
|
|
||||||
|
|
||||||
export default UnreadBadge;
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
|
export const getUnreadStyle = ({
|
||||||
|
unread, userMentions, groupMentions, theme, tunread, tunreadUser, tunreadGroup
|
||||||
|
}) => {
|
||||||
|
if ((!unread || unread <= 0) && (!tunread?.length)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
let backgroundColor = themes[theme].unreadBackground;
|
||||||
|
const color = themes[theme].buttonText;
|
||||||
|
if (userMentions > 0 || tunreadUser?.length) {
|
||||||
|
backgroundColor = themes[theme].mentionMeColor;
|
||||||
|
} else if (groupMentions > 0 || tunreadGroup?.length) {
|
||||||
|
backgroundColor = themes[theme].mentionGroupColor;
|
||||||
|
} else if (tunread?.length > 0) {
|
||||||
|
backgroundColor = themes[theme].tunreadBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
backgroundColor, color
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
import { themes } from '../../constants/colors';
|
||||||
|
import { getUnreadStyle } from './getUnreadStyle';
|
||||||
|
|
||||||
|
const testsForTheme = (theme) => {
|
||||||
|
const getUnreadStyleUtil = ({ ...props }) => getUnreadStyle({ theme, ...props });
|
||||||
|
|
||||||
|
test('render unread', () => {
|
||||||
|
expect(getUnreadStyleUtil({
|
||||||
|
unread: 1
|
||||||
|
})).toEqual({
|
||||||
|
backgroundColor: themes[theme].unreadBackground,
|
||||||
|
color: themes[theme].buttonText
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('render thread unread', () => {
|
||||||
|
expect(getUnreadStyleUtil({
|
||||||
|
tunread: [1]
|
||||||
|
})).toEqual({
|
||||||
|
backgroundColor: themes[theme].tunreadBackground,
|
||||||
|
color: themes[theme].buttonText
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('render user mention', () => {
|
||||||
|
expect(getUnreadStyleUtil({
|
||||||
|
unread: 1,
|
||||||
|
userMentions: 1
|
||||||
|
})).toEqual({
|
||||||
|
backgroundColor: themes[theme].mentionMeColor,
|
||||||
|
color: themes[theme].buttonText
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('render group mention', () => {
|
||||||
|
expect(getUnreadStyleUtil({
|
||||||
|
unread: 1,
|
||||||
|
groupMentions: 1
|
||||||
|
})).toEqual({
|
||||||
|
backgroundColor: themes[theme].mentionGroupColor,
|
||||||
|
color: themes[theme].buttonText
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('mentions priority', () => {
|
||||||
|
expect(getUnreadStyleUtil({
|
||||||
|
unread: 1,
|
||||||
|
userMentions: 1,
|
||||||
|
groupMentions: 1,
|
||||||
|
tunread: [1]
|
||||||
|
})).toEqual({
|
||||||
|
backgroundColor: themes[theme].mentionMeColor,
|
||||||
|
color: themes[theme].buttonText
|
||||||
|
});
|
||||||
|
expect(getUnreadStyleUtil({
|
||||||
|
unread: 1,
|
||||||
|
groupMentions: 1,
|
||||||
|
tunread: [1]
|
||||||
|
})).toEqual({
|
||||||
|
backgroundColor: themes[theme].mentionGroupColor,
|
||||||
|
color: themes[theme].buttonText
|
||||||
|
});
|
||||||
|
expect(getUnreadStyleUtil({
|
||||||
|
unread: 1,
|
||||||
|
tunread: [1]
|
||||||
|
})).toEqual({
|
||||||
|
backgroundColor: themes[theme].tunreadBackground,
|
||||||
|
color: themes[theme].buttonText
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('getUnreadStyle light theme', () => testsForTheme('light'));
|
||||||
|
describe('getUnreadStyle dark theme', () => testsForTheme('dark'));
|
||||||
|
describe('getUnreadStyle black theme', () => testsForTheme('black'));
|
|
@ -0,0 +1,95 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { View, Text, StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
import sharedStyles from '../../views/Styles';
|
||||||
|
import { getUnreadStyle } from './getUnreadStyle';
|
||||||
|
import { withTheme } from '../../theme';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
unreadNumberContainerNormal: {
|
||||||
|
height: 21,
|
||||||
|
paddingVertical: 3,
|
||||||
|
paddingHorizontal: 5,
|
||||||
|
borderRadius: 10.5,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginLeft: 10
|
||||||
|
},
|
||||||
|
unreadNumberContainerSmall: {
|
||||||
|
borderRadius: 10.5,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
},
|
||||||
|
unreadText: {
|
||||||
|
// overflow: 'hidden',
|
||||||
|
fontSize: 13,
|
||||||
|
...sharedStyles.textSemibold,
|
||||||
|
fontWeight: '600'
|
||||||
|
},
|
||||||
|
textSmall: {
|
||||||
|
fontSize: 10
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const UnreadBadge = React.memo(({
|
||||||
|
theme, unread, userMentions, groupMentions, style, tunread, tunreadUser, tunreadGroup, small
|
||||||
|
}) => {
|
||||||
|
if ((!unread || unread <= 0) && (!tunread?.length)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { backgroundColor, color } = getUnreadStyle({
|
||||||
|
theme, unread, userMentions, groupMentions, tunread, tunreadUser, tunreadGroup
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!backgroundColor) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let text = unread || tunread?.length;
|
||||||
|
if (small && text >= 100) {
|
||||||
|
text = '+99';
|
||||||
|
}
|
||||||
|
if (!small && text >= 1000) {
|
||||||
|
text = '+999';
|
||||||
|
}
|
||||||
|
text = text.toString();
|
||||||
|
|
||||||
|
let minWidth = 21;
|
||||||
|
if (small) {
|
||||||
|
minWidth = 11 + text.length * 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
small ? styles.unreadNumberContainerSmall : styles.unreadNumberContainerNormal,
|
||||||
|
{ backgroundColor, minWidth },
|
||||||
|
style
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.unreadText,
|
||||||
|
small && styles.textSmall,
|
||||||
|
{ color }
|
||||||
|
]}
|
||||||
|
numberOfLines={1}
|
||||||
|
>{text}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
UnreadBadge.propTypes = {
|
||||||
|
theme: PropTypes.string,
|
||||||
|
unread: PropTypes.number,
|
||||||
|
userMentions: PropTypes.number,
|
||||||
|
groupMentions: PropTypes.number,
|
||||||
|
style: PropTypes.object,
|
||||||
|
tunread: PropTypes.array,
|
||||||
|
tunreadUser: PropTypes.array,
|
||||||
|
tunreadGroup: PropTypes.array,
|
||||||
|
small: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withTheme(UnreadBadge);
|
|
@ -5,14 +5,14 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import { DrawerButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import { getUserSelector } from '../../selectors/login';
|
import { getUserSelector } from '../../selectors/login';
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
|
|
||||||
class AdminPanelView extends React.Component {
|
class AdminPanelView extends React.Component {
|
||||||
static navigationOptions = ({ navigation, isMasterDetail }) => ({
|
static navigationOptions = ({ navigation, isMasterDetail }) => ({
|
||||||
headerLeft: isMasterDetail ? undefined : () => <DrawerButton navigation={navigation} />,
|
headerLeft: isMasterDetail ? undefined : () => <HeaderButton.Drawer navigation={navigation} />,
|
||||||
title: I18n.t('Admin_Panel')
|
title: I18n.t('Admin_Panel')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { ImageViewer } from '../presentation/ImageViewer';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import { formatAttachmentUrl } from '../lib/utils';
|
import { formatAttachmentUrl } from '../lib/utils';
|
||||||
import RCActivityIndicator from '../containers/ActivityIndicator';
|
import RCActivityIndicator from '../containers/ActivityIndicator';
|
||||||
import { SaveButton, CloseModalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import { isAndroid } from '../utils/deviceInfo';
|
import { isAndroid } from '../utils/deviceInfo';
|
||||||
import { getUserSelector } from '../selectors/login';
|
import { getUserSelector } from '../selectors/login';
|
||||||
import { withDimensions } from '../dimensions';
|
import { withDimensions } from '../dimensions';
|
||||||
|
@ -81,10 +81,10 @@ class AttachmentView extends React.Component {
|
||||||
}
|
}
|
||||||
const options = {
|
const options = {
|
||||||
title,
|
title,
|
||||||
headerLeft: () => <CloseModalButton testID='close-attachment-view' navigation={navigation} buttonStyle={{ color: themes[theme].previewTintColor }} />,
|
headerLeft: () => <HeaderButton.CloseModal testID='close-attachment-view' navigation={navigation} buttonStyle={{ color: themes[theme].previewTintColor }} />,
|
||||||
headerRight: () => (
|
headerRight: () => (
|
||||||
Allow_Save_Media_to_Gallery
|
Allow_Save_Media_to_Gallery
|
||||||
? <SaveButton testID='save-image' onPress={this.handleSave} buttonStyle={{ color: themes[theme].previewTintColor }} />
|
? <HeaderButton.Download testID='save-image' onPress={this.handleSave} buttonStyle={{ color: themes[theme].previewTintColor }} />
|
||||||
: null
|
: null
|
||||||
),
|
),
|
||||||
headerBackground: () => <View style={{ flex: 1, backgroundColor: themes[theme].previewBackground }} />,
|
headerBackground: () => <View style={{ flex: 1, backgroundColor: themes[theme].previewBackground }} />,
|
||||||
|
|
|
@ -10,7 +10,7 @@ import StatusBar from '../containers/StatusBar';
|
||||||
import ActivityIndicator from '../containers/ActivityIndicator';
|
import ActivityIndicator from '../containers/ActivityIndicator';
|
||||||
import { withTheme } from '../theme';
|
import { withTheme } from '../theme';
|
||||||
import debounce from '../utils/debounce';
|
import debounce from '../utils/debounce';
|
||||||
import { CloseModalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
|
|
||||||
const userAgent = isIOS
|
const userAgent = isIOS
|
||||||
? 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1'
|
? 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1'
|
||||||
|
@ -185,7 +185,7 @@ const mapStateToProps = state => ({
|
||||||
AuthenticationWebView.navigationOptions = ({ route, navigation }) => {
|
AuthenticationWebView.navigationOptions = ({ route, navigation }) => {
|
||||||
const { authType } = route.params;
|
const { authType } = route.params;
|
||||||
return {
|
return {
|
||||||
headerLeft: () => <CloseModalButton navigation={navigation} />,
|
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} />,
|
||||||
title: ['saml', 'cas', 'iframe'].includes(authType) ? 'SSO' : 'OAuth'
|
title: ['saml', 'cas', 'iframe'].includes(authType) ? 'SSO' : 'OAuth'
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@ import KeyboardView from '../presentation/KeyboardView';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import UserItem from '../presentation/UserItem';
|
import UserItem from '../presentation/UserItem';
|
||||||
import { CustomHeaderButtons, Item } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
import { SWITCH_TRACK_COLOR, themes } from '../constants/colors';
|
import { SWITCH_TRACK_COLOR, themes } from '../constants/colors';
|
||||||
import { withTheme } from '../theme';
|
import { withTheme } from '../theme';
|
||||||
|
@ -143,9 +143,9 @@ class CreateChannelView extends React.Component {
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerRight: () => channelName.trim().length > 0 && (
|
headerRight: () => channelName.trim().length > 0 && (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item title={I18n.t('Create')} onPress={this.submit} testID='create-channel-submit' />
|
<HeaderButton.Item title={I18n.t('Create')} onPress={this.submit} testID='create-channel-submit' />
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import Loading from '../../containers/Loading';
|
||||||
import KeyboardView from '../../presentation/KeyboardView';
|
import KeyboardView from '../../presentation/KeyboardView';
|
||||||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { CustomHeaderButtons, Item, CloseModalButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
|
@ -96,13 +96,13 @@ class CreateChannelView extends React.Component {
|
||||||
headerRight: (
|
headerRight: (
|
||||||
this.valid()
|
this.valid()
|
||||||
? () => (
|
? () => (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item title={I18n.t('Create')} onPress={this.submit} testID='create-discussion-submit' />
|
<HeaderButton.Item title={I18n.t('Create')} onPress={this.submit} testID='create-discussion-submit' />
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
),
|
),
|
||||||
headerLeft: showCloseModal ? () => <CloseModalButton navigation={navigation} /> : undefined
|
headerLeft: showCloseModal ? () => <HeaderButton.CloseModal navigation={navigation} /> : undefined
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import SearchBox from '../../containers/SearchBox';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import debounce from '../../utils/debounce';
|
import debounce from '../../utils/debounce';
|
||||||
import log, { logEvent, events } from '../../utils/log';
|
import log, { logEvent, events } from '../../utils/log';
|
||||||
import Options from './Options';
|
import Options from './Options';
|
||||||
|
@ -31,7 +31,7 @@ class DirectoryView extends React.Component {
|
||||||
title: I18n.t('Directory')
|
title: I18n.t('Directory')
|
||||||
};
|
};
|
||||||
if (isMasterDetail) {
|
if (isMasterDetail) {
|
||||||
options.headerLeft = () => <CloseModalButton navigation={navigation} testID='directory-view-close' />;
|
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} testID='directory-view-close' />;
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Button from '../containers/Button';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import TextInput from '../containers/TextInput';
|
import TextInput from '../containers/TextInput';
|
||||||
import SafeAreaView from '../containers/SafeAreaView';
|
import SafeAreaView from '../containers/SafeAreaView';
|
||||||
import { CloseModalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import { encryptionDecodeKey as encryptionDecodeKeyAction } from '../actions/encryption';
|
import { encryptionDecodeKey as encryptionDecodeKeyAction } from '../actions/encryption';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
import KeyboardView from '../presentation/KeyboardView';
|
import KeyboardView from '../presentation/KeyboardView';
|
||||||
|
@ -29,7 +29,7 @@ const styles = StyleSheet.create({
|
||||||
});
|
});
|
||||||
class E2EEnterYourPasswordView extends React.Component {
|
class E2EEnterYourPasswordView extends React.Component {
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
headerLeft: () => <CloseModalButton navigation={navigation} testID='e2e-enter-your-password-view-close' />,
|
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} testID='e2e-enter-your-password-view-close' />,
|
||||||
title: I18n.t('Enter_Your_E2E_Password')
|
title: I18n.t('Enter_Your_E2E_Password')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
import SafeAreaView from '../containers/SafeAreaView';
|
import SafeAreaView from '../containers/SafeAreaView';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import { CloseModalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import Markdown from '../containers/markdown';
|
import Markdown from '../containers/markdown';
|
||||||
import { withTheme } from '../theme';
|
import { withTheme } from '../theme';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
|
@ -26,7 +26,7 @@ class E2EHowItWorksView extends React.Component {
|
||||||
const showCloseModal = route.params?.showCloseModal;
|
const showCloseModal = route.params?.showCloseModal;
|
||||||
return {
|
return {
|
||||||
title: I18n.t('How_It_Works'),
|
title: I18n.t('How_It_Works'),
|
||||||
headerLeft: showCloseModal ? () => <CloseModalButton navigation={navigation} /> : undefined
|
headerLeft: showCloseModal ? () => <HeaderButton.CloseModal navigation={navigation} /> : undefined
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
|
|
||||||
import { encryptionSetBanner as encryptionSetBannerAction } from '../actions/encryption';
|
import { encryptionSetBanner as encryptionSetBannerAction } from '../actions/encryption';
|
||||||
import { E2E_RANDOM_PASSWORD_KEY } from '../lib/encryption/constants';
|
import { E2E_RANDOM_PASSWORD_KEY } from '../lib/encryption/constants';
|
||||||
import { CloseModalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
import SafeAreaView from '../containers/SafeAreaView';
|
import SafeAreaView from '../containers/SafeAreaView';
|
||||||
import UserPreferences from '../lib/userPreferences';
|
import UserPreferences from '../lib/userPreferences';
|
||||||
|
@ -61,7 +61,7 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
class E2ESaveYourPasswordView extends React.Component {
|
class E2ESaveYourPasswordView extends React.Component {
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
headerLeft: () => <CloseModalButton navigation={navigation} testID='e2e-save-your-password-view-close' />,
|
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} testID='e2e-save-your-password-view-close' />,
|
||||||
title: I18n.t('Save_Your_E2E_Password')
|
title: I18n.t('Save_Your_E2E_Password')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import equal from 'deep-equal';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import Button from '../containers/Button';
|
import Button from '../containers/Button';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import { LegalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import { withTheme } from '../theme';
|
import { withTheme } from '../theme';
|
||||||
import FormContainer, { FormContainerInner } from '../containers/FormContainer';
|
import FormContainer, { FormContainerInner } from '../containers/FormContainer';
|
||||||
|
@ -51,7 +51,7 @@ const styles = StyleSheet.create({
|
||||||
class LoginView extends React.Component {
|
class LoginView extends React.Component {
|
||||||
static navigationOptions = ({ route, navigation }) => ({
|
static navigationOptions = ({ route, navigation }) => ({
|
||||||
title: route.params?.title ?? 'Rocket.Chat',
|
title: route.params?.title ?? 'Rocket.Chat',
|
||||||
headerRight: () => <LegalButton testID='login-view-more' navigation={navigation} />
|
headerRight: () => <HeaderButton.Legal testID='login-view-more' navigation={navigation} />
|
||||||
})
|
})
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { KeyboardAwareScrollView } from '@codler/react-native-keyboard-aware-scr
|
||||||
import { withTheme } from '../theme';
|
import { withTheme } from '../theme';
|
||||||
import EventEmitter from '../utils/events';
|
import EventEmitter from '../utils/events';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import { CustomHeaderButtons, Item } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import { modalBlockWithContext } from '../containers/UIKit/MessageBlock';
|
import { modalBlockWithContext } from '../containers/UIKit/MessageBlock';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import ActivityIndicator from '../containers/ActivityIndicator';
|
import ActivityIndicator from '../containers/ActivityIndicator';
|
||||||
|
@ -128,24 +128,24 @@ class ModalBlockView extends React.Component {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
title: textParser([title]),
|
title: textParser([title]),
|
||||||
headerLeft: close ? () => (
|
headerLeft: close ? () => (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title={textParser([close.text])}
|
title={textParser([close.text])}
|
||||||
style={styles.submit}
|
style={styles.submit}
|
||||||
onPress={this.cancel}
|
onPress={this.cancel}
|
||||||
testID='close-modal-uikit'
|
testID='close-modal-uikit'
|
||||||
/>
|
/>
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
) : null,
|
) : null,
|
||||||
headerRight: submit ? () => (
|
headerRight: submit ? () => (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title={textParser([submit.text])}
|
title={textParser([submit.text])}
|
||||||
style={styles.submit}
|
style={styles.submit}
|
||||||
onPress={this.submit}
|
onPress={this.submit}
|
||||||
testID='submit-modal-uikit'
|
testID='submit-modal-uikit'
|
||||||
/>
|
/>
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
) : null
|
) : null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import I18n from '../i18n';
|
||||||
import log, { logEvent, events } from '../utils/log';
|
import log, { logEvent, events } from '../utils/log';
|
||||||
import SearchBox from '../containers/SearchBox';
|
import SearchBox from '../containers/SearchBox';
|
||||||
import { CustomIcon } from '../lib/Icons';
|
import { CustomIcon } from '../lib/Icons';
|
||||||
import { CloseModalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import { withTheme } from '../theme';
|
import { withTheme } from '../theme';
|
||||||
|
@ -51,7 +51,7 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
class NewMessageView extends React.Component {
|
class NewMessageView extends React.Component {
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
headerLeft: () => <CloseModalButton navigation={navigation} testID='new-message-view-close' />,
|
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} testID='new-message-view-close' />,
|
||||||
title: I18n.t('New_Message')
|
title: I18n.t('New_Message')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ import log, { logEvent, events } from '../../utils/log';
|
||||||
import { animateNextTransition } from '../../utils/layoutAnimation';
|
import { animateNextTransition } from '../../utils/layoutAnimation';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import { setBasicAuth, BASIC_AUTH_KEY } from '../../utils/fetch';
|
import { setBasicAuth, BASIC_AUTH_KEY } from '../../utils/fetch';
|
||||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import { showConfirmationAlert } from '../../utils/info';
|
import { showConfirmationAlert } from '../../utils/info';
|
||||||
import database from '../../lib/database';
|
import database from '../../lib/database';
|
||||||
import ServerInput from './ServerInput';
|
import ServerInput from './ServerInput';
|
||||||
|
@ -111,7 +111,7 @@ class NewServerView extends React.Component {
|
||||||
const { adding, navigation } = this.props;
|
const { adding, navigation } = this.props;
|
||||||
if (adding) {
|
if (adding) {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerLeft: () => <CloseModalButton navigation={navigation} onPress={this.close} testID='new-server-view-close' />
|
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} onPress={this.close} testID='new-server-view-close' />
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import Button from '../../containers/Button';
|
||||||
import Avatar from '../../containers/Avatar';
|
import Avatar from '../../containers/Avatar';
|
||||||
import { setUser as setUserAction } from '../../actions/login';
|
import { setUser as setUserAction } from '../../actions/login';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
import { DrawerButton, PreferencesButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
|
@ -37,10 +37,10 @@ class ProfileView extends React.Component {
|
||||||
title: I18n.t('Profile')
|
title: I18n.t('Profile')
|
||||||
};
|
};
|
||||||
if (!isMasterDetail) {
|
if (!isMasterDetail) {
|
||||||
options.headerLeft = () => <DrawerButton navigation={navigation} />;
|
options.headerLeft = () => <HeaderButton.Drawer navigation={navigation} />;
|
||||||
}
|
}
|
||||||
options.headerRight = () => (
|
options.headerRight = () => (
|
||||||
<PreferencesButton onPress={() => navigation.navigate('UserPreferencesView')} testID='preferences-view-open' />
|
<HeaderButton.Preferences onPress={() => navigation.navigate('UserPreferencesView')} testID='preferences-view-open' />
|
||||||
);
|
);
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { connect } from 'react-redux';
|
||||||
import Avatar from '../../containers/Avatar';
|
import Avatar from '../../containers/Avatar';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
|
@ -22,7 +22,7 @@ class ReadReceiptView extends React.Component {
|
||||||
title: I18n.t('Read_Receipt')
|
title: I18n.t('Read_Receipt')
|
||||||
};
|
};
|
||||||
if (isMasterDetail) {
|
if (isMasterDetail) {
|
||||||
options.headerLeft = () => <CloseModalButton navigation={navigation} testID='read-receipt-view-close' />;
|
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} testID='read-receipt-view-close' />;
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import log, { logEvent, events } from '../utils/log';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import Button from '../containers/Button';
|
import Button from '../containers/Button';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import { LegalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import { withTheme } from '../theme';
|
import { withTheme } from '../theme';
|
||||||
import FormContainer, { FormContainerInner } from '../containers/FormContainer';
|
import FormContainer, { FormContainerInner } from '../containers/FormContainer';
|
||||||
|
@ -54,7 +54,7 @@ const styles = StyleSheet.create({
|
||||||
class RegisterView extends React.Component {
|
class RegisterView extends React.Component {
|
||||||
static navigationOptions = ({ route, navigation }) => ({
|
static navigationOptions = ({ route, navigation }) => ({
|
||||||
title: route.params?.title ?? 'Rocket.Chat',
|
title: route.params?.title ?? 'Rocket.Chat',
|
||||||
headerRight: () => <LegalButton testID='register-view-more' navigation={navigation} />
|
headerRight: () => <HeaderButton.Legal testID='register-view-more' navigation={navigation} />
|
||||||
});
|
});
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import I18n from '../../i18n';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import { themes, SWITCH_TRACK_COLOR } from '../../constants/colors';
|
import { themes, SWITCH_TRACK_COLOR } from '../../constants/colors';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import Markdown from '../../containers/markdown';
|
import Markdown from '../../containers/markdown';
|
||||||
import { showConfirmationAlert, showErrorAlert } from '../../utils/info';
|
import { showConfirmationAlert, showErrorAlert } from '../../utils/info';
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
|
@ -36,7 +36,7 @@ class RoomActionsView extends React.Component {
|
||||||
title: I18n.t('Actions')
|
title: I18n.t('Actions')
|
||||||
};
|
};
|
||||||
if (isMasterDetail) {
|
if (isMasterDetail) {
|
||||||
options.headerLeft = () => <CloseModalButton navigation={navigation} testID='room-actions-view-close' />;
|
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} testID='room-actions-view-close' />;
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import sharedStyles from '../Styles';
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
import RoomTypeIcon from '../../containers/RoomTypeIcon';
|
import RoomTypeIcon from '../../containers/RoomTypeIcon';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { CustomHeaderButtons, CloseModalButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import log, { logEvent, events } from '../../utils/log';
|
import log, { logEvent, events } from '../../utils/log';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
@ -26,7 +26,6 @@ import EventEmitter from '../../utils/events';
|
||||||
|
|
||||||
import Livechat from './Livechat';
|
import Livechat from './Livechat';
|
||||||
import Channel from './Channel';
|
import Channel from './Channel';
|
||||||
import Item from './Item';
|
|
||||||
import Direct from './Direct';
|
import Direct from './Direct';
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import { goRoom } from '../../utils/goRoom';
|
import { goRoom } from '../../utils/goRoom';
|
||||||
|
@ -104,12 +103,12 @@ class RoomInfoView extends React.Component {
|
||||||
const rid = route.params?.rid;
|
const rid = route.params?.rid;
|
||||||
const showCloseModal = route.params?.showCloseModal;
|
const showCloseModal = route.params?.showCloseModal;
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerLeft: showCloseModal ? () => <CloseModalButton navigation={navigation} /> : undefined,
|
headerLeft: showCloseModal ? () => <HeaderButton.CloseModal navigation={navigation} /> : undefined,
|
||||||
title: t === 'd' ? I18n.t('User_Info') : I18n.t('Room_Info'),
|
title: t === 'd' ? I18n.t('User_Info') : I18n.t('Room_Info'),
|
||||||
headerRight: showEdit
|
headerRight: showEdit
|
||||||
? () => (
|
? () => (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
iconName='edit'
|
iconName='edit'
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
const isLivechat = t === 'l';
|
const isLivechat = t === 'l';
|
||||||
|
@ -118,7 +117,7 @@ class RoomInfoView extends React.Component {
|
||||||
}}
|
}}
|
||||||
testID='room-info-view-edit-button'
|
testID='room-info-view-edit-button'
|
||||||
/>
|
/>
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,7 +15,7 @@ import log from '../../utils/log';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import SearchBox from '../../containers/SearchBox';
|
import SearchBox from '../../containers/SearchBox';
|
||||||
import protectedFunction from '../../lib/methods/helpers/protectedFunction';
|
import protectedFunction from '../../lib/methods/helpers/protectedFunction';
|
||||||
import { CustomHeaderButtons, Item } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
|
@ -97,9 +97,9 @@ class RoomMembersView extends React.Component {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
title: I18n.t('Members'),
|
title: I18n.t('Members'),
|
||||||
headerRight: () => (
|
headerRight: () => (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item title={toggleText} onPress={this.toggleStatus} testID='room-members-view-toggle-status' />
|
<HeaderButton.Item title={toggleText} onPress={this.toggleStatus} testID='room-members-view-toggle-status' />
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,12 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { CustomHeaderButtons, Item } from '../../../containers/HeaderButton';
|
import * as HeaderButton from '../../../containers/HeaderButton';
|
||||||
import database from '../../../lib/database';
|
import database from '../../../lib/database';
|
||||||
import { getUserSelector } from '../../../selectors/login';
|
import { getUserSelector } from '../../../selectors/login';
|
||||||
import { logEvent, events } from '../../../utils/log';
|
import { logEvent, events } from '../../../utils/log';
|
||||||
|
|
||||||
|
|
||||||
class RightButtonsContainer extends React.PureComponent {
|
class RightButtonsContainer extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
userId: PropTypes.string,
|
userId: PropTypes.string,
|
||||||
|
@ -99,33 +100,30 @@ class RightButtonsContainer extends React.PureComponent {
|
||||||
}
|
}
|
||||||
if (tmid) {
|
if (tmid) {
|
||||||
return (
|
return (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title='bell'
|
|
||||||
iconName={isFollowingThread ? 'notification' : 'notification-disabled'}
|
iconName={isFollowingThread ? 'notification' : 'notification-disabled'}
|
||||||
onPress={this.toggleFollowThread}
|
onPress={this.toggleFollowThread}
|
||||||
testID={isFollowingThread ? 'room-view-header-unfollow' : 'room-view-header-follow'}
|
testID={isFollowingThread ? 'room-view-header-unfollow' : 'room-view-header-follow'}
|
||||||
/>
|
/>
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
{threadsEnabled ? (
|
{threadsEnabled ? (
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title='threads'
|
|
||||||
iconName='threads'
|
iconName='threads'
|
||||||
onPress={this.goThreadsView}
|
onPress={this.goThreadsView}
|
||||||
testID='room-view-header-threads'
|
testID='room-view-header-threads'
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title='search'
|
|
||||||
iconName='search'
|
iconName='search'
|
||||||
onPress={this.goSearchView}
|
onPress={this.goSearchView}
|
||||||
testID='room-view-search'
|
testID='room-view-search'
|
||||||
/>
|
/>
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,7 @@ import { appStart as appStartAction, ROOT_BACKGROUND } from '../../actions/app';
|
||||||
import debounce from '../../utils/debounce';
|
import debounce from '../../utils/debounce';
|
||||||
import { isIOS, isTablet } from '../../utils/deviceInfo';
|
import { isIOS, isTablet } from '../../utils/deviceInfo';
|
||||||
import RoomsListHeaderView from './Header';
|
import RoomsListHeaderView from './Header';
|
||||||
import {
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
DrawerButton,
|
|
||||||
CustomHeaderButtons,
|
|
||||||
Item
|
|
||||||
} from '../../containers/HeaderButton';
|
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import ListHeader from './ListHeader';
|
import ListHeader from './ListHeader';
|
||||||
|
@ -346,15 +342,14 @@ class RoomsListView extends React.Component {
|
||||||
return {
|
return {
|
||||||
headerTitleAlign: 'left',
|
headerTitleAlign: 'left',
|
||||||
headerLeft: () => (searching ? (
|
headerLeft: () => (searching ? (
|
||||||
<CustomHeaderButtons left>
|
<HeaderButton.Container left>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title='cancel'
|
|
||||||
iconName='close'
|
iconName='close'
|
||||||
onPress={this.cancelSearch}
|
onPress={this.cancelSearch}
|
||||||
/>
|
/>
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
) : (
|
) : (
|
||||||
<DrawerButton
|
<HeaderButton.Drawer
|
||||||
navigation={navigation}
|
navigation={navigation}
|
||||||
testID='rooms-list-view-sidebar'
|
testID='rooms-list-view-sidebar'
|
||||||
onPress={isMasterDetail
|
onPress={isMasterDetail
|
||||||
|
@ -368,26 +363,23 @@ class RoomsListView extends React.Component {
|
||||||
right: headerTitlePosition.right
|
right: headerTitlePosition.right
|
||||||
},
|
},
|
||||||
headerRight: () => (searching ? null : (
|
headerRight: () => (searching ? null : (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title='new'
|
|
||||||
iconName='create'
|
iconName='create'
|
||||||
onPress={this.goToNewMessage}
|
onPress={this.goToNewMessage}
|
||||||
testID='rooms-list-view-create-channel'
|
testID='rooms-list-view-create-channel'
|
||||||
/>
|
/>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title='search'
|
|
||||||
iconName='search'
|
iconName='search'
|
||||||
onPress={this.initSearching}
|
onPress={this.initSearching}
|
||||||
testID='rooms-list-view-search'
|
testID='rooms-list-view-search'
|
||||||
/>
|
/>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title='directory'
|
|
||||||
iconName='directory'
|
iconName='directory'
|
||||||
onPress={this.goDirectory}
|
onPress={this.goDirectory}
|
||||||
testID='rooms-list-view-directory'
|
testID='rooms-list-view-directory'
|
||||||
/>
|
/>
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -883,7 +875,7 @@ class RoomsListView extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
renderHeader = () => {
|
renderHeader = () => {
|
||||||
const { isMasterDetail, theme } = this.props;
|
const { isMasterDetail } = this.props;
|
||||||
|
|
||||||
if (!isMasterDetail) {
|
if (!isMasterDetail) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -892,7 +884,6 @@ class RoomsListView extends React.Component {
|
||||||
const options = this.getHeader();
|
const options = this.getHeader();
|
||||||
return (
|
return (
|
||||||
<Header
|
<Header
|
||||||
theme={theme}
|
|
||||||
{...options}
|
{...options}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { themes } from '../../constants/colors';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import { getUserSelector } from '../../selectors/login';
|
import { getUserSelector } from '../../selectors/login';
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import database from '../../lib/database';
|
import database from '../../lib/database';
|
||||||
import { sanitizeLikeString } from '../../lib/database/utils';
|
import { sanitizeLikeString } from '../../lib/database/utils';
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class SearchMessagesView extends React.Component {
|
||||||
};
|
};
|
||||||
const showCloseModal = route.params?.showCloseModal;
|
const showCloseModal = route.params?.showCloseModal;
|
||||||
if (showCloseModal) {
|
if (showCloseModal) {
|
||||||
options.headerLeft = () => <CloseModalButton navigation={navigation} />;
|
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} />;
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import I18n from '../i18n';
|
||||||
import log, { logEvent, events } from '../utils/log';
|
import log, { logEvent, events } from '../utils/log';
|
||||||
import SearchBox from '../containers/SearchBox';
|
import SearchBox from '../containers/SearchBox';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import { Item, CustomHeaderButtons } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import { animateNextTransition } from '../utils/layoutAnimation';
|
import { animateNextTransition } from '../utils/layoutAnimation';
|
||||||
|
@ -119,9 +119,9 @@ class SelectedUsersView extends React.Component {
|
||||||
title,
|
title,
|
||||||
headerRight: () => (
|
headerRight: () => (
|
||||||
(!maxUsers || showButton) && (
|
(!maxUsers || showButton) && (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item title={buttonText} onPress={nextAction} testID='selected-users-view-submit' />
|
<HeaderButton.Item title={buttonText} onPress={nextAction} testID='selected-users-view-submit' />
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { logout as logoutAction } from '../../actions/login';
|
||||||
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
|
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
|
||||||
import { toggleCrashReport as toggleCrashReportAction, toggleAnalyticsEvents as toggleAnalyticsEventsAction } from '../../actions/crashReport';
|
import { toggleCrashReport as toggleCrashReportAction, toggleAnalyticsEvents as toggleAnalyticsEventsAction } from '../../actions/crashReport';
|
||||||
import { SWITCH_TRACK_COLOR, themes } from '../../constants/colors';
|
import { SWITCH_TRACK_COLOR, themes } from '../../constants/colors';
|
||||||
import { DrawerButton, CloseModalButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import * as List from '../../containers/List';
|
import * as List from '../../containers/List';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
|
@ -42,9 +42,9 @@ import { getUserSelector } from '../../selectors/login';
|
||||||
class SettingsView extends React.Component {
|
class SettingsView extends React.Component {
|
||||||
static navigationOptions = ({ navigation, isMasterDetail }) => ({
|
static navigationOptions = ({ navigation, isMasterDetail }) => ({
|
||||||
headerLeft: () => (isMasterDetail ? (
|
headerLeft: () => (isMasterDetail ? (
|
||||||
<CloseModalButton navigation={navigation} testID='settings-view-close' />
|
<HeaderButton.CloseModal navigation={navigation} testID='settings-view-close' />
|
||||||
) : (
|
) : (
|
||||||
<DrawerButton navigation={navigation} />
|
<HeaderButton.Drawer navigation={navigation} />
|
||||||
)),
|
)),
|
||||||
title: I18n.t('Settings')
|
title: I18n.t('Settings')
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Keyboard, View, StyleSheet } from 'react-native';
|
||||||
import ShareExtension from 'rn-extensions-share';
|
import ShareExtension from 'rn-extensions-share';
|
||||||
|
|
||||||
import SearchBox from '../../../containers/SearchBox';
|
import SearchBox from '../../../containers/SearchBox';
|
||||||
import { CancelModalButton } from '../../../containers/HeaderButton';
|
import * as HeaderButton from '../../../containers/HeaderButton';
|
||||||
import { themes } from '../../../constants/colors';
|
import { themes } from '../../../constants/colors';
|
||||||
|
|
||||||
import sharedStyles from '../../Styles';
|
import sharedStyles from '../../Styles';
|
||||||
|
@ -52,7 +52,7 @@ const Header = React.memo(({
|
||||||
{
|
{
|
||||||
!searching
|
!searching
|
||||||
? (
|
? (
|
||||||
<CancelModalButton
|
<HeaderButton.CancelModal
|
||||||
onPress={ShareExtension.close}
|
onPress={ShareExtension.close}
|
||||||
testID='share-extension-close'
|
testID='share-extension-close'
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { isIOS, isAndroid } from '../../utils/deviceInfo';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import DirectoryItem, { ROW_HEIGHT } from '../../presentation/DirectoryItem';
|
import DirectoryItem, { ROW_HEIGHT } from '../../presentation/DirectoryItem';
|
||||||
import ServerItem from '../../presentation/ServerItem';
|
import ServerItem from '../../presentation/ServerItem';
|
||||||
import { CancelModalButton, CustomHeaderButtons, Item } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import ShareListHeader from './Header';
|
import ShareListHeader from './Header';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
|
|
||||||
|
@ -157,12 +157,12 @@ class ShareListView extends React.Component {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerLeft: () => (searching
|
headerLeft: () => (searching
|
||||||
? (
|
? (
|
||||||
<CustomHeaderButtons left>
|
<HeaderButton.Container left>
|
||||||
<Item title='cancel' iconName='close' onPress={this.cancelSearch} />
|
<HeaderButton.Item title='cancel' iconName='close' onPress={this.cancelSearch} />
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
)
|
)
|
||||||
: (
|
: (
|
||||||
<CancelModalButton
|
<HeaderButton.CancelModal
|
||||||
onPress={ShareExtension.close}
|
onPress={ShareExtension.close}
|
||||||
testID='share-extension-close'
|
testID='share-extension-close'
|
||||||
/>
|
/>
|
||||||
|
@ -172,9 +172,9 @@ class ShareListView extends React.Component {
|
||||||
searching
|
searching
|
||||||
? null
|
? null
|
||||||
: (
|
: (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item title='search' iconName='search' onPress={this.initSearch} />
|
<HeaderButton.Item iconName='search' onPress={this.initSearch} />
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,11 +9,7 @@ import { themes } from '../../constants/colors';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import Loading from '../../containers/Loading';
|
import Loading from '../../containers/Loading';
|
||||||
import {
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
Item,
|
|
||||||
CloseModalButton,
|
|
||||||
CustomHeaderButtons
|
|
||||||
} from '../../containers/HeaderButton';
|
|
||||||
import { isBlocked } from '../../utils/room';
|
import { isBlocked } from '../../utils/room';
|
||||||
import { isReadOnly } from '../../utils/isReadOnly';
|
import { isReadOnly } from '../../utils/isReadOnly';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
|
@ -75,18 +71,18 @@ class ShareView extends Component {
|
||||||
|
|
||||||
// if is share extension show default back button
|
// if is share extension show default back button
|
||||||
if (!this.isShareExtension) {
|
if (!this.isShareExtension) {
|
||||||
options.headerLeft = () => <CloseModalButton navigation={navigation} buttonStyle={{ color: themes[theme].previewTintColor }} />;
|
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} buttonStyle={{ color: themes[theme].previewTintColor }} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attachments.length && !readOnly) {
|
if (!attachments.length && !readOnly) {
|
||||||
options.headerRight = () => (
|
options.headerRight = () => (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title={I18n.t('Send')}
|
title={I18n.t('Send')}
|
||||||
onPress={this.send}
|
onPress={this.send}
|
||||||
buttonStyle={[styles.send, { color: themes[theme].previewTintColor }]}
|
buttonStyle={[styles.send, { color: themes[theme].previewTintColor }]}
|
||||||
/>
|
/>
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import log, { logEvent, events } from '../utils/log';
|
||||||
import { LISTENER } from '../containers/Toast';
|
import { LISTENER } from '../containers/Toast';
|
||||||
import { withTheme } from '../theme';
|
import { withTheme } from '../theme';
|
||||||
import { getUserSelector } from '../selectors/login';
|
import { getUserSelector } from '../selectors/login';
|
||||||
import { CustomHeaderButtons, Item, CancelModalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import store from '../lib/createStore';
|
import store from '../lib/createStore';
|
||||||
import { setUser } from '../actions/login';
|
import { setUser } from '../actions/login';
|
||||||
import SafeAreaView from '../containers/SafeAreaView';
|
import SafeAreaView from '../containers/SafeAreaView';
|
||||||
|
@ -73,15 +73,15 @@ class StatusView extends React.Component {
|
||||||
const { navigation, isMasterDetail } = this.props;
|
const { navigation, isMasterDetail } = this.props;
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
title: I18n.t('Edit_Status'),
|
title: I18n.t('Edit_Status'),
|
||||||
headerLeft: isMasterDetail ? undefined : () => <CancelModalButton onPress={this.close} />,
|
headerLeft: isMasterDetail ? undefined : () => <HeaderButton.CancelModal onPress={this.close} />,
|
||||||
headerRight: () => (
|
headerRight: () => (
|
||||||
<CustomHeaderButtons>
|
<HeaderButton.Container>
|
||||||
<Item
|
<HeaderButton.Item
|
||||||
title={I18n.t('Done')}
|
title={I18n.t('Done')}
|
||||||
onPress={this.submit}
|
onPress={this.submit}
|
||||||
testID='status-view-submit'
|
testID='status-view-submit'
|
||||||
/>
|
/>
|
||||||
</CustomHeaderButtons>
|
</HeaderButton.Container>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { themes } from '../../constants/colors';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import { getUserSelector } from '../../selectors/login';
|
import { getUserSelector } from '../../selectors/login';
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
|
|
||||||
const Separator = React.memo(({ theme }) => <View style={[styles.separator, { backgroundColor: themes[theme].separatorColor }]} />);
|
const Separator = React.memo(({ theme }) => <View style={[styles.separator, { backgroundColor: themes[theme].separatorColor }]} />);
|
||||||
Separator.propTypes = {
|
Separator.propTypes = {
|
||||||
|
@ -39,7 +39,7 @@ class ThreadMessagesView extends React.Component {
|
||||||
title: I18n.t('Threads')
|
title: I18n.t('Threads')
|
||||||
};
|
};
|
||||||
if (isMasterDetail) {
|
if (isMasterDetail) {
|
||||||
options.headerLeft = () => <CloseModalButton navigation={navigation} />;
|
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} />;
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ShareExtension from 'rn-extensions-share';
|
import ShareExtension from 'rn-extensions-share';
|
||||||
|
|
||||||
import { CancelModalButton } from '../containers/HeaderButton';
|
import * as HeaderButton from '../containers/HeaderButton';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
|
@ -33,7 +33,7 @@ class WithoutServerView extends React.Component {
|
||||||
static navigationOptions = () => ({
|
static navigationOptions = () => ({
|
||||||
title: 'Rocket.Chat',
|
title: 'Rocket.Chat',
|
||||||
headerLeft: () => (
|
headerLeft: () => (
|
||||||
<CancelModalButton
|
<HeaderButton.CancelModal
|
||||||
onPress={ShareExtension.close}
|
onPress={ShareExtension.close}
|
||||||
testID='share-extension-close'
|
testID='share-extension-close'
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -109,7 +109,6 @@
|
||||||
"react-native-unimodules": "0.10.1",
|
"react-native-unimodules": "0.10.1",
|
||||||
"react-native-vector-icons": "7.0.0",
|
"react-native-vector-icons": "7.0.0",
|
||||||
"react-native-webview": "10.3.2",
|
"react-native-webview": "10.3.2",
|
||||||
"react-navigation-header-buttons": "3.0.5",
|
|
||||||
"react-redux": "7.2.0",
|
"react-redux": "7.2.0",
|
||||||
"reactotron-react-native": "5.0.0",
|
"reactotron-react-native": "5.0.0",
|
||||||
"redux": "4.0.5",
|
"redux": "4.0.5",
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
diff --git a/node_modules/react-navigation-header-buttons/src/HeaderButtons.js b/node_modules/react-navigation-header-buttons/src/HeaderButtons.js
|
|
||||||
index 70ff376..01fba5e 100644
|
|
||||||
--- a/node_modules/react-navigation-header-buttons/src/HeaderButtons.js
|
|
||||||
+++ b/node_modules/react-navigation-header-buttons/src/HeaderButtons.js
|
|
||||||
@@ -144,6 +144,6 @@ const styles = StyleSheet.create({
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
button: {
|
|
||||||
- marginHorizontal: 11,
|
|
||||||
+ marginHorizontal: 6
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions, react/prop-types */
|
||||||
|
import React from 'react';
|
||||||
|
import { storiesOf } from '@storybook/react-native';
|
||||||
|
import { View } from 'react-native';
|
||||||
|
|
||||||
|
import * as HeaderButton from '../../app/containers/HeaderButton';
|
||||||
|
import Header from '../../app/containers/Header';
|
||||||
|
import { ThemeContext } from '../../app/theme';
|
||||||
|
|
||||||
|
const stories = storiesOf('Header Buttons', module);
|
||||||
|
|
||||||
|
const HeaderExample = ({ left, right }) => (
|
||||||
|
<Header
|
||||||
|
headerLeft={left}
|
||||||
|
headerTitle={() => <View style={{ flex: 1 }} />}
|
||||||
|
headerRight={right}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
stories.add('title', () => (
|
||||||
|
<>
|
||||||
|
<HeaderExample
|
||||||
|
left={() => (
|
||||||
|
<HeaderButton.Container left>
|
||||||
|
<HeaderButton.Item title='threads' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
right={() => (
|
||||||
|
<HeaderButton.Container>
|
||||||
|
<HeaderButton.Item title='threads' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<HeaderExample
|
||||||
|
left={() => (
|
||||||
|
<HeaderButton.Container left>
|
||||||
|
<HeaderButton.Item title='threads' />
|
||||||
|
<HeaderButton.Item title='search' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
right={() => (
|
||||||
|
<HeaderButton.Container>
|
||||||
|
<HeaderButton.Item title='threads' />
|
||||||
|
<HeaderButton.Item title='search' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
));
|
||||||
|
|
||||||
|
stories.add('icons', () => (
|
||||||
|
<>
|
||||||
|
<HeaderExample
|
||||||
|
left={() => (
|
||||||
|
<HeaderButton.Container left>
|
||||||
|
<HeaderButton.Item iconName='threads' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
right={() => (
|
||||||
|
<HeaderButton.Container>
|
||||||
|
<HeaderButton.Item iconName='threads' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<HeaderExample
|
||||||
|
left={() => (
|
||||||
|
<HeaderButton.Container left>
|
||||||
|
<HeaderButton.Item iconName='threads' />
|
||||||
|
<HeaderButton.Item iconName='search' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
right={() => (
|
||||||
|
<HeaderButton.Container>
|
||||||
|
<HeaderButton.Item iconName='threads' />
|
||||||
|
<HeaderButton.Item iconName='search' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
));
|
||||||
|
|
||||||
|
stories.add('badge', () => (
|
||||||
|
<>
|
||||||
|
<HeaderExample
|
||||||
|
left={() => (
|
||||||
|
<HeaderButton.Container left>
|
||||||
|
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.Badge tunread={[1]} />} />
|
||||||
|
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.Badge tunread={[1]} tunreadUser={[1]} />} />
|
||||||
|
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.Badge tunread={[1]} tunreadGroup={[1]} />} />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
));
|
||||||
|
|
||||||
|
const ThemeStory = ({ theme }) => (
|
||||||
|
<ThemeContext.Provider
|
||||||
|
value={{ theme }}
|
||||||
|
>
|
||||||
|
<HeaderExample
|
||||||
|
left={() => (
|
||||||
|
<HeaderButton.Container left>
|
||||||
|
<HeaderButton.Item iconName='threads' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
right={() => (
|
||||||
|
<HeaderButton.Container>
|
||||||
|
<HeaderButton.Item title='Threads' />
|
||||||
|
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.Badge tunread={999} />} />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</ThemeContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
stories.add('themes', () => (
|
||||||
|
<>
|
||||||
|
<ThemeStory theme='light' />
|
||||||
|
<ThemeStory theme='dark' />
|
||||||
|
<ThemeStory theme='black' />
|
||||||
|
</>
|
||||||
|
));
|
||||||
|
|
||||||
|
stories.add('common', () => (
|
||||||
|
<>
|
||||||
|
<HeaderExample
|
||||||
|
left={() => (
|
||||||
|
<HeaderButton.Drawer />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<HeaderExample
|
||||||
|
left={() => (
|
||||||
|
<HeaderButton.CloseModal />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<HeaderExample
|
||||||
|
left={() => (
|
||||||
|
<HeaderButton.CancelModal />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<HeaderExample
|
||||||
|
right={() => (
|
||||||
|
<HeaderButton.More />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<HeaderExample
|
||||||
|
right={() => (
|
||||||
|
<HeaderButton.Download />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<HeaderExample
|
||||||
|
right={() => (
|
||||||
|
<HeaderButton.Preferences />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<HeaderExample
|
||||||
|
right={() => (
|
||||||
|
<HeaderButton.Legal />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
));
|
|
@ -73,10 +73,9 @@ export default ({ theme }) => {
|
||||||
<RoomItem alert name='unread' unread={1} />
|
<RoomItem alert name='unread' unread={1} />
|
||||||
<RoomItem alert name='unread' unread={1000} />
|
<RoomItem alert name='unread' unread={1000} />
|
||||||
<RoomItem alert name='user mentions' unread={1} userMentions={1} />
|
<RoomItem alert name='user mentions' unread={1} userMentions={1} />
|
||||||
<RoomItem alert name='user mentions' unread={1000} userMentions={1} />
|
|
||||||
<RoomItem alert name='group mentions' unread={1} groupMentions={1} />
|
<RoomItem alert name='group mentions' unread={1} groupMentions={1} />
|
||||||
<RoomItem alert name='group mentions' unread={1000} groupMentions={1} />
|
<RoomItem alert name='thread unread' tunread={[1]} />
|
||||||
<RoomItem name='user mentions > group mentions' alert unread={1000} userMentions={1} groupMentions={1} />
|
<RoomItem name='user mentions > group mentions' alert unread={1} userMentions={1} groupMentions={1} />
|
||||||
|
|
||||||
<Separator title='Last Message' />
|
<Separator title='Last Message' />
|
||||||
<RoomItem
|
<RoomItem
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions, react/prop-types */
|
||||||
|
import React from 'react';
|
||||||
|
import { storiesOf } from '@storybook/react-native';
|
||||||
|
import { View } from 'react-native';
|
||||||
|
|
||||||
|
import UnreadBadge from '../../app/presentation/UnreadBadge';
|
||||||
|
import { ThemeContext } from '../../app/theme';
|
||||||
|
|
||||||
|
const stories = storiesOf('Unread Badge', module);
|
||||||
|
|
||||||
|
const StoryTester = ({ children }) => (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-evenly'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
stories.add('all', () => (
|
||||||
|
<StoryTester>
|
||||||
|
<UnreadBadge unread={9} small />
|
||||||
|
<UnreadBadge unread={999} small />
|
||||||
|
<UnreadBadge unread={9} />
|
||||||
|
<UnreadBadge unread={9999} />
|
||||||
|
<UnreadBadge unread={9} userMentions={1} />
|
||||||
|
<UnreadBadge unread={9} groupMentions={1} />
|
||||||
|
<UnreadBadge unread={9} tunread={[1]} />
|
||||||
|
</StoryTester>
|
||||||
|
));
|
||||||
|
|
||||||
|
stories.add('small', () => (
|
||||||
|
<StoryTester>
|
||||||
|
<UnreadBadge unread={9} small />
|
||||||
|
<UnreadBadge unread={999} small />
|
||||||
|
</StoryTester>
|
||||||
|
));
|
||||||
|
|
||||||
|
stories.add('normal', () => (
|
||||||
|
<StoryTester>
|
||||||
|
<UnreadBadge unread={9} />
|
||||||
|
<UnreadBadge unread={9999} />
|
||||||
|
</StoryTester>
|
||||||
|
));
|
||||||
|
|
||||||
|
stories.add('different mention types', () => (
|
||||||
|
<StoryTester>
|
||||||
|
<UnreadBadge unread={1} />
|
||||||
|
<UnreadBadge unread={1} userMentions={1} />
|
||||||
|
<UnreadBadge unread={1} groupMentions={1} />
|
||||||
|
<UnreadBadge unread={1} userMentions={1} groupMentions={1} />
|
||||||
|
<UnreadBadge unread={1} tunread={[1]} />
|
||||||
|
<UnreadBadge unread={1} tunreadUser={[1]} />
|
||||||
|
<UnreadBadge unread={1} tunreadGroup={[1]} />
|
||||||
|
</StoryTester>
|
||||||
|
));
|
||||||
|
|
||||||
|
const ThemeStory = ({ theme }) => (
|
||||||
|
<ThemeContext.Provider
|
||||||
|
value={{ theme }}
|
||||||
|
>
|
||||||
|
<StoryTester>
|
||||||
|
<UnreadBadge unread={1} />
|
||||||
|
<UnreadBadge unread={1} userMentions={1} />
|
||||||
|
<UnreadBadge unread={1} groupMentions={1} />
|
||||||
|
<UnreadBadge tunread={[1]} />
|
||||||
|
</StoryTester>
|
||||||
|
</ThemeContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
stories.add('themes', () => (
|
||||||
|
<>
|
||||||
|
<ThemeStory theme='light' />
|
||||||
|
<ThemeStory theme='dark' />
|
||||||
|
<ThemeStory theme='black' />
|
||||||
|
</>
|
||||||
|
));
|
|
@ -10,6 +10,8 @@ import Message from './Message';
|
||||||
import UiKitMessage from './UiKitMessage';
|
import UiKitMessage from './UiKitMessage';
|
||||||
import UiKitModal from './UiKitModal';
|
import UiKitModal from './UiKitModal';
|
||||||
import Markdown from './Markdown';
|
import Markdown from './Markdown';
|
||||||
|
import './HeaderButtons';
|
||||||
|
import './UnreadBadge';
|
||||||
import Avatar from './Avatar';
|
import Avatar from './Avatar';
|
||||||
// import RoomViewHeader from './RoomViewHeader';
|
// import RoomViewHeader from './RoomViewHeader';
|
||||||
|
|
||||||
|
|
|
@ -12891,7 +12891,7 @@ react-native-picker-select@7.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash.isequal "^4.5.0"
|
lodash.isequal "^4.5.0"
|
||||||
|
|
||||||
react-native-platform-touchable@1.1.1, react-native-platform-touchable@^1.1.1:
|
react-native-platform-touchable@1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-platform-touchable/-/react-native-platform-touchable-1.1.1.tgz#fde4acc65eea585d28b164d0c3716a42129a68e4"
|
resolved "https://registry.yarnpkg.com/react-native-platform-touchable/-/react-native-platform-touchable-1.1.1.tgz#fde4acc65eea585d28b164d0c3716a42129a68e4"
|
||||||
integrity sha1-/eSsxl7qWF0osWTQw3FqQhKaaOQ=
|
integrity sha1-/eSsxl7qWF0osWTQw3FqQhKaaOQ=
|
||||||
|
@ -13068,13 +13068,6 @@ react-native@^0.63.1:
|
||||||
use-subscription "^1.0.0"
|
use-subscription "^1.0.0"
|
||||||
whatwg-fetch "^3.0.0"
|
whatwg-fetch "^3.0.0"
|
||||||
|
|
||||||
react-navigation-header-buttons@3.0.5:
|
|
||||||
version "3.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-navigation-header-buttons/-/react-navigation-header-buttons-3.0.5.tgz#5b8c0fc32bc59382f02015e4b2f19a135b99dca4"
|
|
||||||
integrity sha512-b1AsL9k6Klp72CnAq4IF0xgw94FClBIsUr/pGUKa1PI+mStdF0AYZzi9qtYgqQNDIOpqxQ2xYUM9azL2VmPUeQ==
|
|
||||||
dependencies:
|
|
||||||
react-native-platform-touchable "^1.1.1"
|
|
||||||
|
|
||||||
react-popper-tooltip@^2.8.3:
|
react-popper-tooltip@^2.8.3:
|
||||||
version "2.11.1"
|
version "2.11.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.11.1.tgz#3c4bdfd8bc10d1c2b9a162e859bab8958f5b2644"
|
resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.11.1.tgz#3c4bdfd8bc10d1c2b9a162e859bab8958f5b2644"
|
||||||
|
|
Loading…
Reference in New Issue