[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 = {
|
||||
unreadBackground: '#6C727A',
|
||||
tunreadBackground: '#1d74f5',
|
||||
mentionMeColor: '#DB0C27',
|
||||
mentionMeBackground: '#F5455C',
|
||||
mentionGroupColor: '#E26D0E',
|
||||
|
|
|
@ -5,6 +5,7 @@ import { View, StyleSheet } from 'react-native';
|
|||
import { themes } from '../../constants/colors';
|
||||
import { themedHeader } from '../../utils/navigation';
|
||||
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
|
||||
export const headerHeight = isIOS ? 44 : 56;
|
||||
|
@ -53,4 +54,4 @@ Header.propTypes = {
|
|||
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 StatusBar from '../../../containers/StatusBar';
|
||||
import { goRoom } from '../../../utils/goRoom';
|
||||
import { CloseModalButton } from '../../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../../containers/HeaderButton';
|
||||
import RocketChat from '../../../lib/rocketchat';
|
||||
import { logEvent, events } from '../../../utils/log';
|
||||
import { getInquiryQueueSelector } from '../selectors/inquiry';
|
||||
|
@ -34,7 +34,7 @@ class QueueListView extends React.Component {
|
|||
title: I18n.t('Queued_chats')
|
||||
};
|
||||
if (isMasterDetail) {
|
||||
options.headerLeft = () => <CloseModalButton navigation={navigation} testID='directory-view-close' />;
|
||||
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} testID='directory-view-close' />;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ const RoomItem = ({
|
|||
alert,
|
||||
hideUnreadStatus,
|
||||
unread,
|
||||
tunread,
|
||||
userMentions,
|
||||
groupMentions,
|
||||
roomUpdatedAt,
|
||||
|
@ -112,6 +113,7 @@ const RoomItem = ({
|
|||
/>
|
||||
<UnreadBadge
|
||||
unread={unread}
|
||||
tunread={tunread}
|
||||
userMentions={userMentions}
|
||||
groupMentions={groupMentions}
|
||||
theme={theme}
|
||||
|
@ -136,6 +138,7 @@ const RoomItem = ({
|
|||
/>
|
||||
<UnreadBadge
|
||||
unread={unread}
|
||||
tunread={tunread}
|
||||
userMentions={userMentions}
|
||||
groupMentions={groupMentions}
|
||||
theme={theme}
|
||||
|
@ -174,6 +177,7 @@ RoomItem.propTypes = {
|
|||
alert: PropTypes.bool,
|
||||
hideUnreadStatus: PropTypes.bool,
|
||||
unread: PropTypes.number,
|
||||
tunread: PropTypes.array,
|
||||
userMentions: PropTypes.number,
|
||||
groupMentions: PropTypes.number,
|
||||
roomUpdatedAt: PropTypes.instanceOf(Date),
|
||||
|
|
|
@ -228,6 +228,7 @@ class RoomItemContainer extends React.Component {
|
|||
username={username}
|
||||
useRealName={useRealName}
|
||||
unread={item.unread}
|
||||
tunread={item.tunread}
|
||||
groupMentions={item.groupMentions}
|
||||
avatarETag={avatarETag || item.avatarETag}
|
||||
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 StatusBar from '../../containers/StatusBar';
|
||||
import { DrawerButton } from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import { withTheme } from '../../theme';
|
||||
import { getUserSelector } from '../../selectors/login';
|
||||
import SafeAreaView from '../../containers/SafeAreaView';
|
||||
|
||||
class AdminPanelView extends React.Component {
|
||||
static navigationOptions = ({ navigation, isMasterDetail }) => ({
|
||||
headerLeft: isMasterDetail ? undefined : () => <DrawerButton navigation={navigation} />,
|
||||
headerLeft: isMasterDetail ? undefined : () => <HeaderButton.Drawer navigation={navigation} />,
|
||||
title: I18n.t('Admin_Panel')
|
||||
})
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import { ImageViewer } from '../presentation/ImageViewer';
|
|||
import { themes } from '../constants/colors';
|
||||
import { formatAttachmentUrl } from '../lib/utils';
|
||||
import RCActivityIndicator from '../containers/ActivityIndicator';
|
||||
import { SaveButton, CloseModalButton } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import { isAndroid } from '../utils/deviceInfo';
|
||||
import { getUserSelector } from '../selectors/login';
|
||||
import { withDimensions } from '../dimensions';
|
||||
|
@ -81,10 +81,10 @@ class AttachmentView extends React.Component {
|
|||
}
|
||||
const options = {
|
||||
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: () => (
|
||||
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
|
||||
),
|
||||
headerBackground: () => <View style={{ flex: 1, backgroundColor: themes[theme].previewBackground }} />,
|
||||
|
|
|
@ -10,7 +10,7 @@ import StatusBar from '../containers/StatusBar';
|
|||
import ActivityIndicator from '../containers/ActivityIndicator';
|
||||
import { withTheme } from '../theme';
|
||||
import debounce from '../utils/debounce';
|
||||
import { CloseModalButton } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
|
||||
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'
|
||||
|
@ -185,7 +185,7 @@ const mapStateToProps = state => ({
|
|||
AuthenticationWebView.navigationOptions = ({ route, navigation }) => {
|
||||
const { authType } = route.params;
|
||||
return {
|
||||
headerLeft: () => <CloseModalButton navigation={navigation} />,
|
||||
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} />,
|
||||
title: ['saml', 'cas', 'iframe'].includes(authType) ? 'SSO' : 'OAuth'
|
||||
};
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@ import KeyboardView from '../presentation/KeyboardView';
|
|||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||
import I18n from '../i18n';
|
||||
import UserItem from '../presentation/UserItem';
|
||||
import { CustomHeaderButtons, Item } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import { SWITCH_TRACK_COLOR, themes } from '../constants/colors';
|
||||
import { withTheme } from '../theme';
|
||||
|
@ -143,9 +143,9 @@ class CreateChannelView extends React.Component {
|
|||
const { navigation } = this.props;
|
||||
navigation.setOptions({
|
||||
headerRight: () => channelName.trim().length > 0 && (
|
||||
<CustomHeaderButtons>
|
||||
<Item title={I18n.t('Create')} onPress={this.submit} testID='create-channel-submit' />
|
||||
</CustomHeaderButtons>
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item title={I18n.t('Create')} onPress={this.submit} testID='create-channel-submit' />
|
||||
</HeaderButton.Container>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import Loading from '../../containers/Loading';
|
|||
import KeyboardView from '../../presentation/KeyboardView';
|
||||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||
import I18n from '../../i18n';
|
||||
import { CustomHeaderButtons, Item, CloseModalButton } from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
import { themes } from '../../constants/colors';
|
||||
import { withTheme } from '../../theme';
|
||||
|
@ -96,13 +96,13 @@ class CreateChannelView extends React.Component {
|
|||
headerRight: (
|
||||
this.valid()
|
||||
? () => (
|
||||
<CustomHeaderButtons>
|
||||
<Item title={I18n.t('Create')} onPress={this.submit} testID='create-discussion-submit' />
|
||||
</CustomHeaderButtons>
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item title={I18n.t('Create')} onPress={this.submit} testID='create-discussion-submit' />
|
||||
</HeaderButton.Container>
|
||||
)
|
||||
: 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 StatusBar from '../../containers/StatusBar';
|
||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import debounce from '../../utils/debounce';
|
||||
import log, { logEvent, events } from '../../utils/log';
|
||||
import Options from './Options';
|
||||
|
@ -31,7 +31,7 @@ class DirectoryView extends React.Component {
|
|||
title: I18n.t('Directory')
|
||||
};
|
||||
if (isMasterDetail) {
|
||||
options.headerLeft = () => <CloseModalButton navigation={navigation} testID='directory-view-close' />;
|
||||
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} testID='directory-view-close' />;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import Button from '../containers/Button';
|
|||
import { themes } from '../constants/colors';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
import { CloseModalButton } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import { encryptionDecodeKey as encryptionDecodeKeyAction } from '../actions/encryption';
|
||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||
import KeyboardView from '../presentation/KeyboardView';
|
||||
|
@ -29,7 +29,7 @@ const styles = StyleSheet.create({
|
|||
});
|
||||
class E2EEnterYourPasswordView extends React.Component {
|
||||
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')
|
||||
})
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { StyleSheet } from 'react-native';
|
|||
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
import { themes } from '../constants/colors';
|
||||
import { CloseModalButton } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import Markdown from '../containers/markdown';
|
||||
import { withTheme } from '../theme';
|
||||
import I18n from '../i18n';
|
||||
|
@ -26,7 +26,7 @@ class E2EHowItWorksView extends React.Component {
|
|||
const showCloseModal = route.params?.showCloseModal;
|
||||
return {
|
||||
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 { 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 SafeAreaView from '../containers/SafeAreaView';
|
||||
import UserPreferences from '../lib/userPreferences';
|
||||
|
@ -61,7 +61,7 @@ const styles = StyleSheet.create({
|
|||
|
||||
class E2ESaveYourPasswordView extends React.Component {
|
||||
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')
|
||||
})
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import equal from 'deep-equal';
|
|||
import sharedStyles from './Styles';
|
||||
import Button from '../containers/Button';
|
||||
import I18n from '../i18n';
|
||||
import { LegalButton } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import { themes } from '../constants/colors';
|
||||
import { withTheme } from '../theme';
|
||||
import FormContainer, { FormContainerInner } from '../containers/FormContainer';
|
||||
|
@ -51,7 +51,7 @@ const styles = StyleSheet.create({
|
|||
class LoginView extends React.Component {
|
||||
static navigationOptions = ({ route, navigation }) => ({
|
||||
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 = {
|
||||
|
|
|
@ -8,7 +8,7 @@ import { KeyboardAwareScrollView } from '@codler/react-native-keyboard-aware-scr
|
|||
import { withTheme } from '../theme';
|
||||
import EventEmitter from '../utils/events';
|
||||
import { themes } from '../constants/colors';
|
||||
import { CustomHeaderButtons, Item } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import { modalBlockWithContext } from '../containers/UIKit/MessageBlock';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import ActivityIndicator from '../containers/ActivityIndicator';
|
||||
|
@ -128,24 +128,24 @@ class ModalBlockView extends React.Component {
|
|||
navigation.setOptions({
|
||||
title: textParser([title]),
|
||||
headerLeft: close ? () => (
|
||||
<CustomHeaderButtons>
|
||||
<Item
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item
|
||||
title={textParser([close.text])}
|
||||
style={styles.submit}
|
||||
onPress={this.cancel}
|
||||
testID='close-modal-uikit'
|
||||
/>
|
||||
</CustomHeaderButtons>
|
||||
</HeaderButton.Container>
|
||||
) : null,
|
||||
headerRight: submit ? () => (
|
||||
<CustomHeaderButtons>
|
||||
<Item
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item
|
||||
title={textParser([submit.text])}
|
||||
style={styles.submit}
|
||||
onPress={this.submit}
|
||||
testID='submit-modal-uikit'
|
||||
/>
|
||||
</CustomHeaderButtons>
|
||||
</HeaderButton.Container>
|
||||
) : null
|
||||
});
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import I18n from '../i18n';
|
|||
import log, { logEvent, events } from '../utils/log';
|
||||
import SearchBox from '../containers/SearchBox';
|
||||
import { CustomIcon } from '../lib/Icons';
|
||||
import { CloseModalButton } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import { themes } from '../constants/colors';
|
||||
import { withTheme } from '../theme';
|
||||
|
@ -51,7 +51,7 @@ const styles = StyleSheet.create({
|
|||
|
||||
class NewMessageView extends React.Component {
|
||||
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')
|
||||
})
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import log, { logEvent, events } from '../../utils/log';
|
|||
import { animateNextTransition } from '../../utils/layoutAnimation';
|
||||
import { withTheme } from '../../theme';
|
||||
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 database from '../../lib/database';
|
||||
import ServerInput from './ServerInput';
|
||||
|
@ -111,7 +111,7 @@ class NewServerView extends React.Component {
|
|||
const { adding, navigation } = this.props;
|
||||
if (adding) {
|
||||
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 { setUser as setUserAction } from '../../actions/login';
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
import { DrawerButton, PreferencesButton } from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
import { themes } from '../../constants/colors';
|
||||
import { withTheme } from '../../theme';
|
||||
|
@ -37,10 +37,10 @@ class ProfileView extends React.Component {
|
|||
title: I18n.t('Profile')
|
||||
};
|
||||
if (!isMasterDetail) {
|
||||
options.headerLeft = () => <DrawerButton navigation={navigation} />;
|
||||
options.headerLeft = () => <HeaderButton.Drawer navigation={navigation} />;
|
||||
}
|
||||
options.headerRight = () => (
|
||||
<PreferencesButton onPress={() => navigation.navigate('UserPreferencesView')} testID='preferences-view-open' />
|
||||
<HeaderButton.Preferences onPress={() => navigation.navigate('UserPreferencesView')} testID='preferences-view-open' />
|
||||
);
|
||||
return options;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import { connect } from 'react-redux';
|
|||
import Avatar from '../../containers/Avatar';
|
||||
import styles from './styles';
|
||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import I18n from '../../i18n';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
|
@ -22,7 +22,7 @@ class ReadReceiptView extends React.Component {
|
|||
title: I18n.t('Read_Receipt')
|
||||
};
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import log, { logEvent, events } from '../utils/log';
|
|||
import sharedStyles from './Styles';
|
||||
import Button from '../containers/Button';
|
||||
import I18n from '../i18n';
|
||||
import { LegalButton } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import { themes } from '../constants/colors';
|
||||
import { withTheme } from '../theme';
|
||||
import FormContainer, { FormContainerInner } from '../containers/FormContainer';
|
||||
|
@ -54,7 +54,7 @@ const styles = StyleSheet.create({
|
|||
class RegisterView extends React.Component {
|
||||
static navigationOptions = ({ route, navigation }) => ({
|
||||
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 = {
|
||||
|
|
|
@ -21,7 +21,7 @@ import I18n from '../../i18n';
|
|||
import StatusBar from '../../containers/StatusBar';
|
||||
import { themes, SWITCH_TRACK_COLOR } from '../../constants/colors';
|
||||
import { withTheme } from '../../theme';
|
||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import Markdown from '../../containers/markdown';
|
||||
import { showConfirmationAlert, showErrorAlert } from '../../utils/info';
|
||||
import SafeAreaView from '../../containers/SafeAreaView';
|
||||
|
@ -36,7 +36,7 @@ class RoomActionsView extends React.Component {
|
|||
title: I18n.t('Actions')
|
||||
};
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import sharedStyles from '../Styles';
|
|||
import RocketChat from '../../lib/rocketchat';
|
||||
import RoomTypeIcon from '../../containers/RoomTypeIcon';
|
||||
import I18n from '../../i18n';
|
||||
import { CustomHeaderButtons, CloseModalButton } from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
import log, { logEvent, events } from '../../utils/log';
|
||||
import { themes } from '../../constants/colors';
|
||||
|
@ -26,7 +26,6 @@ import EventEmitter from '../../utils/events';
|
|||
|
||||
import Livechat from './Livechat';
|
||||
import Channel from './Channel';
|
||||
import Item from './Item';
|
||||
import Direct from './Direct';
|
||||
import SafeAreaView from '../../containers/SafeAreaView';
|
||||
import { goRoom } from '../../utils/goRoom';
|
||||
|
@ -104,12 +103,12 @@ class RoomInfoView extends React.Component {
|
|||
const rid = route.params?.rid;
|
||||
const showCloseModal = route.params?.showCloseModal;
|
||||
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'),
|
||||
headerRight: showEdit
|
||||
? () => (
|
||||
<CustomHeaderButtons>
|
||||
<Item
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item
|
||||
iconName='edit'
|
||||
onPress={() => {
|
||||
const isLivechat = t === 'l';
|
||||
|
@ -118,7 +117,7 @@ class RoomInfoView extends React.Component {
|
|||
}}
|
||||
testID='room-info-view-edit-button'
|
||||
/>
|
||||
</CustomHeaderButtons>
|
||||
</HeaderButton.Container>
|
||||
)
|
||||
: null
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ import log from '../../utils/log';
|
|||
import I18n from '../../i18n';
|
||||
import SearchBox from '../../containers/SearchBox';
|
||||
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 ActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import { withTheme } from '../../theme';
|
||||
|
@ -97,9 +97,9 @@ class RoomMembersView extends React.Component {
|
|||
navigation.setOptions({
|
||||
title: I18n.t('Members'),
|
||||
headerRight: () => (
|
||||
<CustomHeaderButtons>
|
||||
<Item title={toggleText} onPress={this.toggleStatus} testID='room-members-view-toggle-status' />
|
||||
</CustomHeaderButtons>
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item title={toggleText} onPress={this.toggleStatus} testID='room-members-view-toggle-status' />
|
||||
</HeaderButton.Container>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,11 +2,12 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { CustomHeaderButtons, Item } from '../../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../../containers/HeaderButton';
|
||||
import database from '../../../lib/database';
|
||||
import { getUserSelector } from '../../../selectors/login';
|
||||
import { logEvent, events } from '../../../utils/log';
|
||||
|
||||
|
||||
class RightButtonsContainer extends React.PureComponent {
|
||||
static propTypes = {
|
||||
userId: PropTypes.string,
|
||||
|
@ -99,33 +100,30 @@ class RightButtonsContainer extends React.PureComponent {
|
|||
}
|
||||
if (tmid) {
|
||||
return (
|
||||
<CustomHeaderButtons>
|
||||
<Item
|
||||
title='bell'
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item
|
||||
iconName={isFollowingThread ? 'notification' : 'notification-disabled'}
|
||||
onPress={this.toggleFollowThread}
|
||||
testID={isFollowingThread ? 'room-view-header-unfollow' : 'room-view-header-follow'}
|
||||
/>
|
||||
</CustomHeaderButtons>
|
||||
</HeaderButton.Container>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<CustomHeaderButtons>
|
||||
<HeaderButton.Container>
|
||||
{threadsEnabled ? (
|
||||
<Item
|
||||
title='threads'
|
||||
<HeaderButton.Item
|
||||
iconName='threads'
|
||||
onPress={this.goThreadsView}
|
||||
testID='room-view-header-threads'
|
||||
/>
|
||||
) : null}
|
||||
<Item
|
||||
title='search'
|
||||
<HeaderButton.Item
|
||||
iconName='search'
|
||||
onPress={this.goSearchView}
|
||||
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 { isIOS, isTablet } from '../../utils/deviceInfo';
|
||||
import RoomsListHeaderView from './Header';
|
||||
import {
|
||||
DrawerButton,
|
||||
CustomHeaderButtons,
|
||||
Item
|
||||
} from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import ListHeader from './ListHeader';
|
||||
|
@ -346,15 +342,14 @@ class RoomsListView extends React.Component {
|
|||
return {
|
||||
headerTitleAlign: 'left',
|
||||
headerLeft: () => (searching ? (
|
||||
<CustomHeaderButtons left>
|
||||
<Item
|
||||
title='cancel'
|
||||
<HeaderButton.Container left>
|
||||
<HeaderButton.Item
|
||||
iconName='close'
|
||||
onPress={this.cancelSearch}
|
||||
/>
|
||||
</CustomHeaderButtons>
|
||||
</HeaderButton.Container>
|
||||
) : (
|
||||
<DrawerButton
|
||||
<HeaderButton.Drawer
|
||||
navigation={navigation}
|
||||
testID='rooms-list-view-sidebar'
|
||||
onPress={isMasterDetail
|
||||
|
@ -368,26 +363,23 @@ class RoomsListView extends React.Component {
|
|||
right: headerTitlePosition.right
|
||||
},
|
||||
headerRight: () => (searching ? null : (
|
||||
<CustomHeaderButtons>
|
||||
<Item
|
||||
title='new'
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item
|
||||
iconName='create'
|
||||
onPress={this.goToNewMessage}
|
||||
testID='rooms-list-view-create-channel'
|
||||
/>
|
||||
<Item
|
||||
title='search'
|
||||
<HeaderButton.Item
|
||||
iconName='search'
|
||||
onPress={this.initSearching}
|
||||
testID='rooms-list-view-search'
|
||||
/>
|
||||
<Item
|
||||
title='directory'
|
||||
<HeaderButton.Item
|
||||
iconName='directory'
|
||||
onPress={this.goDirectory}
|
||||
testID='rooms-list-view-directory'
|
||||
/>
|
||||
</CustomHeaderButtons>
|
||||
</HeaderButton.Container>
|
||||
))
|
||||
};
|
||||
}
|
||||
|
@ -883,7 +875,7 @@ class RoomsListView extends React.Component {
|
|||
};
|
||||
|
||||
renderHeader = () => {
|
||||
const { isMasterDetail, theme } = this.props;
|
||||
const { isMasterDetail } = this.props;
|
||||
|
||||
if (!isMasterDetail) {
|
||||
return null;
|
||||
|
@ -892,7 +884,6 @@ class RoomsListView extends React.Component {
|
|||
const options = this.getHeader();
|
||||
return (
|
||||
<Header
|
||||
theme={theme}
|
||||
{...options}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -20,7 +20,7 @@ import { themes } from '../../constants/colors';
|
|||
import { withTheme } from '../../theme';
|
||||
import { getUserSelector } from '../../selectors/login';
|
||||
import SafeAreaView from '../../containers/SafeAreaView';
|
||||
import { CloseModalButton } from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import database from '../../lib/database';
|
||||
import { sanitizeLikeString } from '../../lib/database/utils';
|
||||
|
||||
|
@ -31,7 +31,7 @@ class SearchMessagesView extends React.Component {
|
|||
};
|
||||
const showCloseModal = route.params?.showCloseModal;
|
||||
if (showCloseModal) {
|
||||
options.headerLeft = () => <CloseModalButton navigation={navigation} />;
|
||||
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} />;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import I18n from '../i18n';
|
|||
import log, { logEvent, events } from '../utils/log';
|
||||
import SearchBox from '../containers/SearchBox';
|
||||
import sharedStyles from './Styles';
|
||||
import { Item, CustomHeaderButtons } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import { themes } from '../constants/colors';
|
||||
import { animateNextTransition } from '../utils/layoutAnimation';
|
||||
|
@ -119,9 +119,9 @@ class SelectedUsersView extends React.Component {
|
|||
title,
|
||||
headerRight: () => (
|
||||
(!maxUsers || showButton) && (
|
||||
<CustomHeaderButtons>
|
||||
<Item title={buttonText} onPress={nextAction} testID='selected-users-view-submit' />
|
||||
</CustomHeaderButtons>
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item title={buttonText} onPress={nextAction} testID='selected-users-view-submit' />
|
||||
</HeaderButton.Container>
|
||||
)
|
||||
)
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ import { logout as logoutAction } from '../../actions/login';
|
|||
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
|
||||
import { toggleCrashReport as toggleCrashReportAction, toggleAnalyticsEvents as toggleAnalyticsEventsAction } from '../../actions/crashReport';
|
||||
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 * as List from '../../containers/List';
|
||||
import I18n from '../../i18n';
|
||||
|
@ -42,9 +42,9 @@ import { getUserSelector } from '../../selectors/login';
|
|||
class SettingsView extends React.Component {
|
||||
static navigationOptions = ({ navigation, 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')
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Keyboard, View, StyleSheet } from 'react-native';
|
|||
import ShareExtension from 'rn-extensions-share';
|
||||
|
||||
import SearchBox from '../../../containers/SearchBox';
|
||||
import { CancelModalButton } from '../../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../../containers/HeaderButton';
|
||||
import { themes } from '../../../constants/colors';
|
||||
|
||||
import sharedStyles from '../../Styles';
|
||||
|
@ -52,7 +52,7 @@ const Header = React.memo(({
|
|||
{
|
||||
!searching
|
||||
? (
|
||||
<CancelModalButton
|
||||
<HeaderButton.CancelModal
|
||||
onPress={ShareExtension.close}
|
||||
testID='share-extension-close'
|
||||
/>
|
||||
|
|
|
@ -15,7 +15,7 @@ import { isIOS, isAndroid } from '../../utils/deviceInfo';
|
|||
import I18n from '../../i18n';
|
||||
import DirectoryItem, { ROW_HEIGHT } from '../../presentation/DirectoryItem';
|
||||
import ServerItem from '../../presentation/ServerItem';
|
||||
import { CancelModalButton, CustomHeaderButtons, Item } from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import ShareListHeader from './Header';
|
||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||
|
||||
|
@ -157,12 +157,12 @@ class ShareListView extends React.Component {
|
|||
navigation.setOptions({
|
||||
headerLeft: () => (searching
|
||||
? (
|
||||
<CustomHeaderButtons left>
|
||||
<Item title='cancel' iconName='close' onPress={this.cancelSearch} />
|
||||
</CustomHeaderButtons>
|
||||
<HeaderButton.Container left>
|
||||
<HeaderButton.Item title='cancel' iconName='close' onPress={this.cancelSearch} />
|
||||
</HeaderButton.Container>
|
||||
)
|
||||
: (
|
||||
<CancelModalButton
|
||||
<HeaderButton.CancelModal
|
||||
onPress={ShareExtension.close}
|
||||
testID='share-extension-close'
|
||||
/>
|
||||
|
@ -172,9 +172,9 @@ class ShareListView extends React.Component {
|
|||
searching
|
||||
? null
|
||||
: (
|
||||
<CustomHeaderButtons>
|
||||
<Item title='search' iconName='search' onPress={this.initSearch} />
|
||||
</CustomHeaderButtons>
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item iconName='search' onPress={this.initSearch} />
|
||||
</HeaderButton.Container>
|
||||
)
|
||||
)
|
||||
});
|
||||
|
|
|
@ -9,11 +9,7 @@ import { themes } from '../../constants/colors';
|
|||
import I18n from '../../i18n';
|
||||
import styles from './styles';
|
||||
import Loading from '../../containers/Loading';
|
||||
import {
|
||||
Item,
|
||||
CloseModalButton,
|
||||
CustomHeaderButtons
|
||||
} from '../../containers/HeaderButton';
|
||||
import * as HeaderButton from '../../containers/HeaderButton';
|
||||
import { isBlocked } from '../../utils/room';
|
||||
import { isReadOnly } from '../../utils/isReadOnly';
|
||||
import { withTheme } from '../../theme';
|
||||
|
@ -75,18 +71,18 @@ class ShareView extends Component {
|
|||
|
||||
// if is share extension show default back button
|
||||
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) {
|
||||
options.headerRight = () => (
|
||||
<CustomHeaderButtons>
|
||||
<Item
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item
|
||||
title={I18n.t('Send')}
|
||||
onPress={this.send}
|
||||
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 { withTheme } from '../theme';
|
||||
import { getUserSelector } from '../selectors/login';
|
||||
import { CustomHeaderButtons, Item, CancelModalButton } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import store from '../lib/createStore';
|
||||
import { setUser } from '../actions/login';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
|
@ -73,15 +73,15 @@ class StatusView extends React.Component {
|
|||
const { navigation, isMasterDetail } = this.props;
|
||||
navigation.setOptions({
|
||||
title: I18n.t('Edit_Status'),
|
||||
headerLeft: isMasterDetail ? undefined : () => <CancelModalButton onPress={this.close} />,
|
||||
headerLeft: isMasterDetail ? undefined : () => <HeaderButton.CancelModal onPress={this.close} />,
|
||||
headerRight: () => (
|
||||
<CustomHeaderButtons>
|
||||
<Item
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item
|
||||
title={I18n.t('Done')}
|
||||
onPress={this.submit}
|
||||
testID='status-view-submit'
|
||||
/>
|
||||
</CustomHeaderButtons>
|
||||
</HeaderButton.Container>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import { themes } from '../../constants/colors';
|
|||
import { withTheme } from '../../theme';
|
||||
import { getUserSelector } from '../../selectors/login';
|
||||
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 }]} />);
|
||||
Separator.propTypes = {
|
||||
|
@ -39,7 +39,7 @@ class ThreadMessagesView extends React.Component {
|
|||
title: I18n.t('Threads')
|
||||
};
|
||||
if (isMasterDetail) {
|
||||
options.headerLeft = () => <CloseModalButton navigation={navigation} />;
|
||||
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} />;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
import PropTypes from 'prop-types';
|
||||
import ShareExtension from 'rn-extensions-share';
|
||||
|
||||
import { CancelModalButton } from '../containers/HeaderButton';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import sharedStyles from './Styles';
|
||||
import I18n from '../i18n';
|
||||
import { themes } from '../constants/colors';
|
||||
|
@ -33,7 +33,7 @@ class WithoutServerView extends React.Component {
|
|||
static navigationOptions = () => ({
|
||||
title: 'Rocket.Chat',
|
||||
headerLeft: () => (
|
||||
<CancelModalButton
|
||||
<HeaderButton.CancelModal
|
||||
onPress={ShareExtension.close}
|
||||
testID='share-extension-close'
|
||||
/>
|
||||
|
|
|
@ -109,7 +109,6 @@
|
|||
"react-native-unimodules": "0.10.1",
|
||||
"react-native-vector-icons": "7.0.0",
|
||||
"react-native-webview": "10.3.2",
|
||||
"react-navigation-header-buttons": "3.0.5",
|
||||
"react-redux": "7.2.0",
|
||||
"reactotron-react-native": "5.0.0",
|
||||
"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={1000} />
|
||||
<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={1000} groupMentions={1} />
|
||||
<RoomItem name='user mentions > group mentions' alert unread={1000} userMentions={1} groupMentions={1} />
|
||||
<RoomItem alert name='thread unread' tunread={[1]} />
|
||||
<RoomItem name='user mentions > group mentions' alert unread={1} userMentions={1} groupMentions={1} />
|
||||
|
||||
<Separator title='Last Message' />
|
||||
<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 UiKitModal from './UiKitModal';
|
||||
import Markdown from './Markdown';
|
||||
import './HeaderButtons';
|
||||
import './UnreadBadge';
|
||||
import Avatar from './Avatar';
|
||||
// import RoomViewHeader from './RoomViewHeader';
|
||||
|
||||
|
|
|
@ -12891,7 +12891,7 @@ react-native-picker-select@7.0.0:
|
|||
dependencies:
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/react-native-platform-touchable/-/react-native-platform-touchable-1.1.1.tgz#fde4acc65eea585d28b164d0c3716a42129a68e4"
|
||||
integrity sha1-/eSsxl7qWF0osWTQw3FqQhKaaOQ=
|
||||
|
@ -13068,13 +13068,6 @@ react-native@^0.63.1:
|
|||
use-subscription "^1.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:
|
||||
version "2.11.1"
|
||||
resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.11.1.tgz#3c4bdfd8bc10d1c2b9a162e859bab8958f5b2644"
|
||||
|
|
Loading…
Reference in New Issue