Compare commits
4 Commits
develop
...
new.semant
Author | SHA1 | Date |
---|---|---|
|
a05198548e | |
|
81c2021be7 | |
|
6b4085043c | |
|
96e24551bb |
|
@ -345,26 +345,26 @@ jobs:
|
|||
steps:
|
||||
- checkout
|
||||
|
||||
- restore_cache: *restore-npm-cache-linux
|
||||
# - restore_cache: *restore-npm-cache-linux
|
||||
|
||||
- run: *install-npm-modules
|
||||
# - run: *install-npm-modules
|
||||
|
||||
- run:
|
||||
name: Lint
|
||||
command: |
|
||||
yarn lint
|
||||
# - run:
|
||||
# name: Lint
|
||||
# command: |
|
||||
# yarn lint
|
||||
|
||||
- run:
|
||||
name: Test
|
||||
command: |
|
||||
yarn test -w 8
|
||||
# - run:
|
||||
# name: Test
|
||||
# command: |
|
||||
# yarn test -w 8
|
||||
|
||||
- run:
|
||||
name: Codecov
|
||||
command: |
|
||||
yarn codecov
|
||||
# - run:
|
||||
# name: Codecov
|
||||
# command: |
|
||||
# yarn codecov
|
||||
|
||||
- save_cache: *save-npm-cache-linux
|
||||
# - save_cache: *save-npm-cache-linux
|
||||
|
||||
# Android builds
|
||||
android-build-experimental:
|
||||
|
|
|
@ -138,7 +138,7 @@ const ActionSheet = React.memo(
|
|||
handleComponent={renderHandle}
|
||||
enablePanDownToClose
|
||||
style={{ ...styles.container, ...bottomSheet }}
|
||||
backgroundStyle={{ backgroundColor: colors.focusedBackground }}
|
||||
backgroundStyle={{ backgroundColor: colors.backgroundColor }}
|
||||
onChange={index => index === -1 && onClose()}
|
||||
// We need this to allow horizontal swipe gesture inside the bottom sheet like in reaction picker
|
||||
enableContentPanningGesture={data?.enableContentPanningGesture ?? true}
|
||||
|
|
|
@ -126,7 +126,7 @@ const ActionSheetContentWithInputAndSubmit = ({
|
|||
/>
|
||||
) : null}
|
||||
<FooterButtons
|
||||
confirmBackgroundColor={confirmBackgroundColor || colors.actionTintColor}
|
||||
confirmBackgroundColor={confirmBackgroundColor || colors.tintColor}
|
||||
cancelAction={onCancel || hideActionSheet}
|
||||
confirmAction={() => onSubmit(inputValue)}
|
||||
cancelTitle={i18n.t('Cancel')}
|
||||
|
|
|
@ -24,7 +24,7 @@ const BottomSheetContent = React.memo(({ options, hasCancel, hide, children }: I
|
|||
hasCancel ? (
|
||||
<Touch
|
||||
onPress={hide}
|
||||
style={[styles.button, { backgroundColor: colors.auxiliaryBackground }]}
|
||||
style={[styles.button, { backgroundColor: colors.backgroundColor }]}
|
||||
accessibilityLabel={I18n.t('Cancel')}
|
||||
>
|
||||
<Text style={[styles.text, { color: colors.bodyText }]}>{I18n.t('Cancel')}</Text>
|
||||
|
@ -42,7 +42,7 @@ const BottomSheetContent = React.memo(({ options, hasCancel, hide, children }: I
|
|||
keyExtractor={item => item.title}
|
||||
bounces={true}
|
||||
renderItem={renderItem}
|
||||
style={{ backgroundColor: colors.focusedBackground }}
|
||||
style={{ backgroundColor: colors.backgroundColor }}
|
||||
keyboardDismissMode='interactive'
|
||||
indicatorStyle='black'
|
||||
contentContainerStyle={styles.content}
|
||||
|
|
|
@ -21,7 +21,7 @@ export const Item = React.memo(({ item, hide }: IActionSheetItem) => {
|
|||
};
|
||||
|
||||
return (
|
||||
<Touch onPress={onPress} style={[styles.item, { backgroundColor: themes[theme].focusedBackground }]} testID={item.testID}>
|
||||
<Touch onPress={onPress} style={[styles.item, { backgroundColor: themes[theme].backgroundColor }]} testID={item.testID}>
|
||||
{item.icon ? (
|
||||
<CustomIcon name={item.icon} size={20} color={item.danger ? themes[theme].dangerColor : themes[theme].bodyText} />
|
||||
) : null}
|
||||
|
|
|
@ -36,8 +36,8 @@ const BackgroundContainer = ({ text, loading }: IBackgroundContainer): React.Rea
|
|||
return (
|
||||
<View style={styles.container}>
|
||||
<ImageBackground source={{ uri: `message_empty_${theme}` }} style={styles.image} />
|
||||
{text && !loading ? <Text style={[styles.text, { color: themes[theme].auxiliaryTintColor }]}>{text}</Text> : null}
|
||||
{loading ? <ActivityIndicator style={styles.text} color={themes[theme].auxiliaryTintColor} /> : null}
|
||||
{text && !loading ? <Text style={[styles.text, { color: themes[theme].auxiliaryText }]}>{text}</Text> : null}
|
||||
{loading ? <ActivityIndicator style={styles.text} color={themes[theme].auxiliaryText} /> : null}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -61,7 +61,7 @@ const Button = ({
|
|||
disabled={disabled || loading}
|
||||
style={[
|
||||
styles.container,
|
||||
backgroundColor ? { backgroundColor } : { backgroundColor: isPrimary ? colors.actionTintColor : colors.backgroundColor },
|
||||
backgroundColor ? { backgroundColor } : { backgroundColor: isPrimary ? colors.tintColor : colors.backgroundColor },
|
||||
disabled && styles.disabled,
|
||||
style
|
||||
]}
|
||||
|
|
|
@ -68,7 +68,7 @@ const EmojiPicker = ({
|
|||
keyboardShouldPersistTaps: 'always',
|
||||
keyboardDismissMode: 'none'
|
||||
}}
|
||||
style={{ backgroundColor: colors.messageboxBackground }}
|
||||
style={{ backgroundColor: colors.backgroundColor }}
|
||||
>
|
||||
{categories.tabs.map((tab: any, i) => renderCategory(tab.category, i, tab.tabLabel))}
|
||||
</ScrollableTabView>
|
||||
|
|
|
@ -107,7 +107,7 @@ const NotifierComponent = React.memo(({ notification, isMasterDetail }: INotifie
|
|||
styles.container,
|
||||
(isMasterDetail || isLandscape) && styles.small,
|
||||
{
|
||||
backgroundColor: themes[theme].focusedBackground,
|
||||
backgroundColor: themes[theme].backgroundColor,
|
||||
borderColor: themes[theme].separatorColor,
|
||||
marginTop: insets.top
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ const ListHeader = React.memo(({ title, translateTitle = true }: IListHeader) =>
|
|||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={[styles.title, { color: themes[theme].infoText }]} numberOfLines={1}>
|
||||
<Text style={[styles.title, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>
|
||||
{translateTitle ? I18n.t(title) : title}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
|
@ -27,7 +27,7 @@ const ListInfo = React.memo(({ info, translateInfo = true }: IListInfo) => {
|
|||
const { theme } = useTheme();
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={[styles.text, { color: themes[theme].infoText }]}>{translateInfo ? I18n.t(info) : info}</Text>
|
||||
<Text style={[styles.text, { color: themes[theme].auxiliaryText }]}>{translateInfo ? I18n.t(info) : info}</Text>
|
||||
</View>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -84,7 +84,7 @@ export const ServiceList = () => (
|
|||
<ButtonService
|
||||
key={service._id}
|
||||
onPress={() => {}}
|
||||
backgroundColor={colors[theme].chatComponentBackground}
|
||||
backgroundColor={colors[theme].buttonBackgroundSecondaryDefault}
|
||||
buttonText={buttonText}
|
||||
icon={icon}
|
||||
name={service.name}
|
||||
|
|
|
@ -86,7 +86,7 @@ const Service = React.memo(
|
|||
);
|
||||
}
|
||||
|
||||
const backgroundColor = isSaml && service.buttonColor ? service.buttonColor : colors.chatComponentBackground;
|
||||
const backgroundColor = isSaml && service.buttonColor ? service.buttonColor : colors.buttonBackgroundSecondaryDefault;
|
||||
|
||||
return (
|
||||
<ButtonService
|
||||
|
|
|
@ -20,7 +20,7 @@ const ServicesSeparator = ({ services, separator, collapsed, onPress }: IService
|
|||
type='secondary'
|
||||
onPress={onPress}
|
||||
style={styles.options}
|
||||
color={colors.actionTintColor}
|
||||
color={colors.tintColor}
|
||||
/>
|
||||
<OrSeparator theme={theme} />
|
||||
</>
|
||||
|
|
|
@ -65,7 +65,7 @@ const HeaderItem = ({ item, onReaction, theme }: THeaderItem) => (
|
|||
<Touch
|
||||
testID={`message-actions-emoji-${item}`}
|
||||
onPress={() => onReaction({ emoji: item })}
|
||||
style={[styles.headerItem, { backgroundColor: themes[theme].auxiliaryBackground }]}
|
||||
style={[styles.headerItem, { backgroundColor: themes[theme].backgroundColor }]}
|
||||
>
|
||||
{typeof item === 'string' ? (
|
||||
<Text style={styles.headerIcon}>{shortnameToUnicode(`:${item}:`)}</Text>
|
||||
|
@ -109,12 +109,12 @@ const Header = React.memo(({ handleReaction, message, isMasterDetail }: IHeader)
|
|||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor: themes[theme].focusedBackground }]}>
|
||||
<View style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
<FlatList
|
||||
data={frequentlyUsed.slice(0, quantity)}
|
||||
renderItem={renderItem}
|
||||
ListFooterComponent={renderFooter}
|
||||
style={{ backgroundColor: themes[theme].focusedBackground }}
|
||||
style={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
keyExtractor={item => (typeof item === 'string' ? item : item.name)}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
scrollEnabled={false}
|
||||
|
|
|
@ -40,7 +40,7 @@ const Item = ({ item }: IMessageBoxCommandsPreviewItem) => {
|
|||
{loading ? <ActivityIndicator /> : null}
|
||||
</FastImage>
|
||||
) : (
|
||||
<CustomIcon name='attach' size={36} color={themes[theme].actionTintColor} />
|
||||
<CustomIcon name='attach' size={36} color={themes[theme].tintColor} />
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
|
|
@ -20,7 +20,7 @@ const FixedMentionItem = ({ item, onPress }: IMessageBoxFixedMentionItem) => {
|
|||
style={[
|
||||
styles.mentionItem,
|
||||
{
|
||||
backgroundColor: themes[theme].auxiliaryBackground,
|
||||
backgroundColor: themes[theme].backgroundColor,
|
||||
borderTopColor: themes[theme].separatorColor
|
||||
}
|
||||
]}
|
||||
|
|
|
@ -47,7 +47,7 @@ const MentionItemContent = React.memo(({ trackingType, item }: IMessageBoxMentio
|
|||
return (
|
||||
<>
|
||||
<Text style={[styles.cannedItem, { color: themes[theme].titleText }]}>!{item.shortcut}</Text>
|
||||
<Text numberOfLines={1} style={[styles.cannedMentionText, { color: themes[theme].auxiliaryTintColor }]}>
|
||||
<Text numberOfLines={1} style={[styles.cannedMentionText, { color: themes[theme].auxiliaryText }]}>
|
||||
{item.text}
|
||||
</Text>
|
||||
</>
|
||||
|
@ -92,7 +92,7 @@ const MentionItem = ({ item, trackingType }: IMessageBoxMentionItem) => {
|
|||
style={[
|
||||
styles.mentionItem,
|
||||
{
|
||||
backgroundColor: themes[theme].auxiliaryBackground,
|
||||
backgroundColor: themes[theme].backgroundColor,
|
||||
borderTopColor: themes[theme].separatorColor
|
||||
}
|
||||
]}
|
||||
|
|
|
@ -25,7 +25,7 @@ const Mentions = React.memo(
|
|||
return (
|
||||
<View testID='messagebox-container'>
|
||||
<FlatList
|
||||
style={[styles.mentionList, { backgroundColor: themes[theme].auxiliaryBackground }]}
|
||||
style={[styles.mentionList, { backgroundColor: themes[theme].backgroundColor }]}
|
||||
ListHeaderComponent={() => (
|
||||
<MentionHeaderList trackingType={trackingType} hasMentions={mentions.length > 0} loading={loading} />
|
||||
)}
|
||||
|
|
|
@ -202,7 +202,7 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
|
|||
return (
|
||||
<BorderlessButton onPress={this.startRecordingAudio} style={styles.actionButton} testID='messagebox-send-audio'>
|
||||
<View accessible accessibilityLabel={I18n.t('Send_audio_message')} accessibilityRole='button'>
|
||||
<CustomIcon name='microphone' size={24} color={themes[theme].auxiliaryTintColor} />
|
||||
<CustomIcon name='microphone' size={24} color={themes[theme].auxiliaryText} />
|
||||
</View>
|
||||
</BorderlessButton>
|
||||
);
|
||||
|
|
|
@ -66,7 +66,7 @@ const ReplyPreview = React.memo(
|
|||
const time = moment(message.ts).format(Message_TimeFormat);
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor: themes[theme].messageboxBackground }]}>
|
||||
<View style={[styles.messageContainer, { backgroundColor: themes[theme].chatComponentBackground }]}>
|
||||
<View style={[styles.messageContainer, { backgroundColor: themes[theme].surfaceTint }]}>
|
||||
<View style={styles.header}>
|
||||
<Text numberOfLines={1} style={[styles.username, { color: themes[theme].tintColor }]}>
|
||||
{useRealName ? message.u?.name : message.u?.username}
|
||||
|
|
|
@ -25,7 +25,7 @@ const BaseButton = ({ accessibilityLabel, icon, color, ...props }: IBaseButton)
|
|||
accessibilityLabel={accessibilityLabel ? i18n.t(accessibilityLabel) : accessibilityLabel}
|
||||
accessibilityRole='button'
|
||||
>
|
||||
<CustomIcon name={icon} size={24} color={color || themes[theme].auxiliaryTintColor} />
|
||||
<CustomIcon name={icon} size={24} color={color || themes[theme].auxiliaryText} />
|
||||
</View>
|
||||
</BorderlessButton>
|
||||
);
|
||||
|
|
|
@ -1272,7 +1272,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
|||
style={[
|
||||
styles.textArea,
|
||||
{ backgroundColor: themes[theme].messageboxBackground },
|
||||
!recording && editing && { backgroundColor: themes[theme].chatComponentBackground }
|
||||
!recording && editing && { backgroundColor: themes[theme].statusBackgroundWarning }
|
||||
]}
|
||||
testID='messagebox'
|
||||
>
|
||||
|
|
|
@ -15,7 +15,7 @@ const Tag = React.memo(({ name, testID }: ITag) => {
|
|||
|
||||
return (
|
||||
<View style={[styles.tagContainer, { backgroundColor: themes[theme].borderColor }]}>
|
||||
<Text style={[styles.tagText, { color: themes[theme].infoText }]} numberOfLines={1} testID={testID}>
|
||||
<Text style={[styles.tagText, { color: themes[theme].auxiliaryText }]} numberOfLines={1} testID={testID}>
|
||||
{name}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
|
@ -223,7 +223,7 @@ const Touchable = ({
|
|||
onPress={handlePress}
|
||||
testID={testID}
|
||||
style={{
|
||||
backgroundColor: isFocused ? colors.chatComponentBackground : colors.backgroundColor
|
||||
backgroundColor: isFocused ? colors.buttonBackgroundSecondaryDefault : colors.backgroundColor
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -23,7 +23,7 @@ const SafeAreaView = React.memo(({ style, children, vertical = true, ...props }:
|
|||
const { theme } = useTheme();
|
||||
return (
|
||||
<SafeAreaContext
|
||||
style={[styles.view, { backgroundColor: themes[theme].auxiliaryBackground }, style]}
|
||||
style={[styles.view, { backgroundColor: themes[theme].backgroundColor }, style]}
|
||||
edges={vertical ? ['right', 'left'] : undefined}
|
||||
{...props}
|
||||
>
|
||||
|
|
|
@ -28,9 +28,9 @@ const ServerItem = React.memo(({ item, onPress, onLongPress, hasCheck }: IServer
|
|||
onPress={onPress}
|
||||
onLongPress={() => onLongPress?.()}
|
||||
testID={`rooms-list-header-server-${item.id}`}
|
||||
android_ripple={{ color: themes[theme].bannerBackground }}
|
||||
android_ripple={{ color: themes[theme].buttonBackgroundSecondaryPress }}
|
||||
style={({ pressed }: { pressed: boolean }) => ({
|
||||
backgroundColor: isIOS && pressed ? themes[theme].bannerBackground : themes[theme].backgroundColor
|
||||
backgroundColor: isIOS && pressed ? themes[theme].buttonBackgroundSecondaryPress : themes[theme].backgroundColor
|
||||
})}
|
||||
>
|
||||
<View style={styles.serverItemContainer}>
|
||||
|
|
|
@ -136,7 +136,7 @@ export const FormTextInput = ({
|
|||
|
||||
{showClearInput ? (
|
||||
<Touchable onPress={onClearInput} style={[styles.iconContainer, styles.iconRight]} testID='clear-text-input'>
|
||||
<CustomIcon name='input-clear' size={20} color={colors.auxiliaryTintColor} />
|
||||
<CustomIcon name='input-clear' size={20} color={colors.auxiliaryText} />
|
||||
</Touchable>
|
||||
) : null}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ const ThreadDetails = ({ item, user, badgeColor, toggleFollowThread, style }: IT
|
|||
<CustomIcon
|
||||
size={24}
|
||||
name={isFollowing ? 'notification' : 'notification-disabled'}
|
||||
color={themes[theme].auxiliaryTintColor}
|
||||
color={themes[theme].auxiliaryText}
|
||||
/>
|
||||
</Touchable>
|
||||
</View>
|
||||
|
|
|
@ -136,7 +136,7 @@ const TwoFactor = React.memo(({ isMasterDetail }: { isMasterDetail: boolean }) =
|
|||
<Button
|
||||
title={I18n.t('Cancel')}
|
||||
type='secondary'
|
||||
backgroundColor={themes[theme].chatComponentBackground}
|
||||
backgroundColor={themes[theme].buttonBackgroundSecondaryDefault}
|
||||
style={styles.button}
|
||||
onPress={onCancel}
|
||||
/>
|
||||
|
|
|
@ -67,7 +67,7 @@ export const DatePicker = ({ element, language, action, context, loading, value,
|
|||
<Touchable
|
||||
onPress={() => onShow(!show)}
|
||||
style={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
>
|
||||
<View style={[styles.input, { borderColor: error ? themes[theme].dangerColor : themes[theme].separatorColor }]}>
|
||||
<Text style={[styles.inputText, { color: error ? themes[theme].dangerColor : themes[theme].titleText }]}>
|
||||
|
|
|
@ -29,8 +29,8 @@ const Chip = ({ item, onSelect, style }: IChip) => {
|
|||
<Touchable
|
||||
key={item.value}
|
||||
onPress={() => onSelect(item)}
|
||||
style={[styles.chip, { backgroundColor: colors.auxiliaryBackground }, style]}
|
||||
background={Touchable.Ripple(colors.bannerBackground)}
|
||||
style={[styles.chip, { backgroundColor: colors.backgroundColor }, style]}
|
||||
background={Touchable.Ripple(colors.buttonBackgroundSecondaryPress)}
|
||||
>
|
||||
<>
|
||||
{item.imageUrl ? <FastImage style={styles.chipImage} source={{ uri: item.imageUrl }} /> : null}
|
||||
|
|
|
@ -23,7 +23,7 @@ const Input = ({ children, onPress, loading, inputStyle, placeholder, disabled,
|
|||
<Touchable
|
||||
onPress={onPress}
|
||||
style={[{ backgroundColor: colors.backgroundColor }, styles.inputBorder, inputStyle]}
|
||||
background={Touchable.Ripple(colors.bannerBackground)}
|
||||
background={Touchable.Ripple(colors.buttonBackgroundSecondaryPress)}
|
||||
disabled={disabled}
|
||||
>
|
||||
<View style={[styles.input, styles.inputBorder, { borderColor: colors.separatorColor }, innerInputStyle]}>
|
||||
|
|
|
@ -71,7 +71,7 @@ export const MultiSelectContent = React.memo(
|
|||
testID='multi-select-search'
|
||||
onChangeText={handleSearch}
|
||||
placeholder={I18n.t('Search')}
|
||||
inputStyle={{ backgroundColor: colors.focusedBackground }}
|
||||
inputStyle={{ backgroundColor: colors.backgroundColor }}
|
||||
bottomSheet={isIOS}
|
||||
onSubmitEditing={() => {
|
||||
setTimeout(() => {
|
||||
|
|
|
@ -29,7 +29,7 @@ const styles = StyleSheet.create({
|
|||
const Option = ({ option: { text, value }, onOptionPress, parser, theme }: IOption) => (
|
||||
<Touchable
|
||||
onPress={() => onOptionPress({ value })}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
style={styles.option}
|
||||
>
|
||||
<Text>{parser.text(text)}</Text>
|
||||
|
@ -62,7 +62,7 @@ export const Overflow = ({ element, loading, action, parser }: IOverflow) => {
|
|||
<>
|
||||
<Touchable
|
||||
ref={ref => (touchable[blockId] = ref)}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
onPress={() => onShow(!show)}
|
||||
hitSlop={BUTTON_HIT_SLOP}
|
||||
style={styles.menu}
|
||||
|
|
|
@ -54,10 +54,10 @@ const UserItem = ({ name, username, onPress, testID, onLongPress, style, icon, i
|
|||
onLongPress={onLongPress}
|
||||
testID={testID}
|
||||
android_ripple={{
|
||||
color: colors.bannerBackground
|
||||
color: colors.buttonBackgroundSecondaryPress
|
||||
}}
|
||||
style={({ pressed }: any) => ({
|
||||
backgroundColor: isIOS && pressed ? colors.bannerBackground : 'transparent'
|
||||
backgroundColor: isIOS && pressed ? colors.buttonBackgroundSecondaryPress : 'transparent'
|
||||
})}
|
||||
>
|
||||
<View style={[styles.container, styles.button, style]}>
|
||||
|
@ -67,7 +67,7 @@ const UserItem = ({ name, username, onPress, testID, onLongPress, style, icon, i
|
|||
{name}
|
||||
</Text>
|
||||
</View>
|
||||
{icon ? <CustomIcon name={icon} size={22} color={iconColor || colors.actionTintColor} style={styles.icon} /> : null}
|
||||
{icon ? <CustomIcon name={icon} size={22} color={iconColor || colors.tintColor} style={styles.icon} /> : null}
|
||||
</View>
|
||||
</Pressable>
|
||||
);
|
||||
|
|
|
@ -37,7 +37,7 @@ const Link = React.memo(({ children, link, theme, onLinkPress }: ILink) => {
|
|||
|
||||
// if you have a [](https://rocket.chat) render https://rocket.chat
|
||||
return (
|
||||
<Text onPress={handlePress} onLongPress={onLongPress} style={{ ...styles.link, color: themes[theme].actionTintColor }}>
|
||||
<Text onPress={handlePress} onLongPress={onLongPress} style={{ ...styles.link, color: themes[theme].tintColor }}>
|
||||
{childLength !== 0 ? children : link}
|
||||
</Text>
|
||||
);
|
||||
|
|
|
@ -157,8 +157,8 @@ class Markdown extends PureComponent<IMarkdownProps, any> {
|
|||
{
|
||||
...styles.codeInline,
|
||||
color: themes[theme!].bodyText,
|
||||
backgroundColor: themes[theme!].bannerBackground,
|
||||
borderColor: themes[theme!].bannerBackground
|
||||
backgroundColor: themes[theme!].buttonBackgroundSecondaryPress,
|
||||
borderColor: themes[theme!].borderColor
|
||||
},
|
||||
...style
|
||||
]}
|
||||
|
@ -176,8 +176,8 @@ class Markdown extends PureComponent<IMarkdownProps, any> {
|
|||
{
|
||||
...styles.codeBlock,
|
||||
color: themes[theme!].bodyText,
|
||||
backgroundColor: themes[theme!].bannerBackground,
|
||||
borderColor: themes[theme!].bannerBackground
|
||||
backgroundColor: themes[theme!].buttonBackgroundSecondaryPress,
|
||||
borderColor: themes[theme!].borderColor
|
||||
},
|
||||
...style
|
||||
]}
|
||||
|
|
|
@ -18,7 +18,7 @@ const Code = ({ value }: ICodeProps): React.ReactElement => {
|
|||
style={[
|
||||
styles.codeBlock,
|
||||
{
|
||||
backgroundColor: colors.bannerBackground,
|
||||
backgroundColor: colors.buttonBackgroundSecondaryPress,
|
||||
borderColor: colors.borderColor
|
||||
}
|
||||
]}
|
||||
|
|
|
@ -26,7 +26,7 @@ const MessageImage = ({ img, theme }: TMessageImage) => (
|
|||
resizeMode={FastImage.resizeMode.cover}
|
||||
indicator={Progress.Pie}
|
||||
indicatorProps={{
|
||||
color: themes[theme].actionTintColor
|
||||
color: themes[theme].tintColor
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -19,7 +19,7 @@ const InlineCode = ({ value }: IInlineCodeProps) => {
|
|||
styles.codeInline,
|
||||
{
|
||||
color: themes[theme].bodyText,
|
||||
backgroundColor: themes[theme].bannerBackground,
|
||||
backgroundColor: themes[theme].buttonBackgroundSecondaryPress,
|
||||
borderColor: themes[theme].borderColor
|
||||
}
|
||||
]}
|
||||
|
|
|
@ -39,7 +39,7 @@ const Link = ({ value }: ILinkProps) => {
|
|||
};
|
||||
|
||||
return (
|
||||
<Text onPress={handlePress} onLongPress={onLongPress} style={[styles.link, { color: themes[theme].actionTintColor }]}>
|
||||
<Text onPress={handlePress} onLongPress={onLongPress} style={[styles.link, { color: themes[theme].tintColor }]}>
|
||||
{(block => {
|
||||
const blockArray = Array.isArray(block) ? block : [block];
|
||||
return blockArray.map(blockInArray => {
|
||||
|
|
|
@ -300,10 +300,7 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
|||
theme={theme}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
styles.audioContainer,
|
||||
{ backgroundColor: themes[theme].chatComponentBackground, borderColor: themes[theme].borderColor }
|
||||
]}
|
||||
style={[styles.audioContainer, { backgroundColor: themes[theme].surfaceTint, borderColor: themes[theme].borderColor }]}
|
||||
>
|
||||
<Button disabled={isReply} loading={loading} paused={paused} onPress={this.togglePlayPause} theme={theme} />
|
||||
<Slider
|
||||
|
|
|
@ -21,7 +21,7 @@ const Broadcast = React.memo(({ author, broadcast }: IMessageBroadcast) => {
|
|||
<View style={styles.buttonContainer}>
|
||||
<Touchable
|
||||
onPress={replyBroadcast}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
style={[styles.button, { backgroundColor: themes[theme].tintColor }]}
|
||||
hitSlop={BUTTON_HIT_SLOP}
|
||||
testID='message-broadcast-reply'
|
||||
|
|
|
@ -16,7 +16,7 @@ const CallButton = React.memo(({ callJitsi }: IMessageCallButton) => {
|
|||
<View style={styles.buttonContainer}>
|
||||
<Touchable
|
||||
onPress={callJitsi}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
style={[styles.button, { backgroundColor: themes[theme].tintColor }]}
|
||||
hitSlop={BUTTON_HIT_SLOP}
|
||||
>
|
||||
|
|
|
@ -125,7 +125,7 @@ const CollapsibleQuote = React.memo(
|
|||
|
||||
let {
|
||||
borderColor,
|
||||
chatComponentBackground: backgroundColor,
|
||||
surfaceTint: backgroundColor,
|
||||
collapsibleQuoteBorder,
|
||||
collapsibleChevron,
|
||||
headerTintColor
|
||||
|
@ -161,7 +161,7 @@ const CollapsibleQuote = React.memo(
|
|||
borderLeftWidth: 2
|
||||
}
|
||||
]}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
hitSlop={BUTTON_HIT_SLOP}
|
||||
>
|
||||
<View style={styles.touchableContainer}>
|
||||
|
|
|
@ -29,7 +29,7 @@ const Discussion = React.memo(
|
|||
<View style={styles.buttonContainer}>
|
||||
<Touchable
|
||||
onPress={onDiscussionPress}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
style={[styles.button, { backgroundColor: themes[theme].tintColor }]}
|
||||
hitSlop={BUTTON_HIT_SLOP}
|
||||
>
|
||||
|
|
|
@ -38,7 +38,7 @@ const Button = React.memo(({ children, onPress, disabled, theme }: IMessageButto
|
|||
disabled={disabled}
|
||||
onPress={onPress}
|
||||
style={styles.imageContainer}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
>
|
||||
{children}
|
||||
</Touchable>
|
||||
|
@ -51,7 +51,7 @@ export const MessageImage = React.memo(({ imgUri, theme }: { imgUri: string; the
|
|||
resizeMode={FastImage.resizeMode.cover}
|
||||
indicator={Progress.Pie}
|
||||
indicatorProps={{
|
||||
color: themes[theme].actionTintColor
|
||||
color: themes[theme].tintColor
|
||||
}}
|
||||
/>
|
||||
));
|
||||
|
|
|
@ -36,7 +36,7 @@ const AddReaction = React.memo(({ theme }: { theme: TSupportedThemes }) => {
|
|||
key='message-add-reaction'
|
||||
testID='message-add-reaction'
|
||||
style={[styles.reactionButton, { backgroundColor: themes[theme].backgroundColor }]}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
hitSlop={BUTTON_HIT_SLOP}
|
||||
>
|
||||
<View style={[styles.reactionContainer, { borderColor: themes[theme].borderColor }]}>
|
||||
|
@ -57,9 +57,9 @@ const Reaction = React.memo(({ reaction, getCustomEmoji, theme }: IMessageReacti
|
|||
testID={`message-reaction-${reaction.emoji}`}
|
||||
style={[
|
||||
styles.reactionButton,
|
||||
{ backgroundColor: reacted ? themes[theme].bannerBackground : themes[theme].backgroundColor }
|
||||
{ backgroundColor: reacted ? themes[theme].buttonBackgroundSecondaryPress : themes[theme].backgroundColor }
|
||||
]}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
hitSlop={BUTTON_HIT_SLOP}
|
||||
>
|
||||
<View style={[styles.reactionContainer, { borderColor: reacted ? themes[theme].tintColor : themes[theme].borderColor }]}>
|
||||
|
|
|
@ -100,7 +100,7 @@ const Title = React.memo(
|
|||
return (
|
||||
<View style={styles.authorContainer}>
|
||||
{attachment.author_name ? (
|
||||
<Text numberOfLines={1} style={[styles.author, { color: themes[theme].auxiliaryTintColor }]}>
|
||||
<Text numberOfLines={1} style={[styles.author, { color: themes[theme].auxiliaryText }]}>
|
||||
{attachment.author_name}
|
||||
</Text>
|
||||
) : null}
|
||||
|
@ -131,7 +131,7 @@ const Description = React.memo(
|
|||
return (
|
||||
<Markdown
|
||||
msg={text}
|
||||
style={[{ color: themes[theme].auxiliaryTintColor, fontSize: 14 }]}
|
||||
style={[{ color: themes[theme].auxiliaryText, fontSize: 14 }]}
|
||||
username={user.username}
|
||||
getCustomEmoji={getCustomEmoji}
|
||||
theme={theme}
|
||||
|
@ -242,7 +242,7 @@ const Reply = React.memo(
|
|||
borderColor
|
||||
}
|
||||
]}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
disabled={loading}
|
||||
>
|
||||
<View style={styles.attachmentContainer}>
|
||||
|
@ -251,7 +251,7 @@ const Reply = React.memo(
|
|||
attachments={attachment.attachments}
|
||||
getCustomEmoji={getCustomEmoji}
|
||||
timeFormat={timeFormat}
|
||||
style={[{ color: themes[theme].auxiliaryTintColor, fontSize: 14, marginBottom: 8 }]}
|
||||
style={[{ color: themes[theme].auxiliaryText, fontSize: 14, marginBottom: 8 }]}
|
||||
isReply
|
||||
id={messageId}
|
||||
/>
|
||||
|
@ -263,7 +263,10 @@ const Reply = React.memo(
|
|||
<View
|
||||
style={[
|
||||
styles.backdrop,
|
||||
{ backgroundColor: themes[theme].bannerBackground, opacity: themes[theme].attachmentLoadingOpacity }
|
||||
{
|
||||
backgroundColor: themes[theme].buttonBackgroundSecondaryPress,
|
||||
opacity: themes[theme].attachmentLoadingOpacity
|
||||
}
|
||||
]}
|
||||
></View>
|
||||
<RCActivityIndicator />
|
||||
|
|
|
@ -116,11 +116,11 @@ const Url = React.memo(
|
|||
index > 0 && styles.marginTop,
|
||||
styles.container,
|
||||
{
|
||||
backgroundColor: themes[theme].chatComponentBackground,
|
||||
backgroundColor: themes[theme].surfaceTint,
|
||||
borderColor: themes[theme].borderColor
|
||||
}
|
||||
]}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
>
|
||||
<>
|
||||
<UrlImage image={url.image} />
|
||||
|
|
|
@ -88,7 +88,7 @@ const Video = React.memo(
|
|||
disabled={isReply}
|
||||
onPress={onPress}
|
||||
style={[styles.button, { backgroundColor: themes[theme].videoBackground }]}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
background={Touchable.Ripple(themes[theme].buttonBackgroundSecondaryPress)}
|
||||
>
|
||||
{loading ? <RCActivityIndicator /> : <CustomIcon name='play-filled' size={54} color={themes[theme].buttonText} />}
|
||||
</Touchable>
|
||||
|
|
|
@ -21,7 +21,7 @@ const OmnichannelQueue = ({ queueSize, onPress }: IOmnichannelQueue) => {
|
|||
<List.Item
|
||||
title='Omnichannel_queue'
|
||||
heightContainer={50}
|
||||
left={() => <List.Icon name='queue' size={24} color={themes[theme].auxiliaryTintColor} />}
|
||||
left={() => <List.Icon name='queue' size={24} color={themes[theme].auxiliaryText} />}
|
||||
color={themes[theme].bodyText}
|
||||
onPress={queueSize ? onPress : undefined}
|
||||
styleTitle={styles.titleOmnichannelQueue}
|
||||
|
@ -33,7 +33,7 @@ const OmnichannelQueue = ({ queueSize, onPress }: IOmnichannelQueue) => {
|
|||
<CustomIcon name='chevron-right' style={styles.actionIndicator} color={themes[theme].bodyText} size={24} />
|
||||
</>
|
||||
) : (
|
||||
<Text style={[styles.emptyText, { color: themes[theme].auxiliaryTintColor }]}>{i18n.t('Empty')}</Text>
|
||||
<Text style={[styles.emptyText, { color: themes[theme].auxiliaryText }]}>{i18n.t('Empty')}</Text>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
|
|
@ -21,55 +21,58 @@ const mentions = {
|
|||
|
||||
export const colors = {
|
||||
light: {
|
||||
backgroundColor: '#ffffff',
|
||||
focusedBackground: '#ffffff',
|
||||
chatComponentBackground: '#f3f4f5',
|
||||
auxiliaryBackground: '#efeff4',
|
||||
bannerBackground: '#f1f2f4',
|
||||
titleText: '#0d0e12',
|
||||
bodyText: '#2f343d',
|
||||
backdropColor: '#000000',
|
||||
dangerColor: '#f5455c',
|
||||
successColor: '#2de0a5',
|
||||
borderColor: '#e1e5e8',
|
||||
controlText: '#54585e',
|
||||
auxiliaryText: '#9ca2a8',
|
||||
infoText: '#6d6d72',
|
||||
tintColor: '#1d74f5',
|
||||
tintActive: '#549df9',
|
||||
tintDisabled: '#88B4F5',
|
||||
auxiliaryTintColor: '#6C727A',
|
||||
actionTintColor: '#1d74f5',
|
||||
separatorColor: '#cbcbcc',
|
||||
navbarBackground: '#ffffff',
|
||||
headerBorder: '#B2B2B2',
|
||||
headerBackground: '#EEEFF1',
|
||||
headerSecondaryBackground: '#ffffff',
|
||||
headerTintColor: '#6C727A',
|
||||
headerTitleColor: '#0C0D0F',
|
||||
headerSecondaryText: '#1d74f5',
|
||||
toastBackground: '#0C0D0F',
|
||||
videoBackground: '#1f2329',
|
||||
favoriteBackground: '#ffbb00',
|
||||
hideBackground: '#54585e',
|
||||
messageboxBackground: '#ffffff',
|
||||
searchboxBackground: '#E6E6E7',
|
||||
buttonBackground: '#414852',
|
||||
buttonText: '#ffffff',
|
||||
passcodeBackground: '#EEEFF1',
|
||||
passcodeButtonActive: '#E4E7EA',
|
||||
passcodeLockIcon: '#6C727A',
|
||||
passcodePrimary: '#2F343D',
|
||||
passcodeSecondary: '#6C727A',
|
||||
passcodeDotEmpty: '#CBCED1',
|
||||
passcodeDotFull: '#6C727A',
|
||||
previewBackground: '#1F2329',
|
||||
previewTintColor: '#f9f9f9',
|
||||
backdropOpacity: 0.3,
|
||||
attachmentLoadingOpacity: 0.7,
|
||||
collapsibleQuoteBorder: '#CBCED1',
|
||||
collapsibleChevron: '#6C727A',
|
||||
cancelButton: '#E4E7EA',
|
||||
backgroundColor: '#ffffff', // surface-light
|
||||
// focusedBackground: '#ffffff', // removed in favor of backgroundColor
|
||||
// chatComponentBackground: 'red',
|
||||
surfaceTint: '#F7F8FA',
|
||||
buttonBackgroundSecondaryDefault: '#E4E7EA',
|
||||
buttonBackgroundSecondaryPress: '#9EA2A8',
|
||||
statusBackgroundWarning: '#FFECAD',
|
||||
// auxiliaryBackground: '#efeff4', // removed in favor of backgroundColor
|
||||
// bannerBackground: '#f1f2f4', // removed in favor of buttonBackgroundSecondaryPress
|
||||
titleText: '#1F2329', // fontTitleLabels
|
||||
bodyText: '#2F343D', // fontDefault
|
||||
auxiliaryText: '#6C727A', // fontSecondaryInfo
|
||||
// controlText: '#54585e', // removed in favor of auxiliaryText
|
||||
// infoText: '#6d6d72', // removed in favor of auxiliaryText
|
||||
separatorColor: '#CBCED1', // strokeLight
|
||||
tintColor: '#156FF5', // buttonBackgroundPrimaryDefault
|
||||
// tintColor: '#549df9', // removed in favor of tintColor
|
||||
// actionTintColor: '#1d74f5', // removed in favor of tintColor
|
||||
tintDisabled: '#D1EBFE', // buttonBackgroundDisabled
|
||||
// auxiliaryTintColor: '#6C727A', // removed in favor of auxiliaryText
|
||||
backdropOpacity: 0.7,
|
||||
dangerColor: '#EC0D2A', // buttonBackgroundDangerDefault
|
||||
// successColor: '#2de0a5', not used
|
||||
borderColor: '#9EA2A8', // strokeMedium
|
||||
navbarBackground: '#F7F8FA', // surfaceTint
|
||||
headerBorder: '#CBCED1', // strokeLight
|
||||
headerBackground: '#F7F8FA', // surfaceTint
|
||||
// headerSecondaryBackground: '#ffffff', removed in favor of headerBackground
|
||||
headerTintColor: '#6C727A', // fontSecondaryInfo
|
||||
headerTitleColor: '#1F2329', // fontTitleLabels
|
||||
// headerSecondaryText: '#1d74f5', not used
|
||||
toastBackground: '#0C0D0F', // strokeExtraDark
|
||||
videoBackground: '#0C0D0F', // strokeExtraDark
|
||||
favoriteBackground: '#ffbb00', // tbd
|
||||
hideBackground: '#54585e', // tbd
|
||||
messageboxBackground: '#F7F8FA', // surfaceTint
|
||||
// searchboxBackground: '#E6E6E7', removed in favor of buttonBackgroundSecondaryDefault
|
||||
// buttonBackground: '#414852', buttonBackgroundSecondaryDefault
|
||||
buttonText: '#ffffff', // buttonFontOnPrimary
|
||||
passcodeBackground: '#F7F8FA', // surfaceTint
|
||||
passcodeButtonActive: '#9EA2A8', // buttonBackgroundSecondaryPress
|
||||
passcodeLockIcon: '#1F2329', // fontTitleLabels
|
||||
passcodePrimary: '#1F2329', // fontTitleLabels
|
||||
passcodeSecondary: '#6C727A', // fontSecondaryInfo
|
||||
passcodeDotEmpty: '#CBCED1', // surfaceLight
|
||||
passcodeDotFull: '#9EA2A8', // surfaceMedium
|
||||
previewBackground: '#0C0D0F', // strokeExtraDark
|
||||
previewTintColor: '#ffffff', // buttonFontOnPrimary change later
|
||||
attachmentLoadingOpacity: 0.7, // tbd
|
||||
collapsibleQuoteBorder: '#CBCED1', // strokeLight
|
||||
collapsibleChevron: '#6C727A', // fontSecondaryInfo
|
||||
cancelButton: '#E4E7EA', // buttonBackgroundSecondaryDefault
|
||||
conferenceCallBorder: '#F2F3F5',
|
||||
conferenceCallBackground: '#F7F8FA',
|
||||
conferenceCallOngoingPhoneBackground: '#C0F6E4',
|
||||
|
@ -105,7 +108,7 @@ export const colors = {
|
|||
auxiliaryText: '#9297a2',
|
||||
infoText: '#6D6D72',
|
||||
tintColor: '#1d74f5',
|
||||
tintActive: '#549df9',
|
||||
// tintColor: '#549df9',
|
||||
tintDisabled: '#88B4F5',
|
||||
auxiliaryTintColor: '#f9f9f9',
|
||||
actionTintColor: '#1d74f5',
|
||||
|
@ -174,7 +177,7 @@ export const colors = {
|
|||
auxiliaryText: '#b2b8c6',
|
||||
infoText: '#6d6d72',
|
||||
tintColor: '#1e9bfe',
|
||||
tintActive: '#76b7fc',
|
||||
// tintColor: '#76b7fc',
|
||||
tintDisabled: '#88B4F5', // TODO: Evaluate this with design team
|
||||
auxiliaryTintColor: '#f9f9f9',
|
||||
actionTintColor: '#1e9bfe',
|
||||
|
|
|
@ -15,9 +15,9 @@ export const defaultHeader = {
|
|||
cardStyle: { backgroundColor: 'transparent' }
|
||||
};
|
||||
|
||||
export const cardStyle = {
|
||||
backgroundColor: 'rgba(0,0,0,0)'
|
||||
};
|
||||
// export const cardStyle = {
|
||||
// backgroundColor: 'rgba(0,0,0,0)'
|
||||
// };
|
||||
|
||||
export const borderBottom: any = (theme: TSupportedThemes) => ({
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import React from 'react';
|
||||
import { RectButton, RectButtonProps } from 'react-native-gesture-handler';
|
||||
|
||||
import { TSupportedThemes } from '../../../theme';
|
||||
import { themes } from '../../constants';
|
||||
|
||||
interface ITouchProps extends RectButtonProps {
|
||||
children: React.ReactNode;
|
||||
theme: TSupportedThemes;
|
||||
accessibilityLabel?: string;
|
||||
testID?: string;
|
||||
}
|
||||
|
||||
class Touch extends React.Component<ITouchProps> {
|
||||
private ref: any;
|
||||
|
||||
setNativeProps(props: ITouchProps): void {
|
||||
this.ref.setNativeProps(props);
|
||||
}
|
||||
|
||||
getRef = (ref: RectButton): void => {
|
||||
this.ref = ref;
|
||||
};
|
||||
|
||||
render(): JSX.Element {
|
||||
const { children, onPress, theme, underlayColor, ...props } = this.props;
|
||||
|
||||
return (
|
||||
<RectButton
|
||||
ref={this.getRef}
|
||||
onPress={onPress}
|
||||
activeOpacity={1}
|
||||
underlayColor={underlayColor || themes[theme].buttonBackgroundSecondaryPress}
|
||||
rippleColor={themes[theme].buttonBackgroundSecondaryPress}
|
||||
{...props}>
|
||||
{children}
|
||||
</RectButton>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Touch;
|
|
@ -124,12 +124,12 @@ const CannedResponseDetail = ({ navigation, route }: ICannedResponseDetailProps)
|
|||
<View style={styles.cannedTagContainer}>
|
||||
{cannedResponse?.tags?.length > 0 ? (
|
||||
cannedResponse.tags.map(t => (
|
||||
<View style={[styles.cannedTagWrap, { backgroundColor: themes[theme].searchboxBackground }]}>
|
||||
<Text style={[styles.cannedTag, { color: themes[theme].auxiliaryTintColor }]}>{t}</Text>
|
||||
<View style={[styles.cannedTagWrap, { backgroundColor: themes[theme].buttonBackgroundSecondaryDefault }]}>
|
||||
<Text style={[styles.cannedTag, { color: themes[theme].auxiliaryText }]}>{t}</Text>
|
||||
</View>
|
||||
))
|
||||
) : (
|
||||
<Text style={[styles.cannedText, { color: themes[theme].auxiliaryTintColor }]}>-</Text>
|
||||
<Text style={[styles.cannedText, { color: themes[theme].auxiliaryText }]}>-</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
|
|
@ -32,26 +32,26 @@ const CannedResponseItem = ({
|
|||
<View style={styles.cannedRow}>
|
||||
<View style={styles.cannedWrapShortcutScope}>
|
||||
<Text style={[styles.cannedShortcut, { color: themes[theme].titleText }]}>!{shortcut}</Text>
|
||||
<Text style={[styles.cannedScope, { color: themes[theme].auxiliaryTintColor }]}>{scope}</Text>
|
||||
<Text style={[styles.cannedScope, { color: themes[theme].auxiliaryText }]}>{scope}</Text>
|
||||
</View>
|
||||
|
||||
<Button
|
||||
title={I18n.t('Use')}
|
||||
fontSize={12}
|
||||
color={themes[theme].titleText}
|
||||
style={[styles.cannedUseButton, { backgroundColor: themes[theme].chatComponentBackground }]}
|
||||
style={[styles.cannedUseButton, { backgroundColor: themes[theme].buttonBackgroundSecondaryDefault }]}
|
||||
onPress={onPressUse}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Text ellipsizeMode='tail' numberOfLines={2} style={[styles.cannedText, { color: themes[theme].auxiliaryTintColor }]}>
|
||||
<Text ellipsizeMode='tail' numberOfLines={2} style={[styles.cannedText, { color: themes[theme].auxiliaryText }]}>
|
||||
“{text}”
|
||||
</Text>
|
||||
<View style={styles.cannedTagContainer}>
|
||||
{tags?.length > 0
|
||||
? tags.map(t => (
|
||||
<View style={[styles.cannedTagWrap, { backgroundColor: themes[theme].searchboxBackground }]}>
|
||||
<Text style={[styles.cannedTag, { color: themes[theme].auxiliaryTintColor }]}>{t}</Text>
|
||||
<View style={[styles.cannedTagWrap, { backgroundColor: themes[theme].buttonBackgroundSecondaryDefault }]}>
|
||||
<Text style={[styles.cannedTag, { color: themes[theme].auxiliaryText }]}>{t}</Text>
|
||||
</View>
|
||||
))
|
||||
: null}
|
||||
|
|
|
@ -73,7 +73,7 @@ const CloseLivechatView = ({ navigation, route }: IBaseScreen<ChatsStackParamLis
|
|||
|
||||
return (
|
||||
<KeyboardView
|
||||
style={{ backgroundColor: colors.auxiliaryBackground }}
|
||||
style={{ backgroundColor: colors.backgroundColor }}
|
||||
contentContainerStyle={sharedStyles.container}
|
||||
keyboardVerticalOffset={128}
|
||||
>
|
||||
|
|
|
@ -0,0 +1,429 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { FlatList, ScrollView, StyleSheet, Switch, Text, View, SwitchProps } from 'react-native';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import * as List from '../containers/List';
|
||||
import { TextInput } from '../containers/TextInput';
|
||||
import Loading from '../containers/Loading';
|
||||
import { createChannelRequest } from '../actions/createChannel';
|
||||
import { removeUser } from '../actions/selectedUsers';
|
||||
import KeyboardView from '../containers/KeyboardView';
|
||||
import scrollPersistTaps from '../lib/methods/helpers/scrollPersistTaps';
|
||||
import I18n from '../i18n';
|
||||
import UserItem from '../containers/UserItem';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import { SWITCH_TRACK_COLOR, themes } from '../lib/constants';
|
||||
import { withTheme } from '../theme';
|
||||
import { Review } from '../lib/methods/helpers/review';
|
||||
import { getUserSelector } from '../selectors/login';
|
||||
import { events, logEvent } from '../lib/methods/helpers/log';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
import sharedStyles from './Styles';
|
||||
import { ChatsStackParamList } from '../stacks/types';
|
||||
import { IApplicationState, IBaseScreen, IUser } from '../definitions';
|
||||
import { hasPermission } from '../lib/methods/helpers';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1
|
||||
},
|
||||
list: {
|
||||
width: '100%'
|
||||
},
|
||||
input: {
|
||||
height: 54,
|
||||
paddingHorizontal: 18,
|
||||
fontSize: 17,
|
||||
...sharedStyles.textRegular
|
||||
},
|
||||
switchContainer: {
|
||||
height: 54,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
flexDirection: 'row',
|
||||
paddingHorizontal: 18
|
||||
},
|
||||
label: {
|
||||
fontSize: 17,
|
||||
...sharedStyles.textMedium
|
||||
},
|
||||
invitedHeader: {
|
||||
marginTop: 18,
|
||||
marginHorizontal: 15,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center'
|
||||
},
|
||||
invitedTitle: {
|
||||
fontSize: 18,
|
||||
...sharedStyles.textSemibold,
|
||||
lineHeight: 41
|
||||
},
|
||||
invitedCount: {
|
||||
fontSize: 14,
|
||||
...sharedStyles.textRegular
|
||||
}
|
||||
});
|
||||
|
||||
interface IOtherUser {
|
||||
_id: string;
|
||||
name: string;
|
||||
fname: string;
|
||||
}
|
||||
|
||||
interface ICreateChannelViewState {
|
||||
channelName: string;
|
||||
type: boolean;
|
||||
readOnly: boolean;
|
||||
encrypted: boolean;
|
||||
broadcast: boolean;
|
||||
isTeam: boolean;
|
||||
permissions: boolean[];
|
||||
}
|
||||
|
||||
interface ICreateChannelViewProps extends IBaseScreen<ChatsStackParamList, 'CreateChannelView'> {
|
||||
baseUrl: string;
|
||||
error: object;
|
||||
failure: boolean;
|
||||
isFetching: boolean;
|
||||
encryptionEnabled: boolean;
|
||||
users: IOtherUser[];
|
||||
user: IUser;
|
||||
teamId: string;
|
||||
createPublicChannelPermission: string[] | undefined;
|
||||
createPrivateChannelPermission: string[] | undefined;
|
||||
}
|
||||
|
||||
interface ISwitch extends SwitchProps {
|
||||
id: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
class CreateChannelView extends React.Component<ICreateChannelViewProps, ICreateChannelViewState> {
|
||||
private teamId?: string;
|
||||
|
||||
constructor(props: ICreateChannelViewProps) {
|
||||
super(props);
|
||||
const { route } = this.props;
|
||||
const isTeam = route?.params?.isTeam || false;
|
||||
this.teamId = route?.params?.teamId;
|
||||
this.state = {
|
||||
channelName: '',
|
||||
type: true,
|
||||
readOnly: false,
|
||||
encrypted: false,
|
||||
broadcast: false,
|
||||
isTeam,
|
||||
permissions: []
|
||||
};
|
||||
this.setHeader();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.handleHasPermission();
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps: ICreateChannelViewProps, nextState: ICreateChannelViewState) {
|
||||
const { channelName, type, readOnly, broadcast, encrypted, permissions } = this.state;
|
||||
const { users, isFetching, encryptionEnabled, theme, createPublicChannelPermission, createPrivateChannelPermission } =
|
||||
this.props;
|
||||
if (nextProps.theme !== theme) {
|
||||
return true;
|
||||
}
|
||||
if (nextState.channelName !== channelName) {
|
||||
return true;
|
||||
}
|
||||
if (nextState.type !== type) {
|
||||
return true;
|
||||
}
|
||||
if (nextState.readOnly !== readOnly) {
|
||||
return true;
|
||||
}
|
||||
if (nextState.encrypted !== encrypted) {
|
||||
return true;
|
||||
}
|
||||
if (nextState.broadcast !== broadcast) {
|
||||
return true;
|
||||
}
|
||||
if (nextState.permissions !== permissions) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.isFetching !== isFetching) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.encryptionEnabled !== encryptionEnabled) {
|
||||
return true;
|
||||
}
|
||||
if (!dequal(nextProps.createPublicChannelPermission, createPublicChannelPermission)) {
|
||||
return true;
|
||||
}
|
||||
if (!dequal(nextProps.createPrivateChannelPermission, createPrivateChannelPermission)) {
|
||||
return true;
|
||||
}
|
||||
if (!dequal(nextProps.users, users)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: ICreateChannelViewProps) {
|
||||
const { createPublicChannelPermission, createPrivateChannelPermission } = this.props;
|
||||
if (
|
||||
!dequal(createPublicChannelPermission, prevProps.createPublicChannelPermission) ||
|
||||
!dequal(createPrivateChannelPermission, prevProps.createPrivateChannelPermission)
|
||||
) {
|
||||
this.handleHasPermission();
|
||||
}
|
||||
}
|
||||
|
||||
setHeader = () => {
|
||||
const { navigation } = this.props;
|
||||
const { isTeam } = this.state;
|
||||
|
||||
navigation.setOptions({
|
||||
title: isTeam ? I18n.t('Create_Team') : I18n.t('Create_Channel')
|
||||
});
|
||||
};
|
||||
|
||||
toggleRightButton = (channelName: string) => {
|
||||
const { navigation } = this.props;
|
||||
navigation.setOptions({
|
||||
headerRight: () =>
|
||||
channelName.trim().length > 0 && (
|
||||
<HeaderButton.Container>
|
||||
<HeaderButton.Item title={I18n.t('Create')} onPress={this.submit} testID='create-channel-submit' />
|
||||
</HeaderButton.Container>
|
||||
)
|
||||
});
|
||||
};
|
||||
|
||||
onChangeText = (channelName: string) => {
|
||||
this.toggleRightButton(channelName);
|
||||
this.setState({ channelName });
|
||||
};
|
||||
|
||||
submit = () => {
|
||||
const { channelName, type, readOnly, broadcast, encrypted, isTeam } = this.state;
|
||||
const { users: usersProps, isFetching, dispatch } = this.props;
|
||||
|
||||
if (!channelName.trim() || isFetching) {
|
||||
return;
|
||||
}
|
||||
|
||||
// transform users object into array of usernames
|
||||
const users = usersProps.map(user => user.name);
|
||||
|
||||
// create channel or team
|
||||
const data = {
|
||||
name: channelName,
|
||||
users,
|
||||
type,
|
||||
readOnly,
|
||||
broadcast,
|
||||
encrypted,
|
||||
isTeam,
|
||||
teamId: this.teamId
|
||||
};
|
||||
dispatch(createChannelRequest(data));
|
||||
Review.pushPositiveEvent();
|
||||
};
|
||||
|
||||
removeUser = (user: IOtherUser) => {
|
||||
logEvent(events.CR_REMOVE_USER);
|
||||
const { dispatch } = this.props;
|
||||
dispatch(removeUser(user));
|
||||
};
|
||||
|
||||
renderSwitch = ({ id, value, label, onValueChange, disabled = false }: ISwitch) => {
|
||||
const { theme } = this.props;
|
||||
return (
|
||||
<View style={[styles.switchContainer, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
<Text style={[styles.label, { color: themes[theme].titleText }]}>{I18n.t(label)}</Text>
|
||||
<Switch
|
||||
value={value}
|
||||
onValueChange={onValueChange}
|
||||
testID={`create-channel-${id}`}
|
||||
trackColor={SWITCH_TRACK_COLOR}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
handleHasPermission = async () => {
|
||||
const { createPublicChannelPermission, createPrivateChannelPermission } = this.props;
|
||||
const permissions = [createPublicChannelPermission, createPrivateChannelPermission];
|
||||
const permissionsToCreate = await hasPermission(permissions);
|
||||
this.setState({ permissions: permissionsToCreate });
|
||||
};
|
||||
|
||||
renderType() {
|
||||
const { type, isTeam, permissions } = this.state;
|
||||
const isDisabled = permissions.filter(r => r === true).length <= 1;
|
||||
|
||||
return this.renderSwitch({
|
||||
id: 'type',
|
||||
value: permissions[1] ? type : false,
|
||||
disabled: isDisabled,
|
||||
label: isTeam ? 'Private_Team' : 'Private_Channel',
|
||||
onValueChange: (value: boolean) => {
|
||||
logEvent(events.CR_TOGGLE_TYPE);
|
||||
// If we set the channel as public, encrypted status should be false
|
||||
this.setState(({ encrypted }) => ({ type: value, encrypted: value && encrypted }));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
renderReadOnly() {
|
||||
const { readOnly, broadcast, isTeam } = this.state;
|
||||
|
||||
return this.renderSwitch({
|
||||
id: 'readonly',
|
||||
value: readOnly,
|
||||
label: isTeam ? 'Read_Only_Team' : 'Read_Only_Channel',
|
||||
onValueChange: value => {
|
||||
logEvent(events.CR_TOGGLE_READ_ONLY);
|
||||
this.setState({ readOnly: value });
|
||||
},
|
||||
disabled: broadcast
|
||||
});
|
||||
}
|
||||
|
||||
renderEncrypted() {
|
||||
const { type, encrypted } = this.state;
|
||||
const { encryptionEnabled } = this.props;
|
||||
|
||||
if (!encryptionEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.renderSwitch({
|
||||
id: 'encrypted',
|
||||
value: encrypted,
|
||||
label: 'Encrypted',
|
||||
onValueChange: value => {
|
||||
logEvent(events.CR_TOGGLE_ENCRYPTED);
|
||||
this.setState({ encrypted: value });
|
||||
},
|
||||
disabled: !type
|
||||
});
|
||||
}
|
||||
|
||||
renderBroadcast() {
|
||||
const { broadcast, readOnly, isTeam } = this.state;
|
||||
|
||||
return this.renderSwitch({
|
||||
id: 'broadcast',
|
||||
value: broadcast,
|
||||
label: isTeam ? 'Broadcast_Team' : 'Broadcast_Channel',
|
||||
onValueChange: value => {
|
||||
logEvent(events.CR_TOGGLE_BROADCAST);
|
||||
this.setState({
|
||||
broadcast: value,
|
||||
readOnly: value ? true : readOnly
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
renderItem = ({ item }: { item: IOtherUser }) => {
|
||||
const { theme } = this.props;
|
||||
|
||||
return (
|
||||
<UserItem
|
||||
name={item.fname}
|
||||
username={item.name}
|
||||
onPress={() => this.removeUser(item)}
|
||||
testID={`create-channel-view-item-${item.name}`}
|
||||
icon='check'
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
renderInvitedList = () => {
|
||||
const { users, theme } = this.props;
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
data={users}
|
||||
extraData={users}
|
||||
keyExtractor={item => item._id}
|
||||
style={[
|
||||
styles.list,
|
||||
sharedStyles.separatorVertical,
|
||||
{
|
||||
backgroundColor: themes[theme].backgroundColor,
|
||||
borderColor: themes[theme].separatorColor
|
||||
}
|
||||
]}
|
||||
renderItem={this.renderItem}
|
||||
ItemSeparatorComponent={List.Separator}
|
||||
keyboardShouldPersistTaps='always'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { channelName, isTeam } = this.state;
|
||||
const { users, isFetching, theme } = this.props;
|
||||
const userCount = users.length;
|
||||
|
||||
return (
|
||||
<KeyboardView
|
||||
style={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
contentContainerStyle={[sharedStyles.container, styles.container]}
|
||||
keyboardVerticalOffset={128}>
|
||||
<StatusBar />
|
||||
<SafeAreaView testID='create-channel-view'>
|
||||
<ScrollView {...scrollPersistTaps}>
|
||||
<View style={[sharedStyles.separatorVertical, { borderColor: themes[theme].separatorColor }]}>
|
||||
<TextInput
|
||||
autoFocus
|
||||
style={[styles.input, { backgroundColor: themes[theme].backgroundColor }]}
|
||||
value={channelName}
|
||||
onChangeText={this.onChangeText}
|
||||
placeholder={isTeam ? I18n.t('Team_Name') : I18n.t('Channel_Name')}
|
||||
returnKeyType='done'
|
||||
testID='create-channel-name'
|
||||
autoCorrect={false}
|
||||
autoCapitalize='none'
|
||||
underlineColorAndroid='transparent'
|
||||
/>
|
||||
<List.Separator />
|
||||
{this.renderType()}
|
||||
<List.Separator />
|
||||
{this.renderReadOnly()}
|
||||
<List.Separator />
|
||||
{this.renderEncrypted()}
|
||||
<List.Separator />
|
||||
{this.renderBroadcast()}
|
||||
</View>
|
||||
<View style={styles.invitedHeader}>
|
||||
<Text style={[styles.invitedTitle, { color: themes[theme].titleText }]}>{I18n.t('Invite')}</Text>
|
||||
<Text style={[styles.invitedCount, { color: themes[theme].auxiliaryText }]}>
|
||||
{userCount === 1 ? I18n.t('1_user') : I18n.t('N_users', { n: userCount })}
|
||||
</Text>
|
||||
</View>
|
||||
{this.renderInvitedList()}
|
||||
<Loading visible={isFetching} />
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
</KeyboardView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: IApplicationState) => ({
|
||||
baseUrl: state.server.server,
|
||||
isFetching: state.createChannel.isFetching,
|
||||
encryptionEnabled: state.encryption.enabled,
|
||||
users: state.selectedUsers.users,
|
||||
user: getUserSelector(state),
|
||||
createPublicChannelPermission: state.permissions['create-c'],
|
||||
createPrivateChannelPermission: state.permissions['create-p']
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(withTheme(CreateChannelView));
|
|
@ -144,7 +144,7 @@ class CreateChannelView extends React.Component<ICreateChannelViewProps, ICreate
|
|||
const { server, user, blockUnauthenticatedAccess, theme, serverVersion } = this.props;
|
||||
return (
|
||||
<KeyboardView
|
||||
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
|
||||
style={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
contentContainerStyle={styles.container}
|
||||
keyboardVerticalOffset={128}
|
||||
>
|
||||
|
|
|
@ -105,7 +105,7 @@ export default class DirectoryOptions extends PureComponent<IDirectoryOptionsPro
|
|||
style={[styles.dropdownItemIcon, styles.inverted]}
|
||||
size={22}
|
||||
name='chevron-down'
|
||||
color={themes[theme].auxiliaryTintColor}
|
||||
color={themes[theme].auxiliaryText}
|
||||
/>
|
||||
</View>
|
||||
</Touch>
|
||||
|
@ -117,10 +117,10 @@ export default class DirectoryOptions extends PureComponent<IDirectoryOptionsPro
|
|||
<View style={[styles.dropdownSeparator, { backgroundColor: themes[theme].separatorColor }]} />
|
||||
<View style={[styles.dropdownItemContainer, styles.globalUsersContainer]}>
|
||||
<View style={styles.globalUsersTextContainer}>
|
||||
<Text style={[styles.dropdownItemText, { color: themes[theme].infoText }]}>
|
||||
<Text style={[styles.dropdownItemText, { color: themes[theme].auxiliaryText }]}>
|
||||
{I18n.t('Search_global_users')}
|
||||
</Text>
|
||||
<Text style={[styles.dropdownItemDescription, { color: themes[theme].infoText }]}>
|
||||
<Text style={[styles.dropdownItemDescription, { color: themes[theme].auxiliaryText }]}>
|
||||
{I18n.t('Search_global_users_description')}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
|
@ -215,12 +215,7 @@ class DirectoryView extends React.Component<IDirectoryViewProps, IDirectoryViewS
|
|||
>
|
||||
<CustomIcon name={icon} size={20} color={themes[theme].tintColor} style={styles.toggleDropdownIcon} />
|
||||
<Text style={[styles.toggleDropdownText, { color: themes[theme].tintColor }]}>{I18n.t(text)}</Text>
|
||||
<CustomIcon
|
||||
name='chevron-down'
|
||||
size={20}
|
||||
color={themes[theme].auxiliaryTintColor}
|
||||
style={styles.toggleDropdownArrow}
|
||||
/>
|
||||
<CustomIcon name='chevron-down' size={20} color={themes[theme].auxiliaryText} style={styles.toggleDropdownArrow} />
|
||||
</View>
|
||||
</Touch>
|
||||
</>
|
||||
|
|
|
@ -87,7 +87,7 @@ const DisplayPrefsView = (): React.ReactElement => {
|
|||
};
|
||||
|
||||
const renderCheckBox = (value: boolean) => (
|
||||
<List.Icon name={value ? 'checkbox-checked' : 'checkbox-unchecked'} color={value ? colors.actionTintColor : null} />
|
||||
<List.Icon name={value ? 'checkbox-checked' : 'checkbox-unchecked'} color={value ? colors.tintColor : null} />
|
||||
);
|
||||
|
||||
const renderAvatarSwitch = (value: boolean) => (
|
||||
|
@ -95,7 +95,7 @@ const DisplayPrefsView = (): React.ReactElement => {
|
|||
);
|
||||
|
||||
const renderRadio = (value: boolean) => (
|
||||
<RadioButton selected={!!value} color={value ? colors.actionTintColor : colors.auxiliaryText} size={ICON_SIZE} />
|
||||
<RadioButton selected={!!value} color={value ? colors.tintColor : colors.auxiliaryText} size={ICON_SIZE} />
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -176,7 +176,7 @@ class E2EEncryptionSecurityView extends React.Component<IE2EEncryptionSecurityVi
|
|||
onPress={this.resetOwnKey}
|
||||
title={I18n.t('E2E_encryption_reset_button')}
|
||||
type='secondary'
|
||||
backgroundColor={themes[theme].chatComponentBackground}
|
||||
backgroundColor={themes[theme].buttonBackgroundSecondaryDefault}
|
||||
testID='e2e-encryption-security-view-reset-key'
|
||||
/>
|
||||
</List.Section>
|
||||
|
|
|
@ -111,7 +111,7 @@ const E2ESaveYourPasswordView = () => {
|
|||
<Text style={[styles.password, { color: colors.bodyText }]}>{password}</Text>
|
||||
<Button
|
||||
onPress={onCopy}
|
||||
style={[styles.copyButton, { backgroundColor: colors.auxiliaryBackground }]}
|
||||
style={[styles.copyButton, { backgroundColor: colors.backgroundColor }]}
|
||||
title={I18n.t('Copy')}
|
||||
type='secondary'
|
||||
fontSize={14}
|
||||
|
|
|
@ -149,7 +149,7 @@ const ForwardLivechatView = ({ navigation, route }: IBaseScreen<ChatsStackParamL
|
|||
};
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor: colors.auxiliaryBackground }]}>
|
||||
<View style={[styles.container, { backgroundColor: colors.backgroundColor }]}>
|
||||
<Input onPress={onPressDepartment} placeholder={I18n.t('Select_a_Department')} />
|
||||
<OrSeparator theme={theme} />
|
||||
<Input onPress={onPressUser} placeholder={I18n.t('Select_a_User')} />
|
||||
|
|
|
@ -100,7 +100,7 @@ class InviteUsersEditView extends React.Component<IInviteUsersEditViewProps, any
|
|||
renderPicker = (key: 'days' | 'maxUses', first: string) => {
|
||||
const { props } = this;
|
||||
const { theme } = props;
|
||||
const textInputStyle: TextInputProps = { style: { ...styles.pickerText, color: themes[theme].actionTintColor } };
|
||||
const textInputStyle: TextInputProps = { style: { ...styles.pickerText, color: themes[theme].tintColor } };
|
||||
const firstEl = [
|
||||
{
|
||||
label: I18n.t(first),
|
||||
|
|
|
@ -86,11 +86,7 @@ const InviteUsersView = ({ route, navigation }: IInviteUsersViewProps): React.Re
|
|||
|
||||
return (
|
||||
<SafeAreaView style={{ backgroundColor: colors.backgroundColor }}>
|
||||
<ScrollView
|
||||
{...scrollPersistTaps}
|
||||
style={{ backgroundColor: colors.auxiliaryBackground }}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<ScrollView {...scrollPersistTaps} style={{ backgroundColor: colors.backgroundColor }} showsVerticalScrollIndicator={false}>
|
||||
<StatusBar />
|
||||
<View style={styles.innerContainer}>
|
||||
<FormTextInput label={I18n.t('Invite_Link')} value={invite && invite.url} editable={false} />
|
||||
|
|
|
@ -178,7 +178,7 @@ const LivechatEditView = ({ user, navigation, route, theme }: ILivechatEditViewP
|
|||
|
||||
return (
|
||||
<KeyboardView
|
||||
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
|
||||
style={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
contentContainerStyle={sharedStyles.container}
|
||||
keyboardVerticalOffset={128}
|
||||
>
|
||||
|
|
|
@ -212,7 +212,7 @@ class LoginView extends React.Component<ILoginViewProps, ILoginViewState> {
|
|||
{I18n.t('Dont_Have_An_Account')}
|
||||
</Text>
|
||||
<Text
|
||||
style={[styles.bottomContainerTextBold, { color: themes[theme].actionTintColor }]}
|
||||
style={[styles.bottomContainerTextBold, { color: themes[theme].tintColor }]}
|
||||
onPress={this.register}
|
||||
testID='login-view-register'
|
||||
>
|
||||
|
|
|
@ -255,7 +255,7 @@ class ModalBlockView extends React.Component<IModalBlockViewProps, IModalBlockVi
|
|||
|
||||
return (
|
||||
<KeyboardAwareScrollView
|
||||
style={[styles.container, { backgroundColor: themes[theme].auxiliaryBackground }]}
|
||||
style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]}
|
||||
keyboardShouldPersistTaps='always'
|
||||
>
|
||||
<View style={styles.content}>
|
||||
|
|
|
@ -0,0 +1,335 @@
|
|||
import { Q } from '@nozbe/watermelondb';
|
||||
import { StackNavigationOptions } from '@react-navigation/stack';
|
||||
import { dequal } from 'dequal';
|
||||
import React from 'react';
|
||||
import { FlatList, StyleSheet, Text, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { createChannelRequest } from '../actions/createChannel';
|
||||
import { themes } from '../lib/constants';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import * as List from '../containers/List';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
import SearchBox from '../containers/SearchBox';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import { IApplicationState, IBaseScreen, ISearch, TSubscriptionModel } from '../definitions';
|
||||
import I18n from '../i18n';
|
||||
import database from '../lib/database';
|
||||
import { CustomIcon, TIconsName } from '../containers/CustomIcon';
|
||||
import Navigation from '../lib/navigation/appNavigation';
|
||||
import UserItem from '../containers/UserItem';
|
||||
import { withTheme } from '../theme';
|
||||
import { goRoom, TGoRoomItem } from '../lib/methods/helpers/goRoom';
|
||||
import log, { events, logEvent } from '../lib/methods/helpers/log';
|
||||
import Touch from '../lib/methods/helpers/touch';
|
||||
import sharedStyles from './Styles';
|
||||
import { NewMessageStackParamList } from '../stacks/types';
|
||||
import { search } from '../lib/methods';
|
||||
import { hasPermission, compareServerVersion } from '../lib/methods/helpers';
|
||||
|
||||
const QUERY_SIZE = 50;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
button: {
|
||||
height: 46,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
buttonIcon: {
|
||||
marginLeft: 18,
|
||||
marginRight: 16
|
||||
},
|
||||
buttonText: {
|
||||
fontSize: 17,
|
||||
...sharedStyles.textRegular
|
||||
},
|
||||
buttonContainer: {
|
||||
paddingBottom: 16
|
||||
}
|
||||
});
|
||||
|
||||
interface IButton {
|
||||
onPress: () => void;
|
||||
testID: string;
|
||||
title: string;
|
||||
icon: TIconsName;
|
||||
first?: boolean;
|
||||
}
|
||||
|
||||
interface INewMessageViewState {
|
||||
search: (ISearch | TSubscriptionModel)[];
|
||||
chats: TSubscriptionModel[];
|
||||
permissions: boolean[];
|
||||
}
|
||||
|
||||
interface INewMessageViewProps extends IBaseScreen<NewMessageStackParamList, 'NewMessageView'> {
|
||||
maxUsers: number;
|
||||
isMasterDetail: boolean;
|
||||
serverVersion: string;
|
||||
createTeamPermission?: string[];
|
||||
createDirectMessagePermission?: string[];
|
||||
createPublicChannelPermission?: string[];
|
||||
createPrivateChannelPermission?: string[];
|
||||
createDiscussionPermission?: string[];
|
||||
}
|
||||
|
||||
class NewMessageView extends React.Component<INewMessageViewProps, INewMessageViewState> {
|
||||
static navigationOptions = ({ navigation }: INewMessageViewProps): StackNavigationOptions => ({
|
||||
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} testID='new-message-view-close' />,
|
||||
title: I18n.t('New_Message')
|
||||
});
|
||||
|
||||
constructor(props: INewMessageViewProps) {
|
||||
super(props);
|
||||
this.init();
|
||||
this.state = {
|
||||
search: [],
|
||||
chats: [],
|
||||
permissions: []
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/sort-comp
|
||||
init = async () => {
|
||||
try {
|
||||
const db = database.active;
|
||||
const chats = await db
|
||||
.get('subscriptions')
|
||||
.query(Q.where('t', 'd'), Q.experimentalTake(QUERY_SIZE), Q.experimentalSortBy('room_updated_at', Q.desc))
|
||||
.fetch();
|
||||
|
||||
this.setState({ chats });
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.handleHasPermission();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: INewMessageViewProps) {
|
||||
const {
|
||||
createTeamPermission,
|
||||
createPublicChannelPermission,
|
||||
createPrivateChannelPermission,
|
||||
createDirectMessagePermission,
|
||||
createDiscussionPermission
|
||||
} = this.props;
|
||||
|
||||
if (
|
||||
!dequal(createTeamPermission, prevProps.createTeamPermission) ||
|
||||
!dequal(createPublicChannelPermission, prevProps.createPublicChannelPermission) ||
|
||||
!dequal(createPrivateChannelPermission, prevProps.createPrivateChannelPermission) ||
|
||||
!dequal(createDirectMessagePermission, prevProps.createDirectMessagePermission) ||
|
||||
!dequal(createDiscussionPermission, prevProps.createDiscussionPermission)
|
||||
) {
|
||||
this.handleHasPermission();
|
||||
}
|
||||
}
|
||||
|
||||
handleSearch = async (text: string) => {
|
||||
const result = (await search({ text, filterRooms: false })) as ISearch[];
|
||||
this.setState({
|
||||
search: result
|
||||
});
|
||||
};
|
||||
|
||||
onSearchChangeText(text: string) {
|
||||
this.handleSearch(text);
|
||||
}
|
||||
|
||||
dismiss = () => {
|
||||
const { navigation } = this.props;
|
||||
return navigation.pop();
|
||||
};
|
||||
|
||||
createChannel = () => {
|
||||
logEvent(events.NEW_MSG_CREATE_CHANNEL);
|
||||
const { navigation } = this.props;
|
||||
navigation.navigate('SelectedUsersViewCreateChannel', { nextAction: () => navigation.navigate('CreateChannelView') });
|
||||
};
|
||||
|
||||
createTeam = () => {
|
||||
logEvent(events.NEW_MSG_CREATE_TEAM);
|
||||
const { navigation } = this.props;
|
||||
navigation.navigate('SelectedUsersViewCreateChannel', {
|
||||
nextAction: () => navigation.navigate('CreateChannelView', { isTeam: true })
|
||||
});
|
||||
};
|
||||
|
||||
createGroupChat = () => {
|
||||
logEvent(events.NEW_MSG_CREATE_GROUP_CHAT);
|
||||
const { dispatch, maxUsers, navigation } = this.props;
|
||||
navigation.navigate('SelectedUsersViewCreateChannel', {
|
||||
nextAction: () => dispatch(createChannelRequest({ group: true })),
|
||||
buttonText: I18n.t('Create'),
|
||||
maxUsers
|
||||
});
|
||||
};
|
||||
|
||||
goRoom = (item: TGoRoomItem) => {
|
||||
logEvent(events.NEW_MSG_CHAT_WITH_USER);
|
||||
const { isMasterDetail, navigation } = this.props;
|
||||
if (isMasterDetail) {
|
||||
navigation.pop();
|
||||
}
|
||||
goRoom({ item, isMasterDetail });
|
||||
};
|
||||
|
||||
renderButton = ({ onPress, testID, title, icon, first }: IButton) => {
|
||||
const { theme } = this.props;
|
||||
return (
|
||||
<Touch onPress={onPress} style={{ backgroundColor: themes[theme].backgroundColor }} testID={testID} theme={theme}>
|
||||
<View
|
||||
style={[
|
||||
first ? sharedStyles.separatorVertical : sharedStyles.separatorBottom,
|
||||
styles.button,
|
||||
{ borderColor: themes[theme].separatorColor }
|
||||
]}>
|
||||
<CustomIcon name={icon} size={24} color={themes[theme].tintColor} style={styles.buttonIcon} />
|
||||
<Text style={[styles.buttonText, { color: themes[theme].tintColor }]}>{title}</Text>
|
||||
</View>
|
||||
</Touch>
|
||||
);
|
||||
};
|
||||
|
||||
createDiscussion = () => {
|
||||
logEvent(events.NEW_MSG_CREATE_DISCUSSION);
|
||||
Navigation.navigate('CreateDiscussionView');
|
||||
};
|
||||
|
||||
handleHasPermission = async () => {
|
||||
const {
|
||||
createTeamPermission,
|
||||
createDirectMessagePermission,
|
||||
createPublicChannelPermission,
|
||||
createPrivateChannelPermission,
|
||||
createDiscussionPermission
|
||||
} = this.props;
|
||||
const permissions = [
|
||||
createPublicChannelPermission,
|
||||
createPrivateChannelPermission,
|
||||
createTeamPermission,
|
||||
createDirectMessagePermission,
|
||||
createDiscussionPermission
|
||||
];
|
||||
const permissionsToCreate = await hasPermission(permissions);
|
||||
this.setState({ permissions: permissionsToCreate });
|
||||
};
|
||||
|
||||
renderHeader = () => {
|
||||
const { maxUsers, theme, serverVersion } = this.props;
|
||||
const { permissions } = this.state;
|
||||
|
||||
return (
|
||||
<View style={{ backgroundColor: themes[theme].backgroundColor }}>
|
||||
<SearchBox onChangeText={(text: string) => this.onSearchChangeText(text)} testID='new-message-view-search' />
|
||||
<View style={styles.buttonContainer}>
|
||||
{permissions[0] || permissions[1]
|
||||
? this.renderButton({
|
||||
onPress: this.createChannel,
|
||||
title: I18n.t('Create_Channel'),
|
||||
icon: 'channel-public',
|
||||
testID: 'new-message-view-create-channel',
|
||||
first: true
|
||||
})
|
||||
: null}
|
||||
{compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '3.13.0') && permissions[2]
|
||||
? this.renderButton({
|
||||
onPress: this.createTeam,
|
||||
title: I18n.t('Create_Team'),
|
||||
icon: 'teams',
|
||||
testID: 'new-message-view-create-team'
|
||||
})
|
||||
: null}
|
||||
{maxUsers > 2 && permissions[3]
|
||||
? this.renderButton({
|
||||
onPress: this.createGroupChat,
|
||||
title: I18n.t('Create_Direct_Messages'),
|
||||
icon: 'message',
|
||||
testID: 'new-message-view-create-direct-message'
|
||||
})
|
||||
: null}
|
||||
{permissions[4]
|
||||
? this.renderButton({
|
||||
onPress: this.createDiscussion,
|
||||
title: I18n.t('Create_Discussion'),
|
||||
icon: 'discussions',
|
||||
testID: 'new-message-view-create-discussion'
|
||||
})
|
||||
: null}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
renderItem = ({ item, index }: { item: ISearch | TSubscriptionModel; index: number }) => {
|
||||
const { search, chats } = this.state;
|
||||
const { theme } = this.props;
|
||||
|
||||
let style = { borderColor: themes[theme].separatorColor };
|
||||
if (index === 0) {
|
||||
style = { ...style, ...sharedStyles.separatorTop };
|
||||
}
|
||||
if (search.length > 0 && index === search.length - 1) {
|
||||
style = { ...style, ...sharedStyles.separatorBottom };
|
||||
}
|
||||
if (search.length === 0 && index === chats.length - 1) {
|
||||
style = { ...style, ...sharedStyles.separatorBottom };
|
||||
}
|
||||
|
||||
const itemSearch = item as ISearch;
|
||||
const itemModel = item as TSubscriptionModel;
|
||||
|
||||
return (
|
||||
<UserItem
|
||||
name={itemSearch.search ? itemSearch.name : itemModel.fname || ''}
|
||||
username={itemSearch.search ? itemSearch.username : itemModel.name}
|
||||
onPress={() => this.goRoom(itemModel)}
|
||||
testID={`new-message-view-item-${item.name}`}
|
||||
style={style}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
renderList = () => {
|
||||
const { search, chats } = this.state;
|
||||
const { theme } = this.props;
|
||||
return (
|
||||
<FlatList
|
||||
data={search.length > 0 ? search : chats}
|
||||
extraData={this.state}
|
||||
keyExtractor={item => item._id || item.rid}
|
||||
ListHeaderComponent={this.renderHeader}
|
||||
renderItem={this.renderItem}
|
||||
ItemSeparatorComponent={List.Separator}
|
||||
contentContainerStyle={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
keyboardShouldPersistTaps='always'
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SafeAreaView testID='new-message-view'>
|
||||
<StatusBar />
|
||||
{this.renderList()}
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: IApplicationState) => ({
|
||||
serverVersion: state.server.version as string,
|
||||
isMasterDetail: state.app.isMasterDetail,
|
||||
maxUsers: (state.settings.DirectMesssage_maxUsers as number) || 1,
|
||||
createTeamPermission: state.permissions['create-team'],
|
||||
createDirectMessagePermission: state.permissions['create-d'],
|
||||
createPublicChannelPermission: state.permissions['create-c'],
|
||||
createPrivateChannelPermission: state.permissions['create-p'],
|
||||
createDiscussionPermission: state.permissions['start-discussion']
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(withTheme(NewMessageView));
|
|
@ -366,7 +366,7 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
|
|||
style={[
|
||||
styles.subtitle,
|
||||
{
|
||||
color: themes[theme].controlText,
|
||||
color: themes[theme].auxiliaryText,
|
||||
fontSize: moderateScale({ size: 16, width }),
|
||||
marginBottom: verticalScale({ size: 30, height })
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
|
|||
<Button
|
||||
title={I18n.t('Join_our_open_workspace')}
|
||||
type='secondary'
|
||||
backgroundColor={themes[theme].chatComponentBackground}
|
||||
backgroundColor={themes[theme].buttonBackgroundSecondaryDefault}
|
||||
onPress={this.connectOpen}
|
||||
disabled={connecting}
|
||||
loading={connectingOpen && connecting}
|
||||
|
|
|
@ -56,7 +56,7 @@ const RenderListPicker = ({
|
|||
onChangeValue(preference, { [preference]: i.value.toString() }, () => setOption(option));
|
||||
setOption(i);
|
||||
},
|
||||
right: option?.value === i.value ? () => <CustomIcon name={'check'} size={20} color={colors.tintActive} /> : undefined
|
||||
right: option?.value === i.value ? () => <CustomIcon name={'check'} size={20} color={colors.tintColor} /> : undefined
|
||||
}));
|
||||
|
||||
return (
|
||||
|
@ -65,7 +65,7 @@ const RenderListPicker = ({
|
|||
testID={testID}
|
||||
onPress={() => showActionSheet({ options })}
|
||||
right={() => (
|
||||
<Text style={[{ ...sharedStyles.textRegular, fontSize: 16 }, { color: colors.actionTintColor }]}>
|
||||
<Text style={[{ ...sharedStyles.textRegular, fontSize: 16 }, { color: colors.tintColor }]}>
|
||||
{option?.label ? I18n.t(option?.label, { defaultValue: option?.label, second: option?.second }) : option?.label}
|
||||
</Text>
|
||||
)}
|
||||
|
|
|
@ -535,7 +535,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
|||
|
||||
return (
|
||||
<KeyboardView
|
||||
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
|
||||
style={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
contentContainerStyle={sharedStyles.container}
|
||||
keyboardVerticalOffset={128}
|
||||
>
|
||||
|
@ -642,7 +642,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
|||
<Button
|
||||
title={I18n.t('Logout_from_other_logged_in_locations')}
|
||||
type='secondary'
|
||||
backgroundColor={themes[theme].chatComponentBackground}
|
||||
backgroundColor={themes[theme].buttonBackgroundSecondaryDefault}
|
||||
onPress={this.logoutOtherLocations}
|
||||
testID='profile-view-logout-other-locations'
|
||||
/>
|
||||
|
|
|
@ -105,11 +105,8 @@ class ReadReceiptView extends React.Component<IReadReceiptViewProps, IReadReceip
|
|||
return null;
|
||||
}
|
||||
return (
|
||||
<View
|
||||
style={[styles.listEmptyContainer, { backgroundColor: themes[theme].chatComponentBackground }]}
|
||||
testID='read-receipt-view'
|
||||
>
|
||||
<Text style={[styles.emptyText, { color: themes[theme].auxiliaryTintColor }]}>{I18n.t('No_Read_Receipts')}</Text>
|
||||
<View style={[styles.listEmptyContainer, { backgroundColor: themes[theme].backgroundColor }]} testID='read-receipt-view'>
|
||||
<Text style={[styles.emptyText, { color: themes[theme].auxiliaryText }]}>{I18n.t('No_Read_Receipts')}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
@ -157,7 +154,7 @@ class ReadReceiptView extends React.Component<IReadReceiptViewProps, IReadReceip
|
|||
style={[
|
||||
styles.list,
|
||||
{
|
||||
backgroundColor: themes[theme].chatComponentBackground,
|
||||
backgroundColor: themes[theme].backgroundColor,
|
||||
borderColor: themes[theme].separatorColor
|
||||
}
|
||||
]}
|
||||
|
|
|
@ -319,14 +319,14 @@ class RegisterView extends React.Component<IProps, any> {
|
|||
<Text style={[styles.bottomContainerText, { color: themes[theme].auxiliaryText }]}>
|
||||
{`${I18n.t('Onboarding_agree_terms')}\n`}
|
||||
<Text
|
||||
style={[styles.bottomContainerTextBold, { color: themes[theme].actionTintColor }]}
|
||||
style={[styles.bottomContainerTextBold, { color: themes[theme].tintColor }]}
|
||||
onPress={() => this.openContract('terms-of-service')}
|
||||
>
|
||||
{I18n.t('Terms_of_Service')}
|
||||
</Text>{' '}
|
||||
{I18n.t('and')}
|
||||
<Text
|
||||
style={[styles.bottomContainerTextBold, { color: themes[theme].actionTintColor }]}
|
||||
style={[styles.bottomContainerTextBold, { color: themes[theme].tintColor }]}
|
||||
onPress={() => this.openContract('privacy-policy')}
|
||||
>
|
||||
{' '}
|
||||
|
@ -340,7 +340,7 @@ class RegisterView extends React.Component<IProps, any> {
|
|||
<Text style={[styles.bottomContainerText, { color: themes[theme].auxiliaryText }]}>
|
||||
{I18n.t('Do_you_have_an_account')}
|
||||
</Text>
|
||||
<Text style={[styles.bottomContainerTextBold, { color: themes[theme].actionTintColor }]} onPress={this.login}>
|
||||
<Text style={[styles.bottomContainerTextBold, { color: themes[theme].tintColor }]} onPress={this.login}>
|
||||
{I18n.t('Login')}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
|
@ -743,7 +743,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
|
|||
<TouchableOpacity
|
||||
style={[
|
||||
styles.buttonContainer,
|
||||
{ backgroundColor: themes[theme].buttonBackground },
|
||||
{ backgroundColor: themes[theme].buttonBackgroundSecondaryDefault },
|
||||
!this.formIsChanged() && styles.buttonContainerDisabled
|
||||
]}
|
||||
onPress={this.submit}
|
||||
|
|
|
@ -13,18 +13,20 @@ const Roles = ({ roles }: { roles?: string[] }) => {
|
|||
const { theme } = useTheme();
|
||||
|
||||
if (roles && roles.length) {
|
||||
<View style={styles.item}>
|
||||
<Text style={[styles.itemLabel, { color: themes[theme].titleText }]}>{I18n.t('Roles')}</Text>
|
||||
<View style={styles.rolesContainer}>
|
||||
{roles.map(role =>
|
||||
role ? (
|
||||
<View style={[styles.roleBadge, { backgroundColor: themes[theme].chatComponentBackground }]} key={role}>
|
||||
<Text style={[styles.role, { color: themes[theme].titleText }]}>{role}</Text>
|
||||
</View>
|
||||
) : null
|
||||
)}
|
||||
return (
|
||||
<View style={styles.item}>
|
||||
<Text style={[styles.itemLabel, { color: themes[theme].titleText }]}>{I18n.t('Roles')}</Text>
|
||||
<View style={styles.rolesContainer}>
|
||||
{roles.map(role =>
|
||||
role ? (
|
||||
<View style={[styles.roleBadge, { backgroundColor: themes[theme].buttonBackgroundSecondaryDefault }]} key={role}>
|
||||
<Text style={[styles.role, { color: themes[theme].titleText }]}>{role}</Text>
|
||||
</View>
|
||||
) : null
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</View>;
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -405,7 +405,7 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
|
|||
return (
|
||||
<Avatar text={room.name || roomUser.username} style={styles.avatar} type={this.t} size={100} rid={room?.rid}>
|
||||
{this.t === SubscriptionType.DIRECT && roomUser._id ? (
|
||||
<View style={[sharedStyles.status, { backgroundColor: themes[theme].auxiliaryBackground }]}>
|
||||
<View style={[sharedStyles.status, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
<Status size={20} id={roomUser._id} />
|
||||
</View>
|
||||
) : null}
|
||||
|
@ -415,7 +415,7 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
|
|||
|
||||
renderButton = (onPress: () => void, iconName: TIconsName, text: string, danger?: boolean) => {
|
||||
const { theme } = this.props;
|
||||
const color = danger ? themes[theme].dangerColor : themes[theme].actionTintColor;
|
||||
const color = danger ? themes[theme].dangerColor : themes[theme].tintColor;
|
||||
return (
|
||||
<BorderlessButton testID={`room-info-view-${iconName}`} onPress={onPress} style={styles.roomButton}>
|
||||
<CustomIcon name={iconName} size={30} color={color} />
|
||||
|
@ -487,7 +487,7 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
|
|||
<ScrollView style={[styles.scroll, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
<StatusBar />
|
||||
<SafeAreaView style={{ backgroundColor: themes[theme].backgroundColor }} testID='room-info-view'>
|
||||
<View style={[styles.avatarContainer, { backgroundColor: themes[theme].auxiliaryBackground }]}>
|
||||
<View style={[styles.avatarContainer, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
{this.renderAvatar(room, roomUserParsed)}
|
||||
<View style={styles.roomTitleContainer}>
|
||||
{renderRoomTitle({
|
||||
|
|
|
@ -27,7 +27,7 @@ const Banner = React.memo(
|
|||
return (
|
||||
<>
|
||||
<BorderlessButton
|
||||
style={[styles.bannerContainer, { backgroundColor: themes[theme].bannerBackground }]}
|
||||
style={[styles.bannerContainer, { backgroundColor: themes[theme].buttonBackgroundSecondaryPress }]}
|
||||
testID='room-view-banner'
|
||||
onPress={toggleModal}
|
||||
>
|
||||
|
@ -44,7 +44,7 @@ const Banner = React.memo(
|
|||
animationIn='fadeIn'
|
||||
animationOut='fadeOut'
|
||||
>
|
||||
<View style={[styles.modalView, { backgroundColor: themes[theme].bannerBackground }]}>
|
||||
<View style={[styles.modalView, { backgroundColor: themes[theme].buttonBackgroundSecondaryPress }]}>
|
||||
<Text style={[styles.bannerModalTitle, { color: themes[theme].auxiliaryText }]}>{title}</Text>
|
||||
<ScrollView style={styles.modalScrollView}>
|
||||
<Markdown msg={text} theme={theme} />
|
||||
|
|
|
@ -105,7 +105,7 @@ const JoinCode = React.memo(
|
|||
title={I18n.t('Cancel')}
|
||||
type='secondary'
|
||||
style={styles.button}
|
||||
backgroundColor={themes[theme].chatComponentBackground}
|
||||
backgroundColor={themes[theme].buttonBackgroundSecondaryDefault}
|
||||
testID='join-code-cancel'
|
||||
onPress={hide}
|
||||
/>
|
||||
|
|
|
@ -65,7 +65,7 @@ const NavBottomFAB = ({
|
|||
<Animated.View style={[styles.container, { bottom }]} testID='nav-jump-to-bottom'>
|
||||
<Touch onPress={handleOnPress} style={[styles.button, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
<View style={[styles.content, { borderColor: themes[theme].borderColor }]}>
|
||||
<CustomIcon name='chevron-down' color={themes[theme].auxiliaryTintColor} size={36} />
|
||||
<CustomIcon name='chevron-down' color={themes[theme].auxiliaryText} size={36} />
|
||||
</View>
|
||||
</Touch>
|
||||
</Animated.View>
|
||||
|
|
|
@ -214,7 +214,7 @@ class UploadProgress extends Component<IUploadProgressProps, IUploadProgressStat
|
|||
styles.item,
|
||||
index !== 0 ? { marginTop: 4 } : {},
|
||||
{
|
||||
backgroundColor: themes[theme!].chatComponentBackground,
|
||||
backgroundColor: themes[theme!].surfaceTint,
|
||||
borderColor: themes[theme!].borderColor
|
||||
}
|
||||
]}
|
||||
|
|
|
@ -1418,7 +1418,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
</Text>
|
||||
<Touch
|
||||
onPress={this.resumeRoom}
|
||||
style={[styles.joinRoomButton, { backgroundColor: themes[theme].actionTintColor }]}
|
||||
style={[styles.joinRoomButton, { backgroundColor: themes[theme].tintColor }]}
|
||||
enabled={!loading}
|
||||
>
|
||||
<Text style={[styles.joinRoomText, { color: themes[theme].buttonText }]} testID='room-view-chat-on-hold-button'>
|
||||
|
@ -1439,7 +1439,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
</Text>
|
||||
<Touch
|
||||
onPress={this.joinRoom}
|
||||
style={[styles.joinRoomButton, { backgroundColor: themes[theme].actionTintColor }]}
|
||||
style={[styles.joinRoomButton, { backgroundColor: themes[theme].tintColor }]}
|
||||
enabled={!loading}
|
||||
>
|
||||
<Text style={[styles.joinRoomText, { color: themes[theme].buttonText }]} testID='room-view-join-button'>
|
||||
|
|
|
@ -37,8 +37,8 @@ const ListHeader = React.memo(
|
|||
: 'Save_Your_Encryption_Password'
|
||||
}
|
||||
left={() => <List.Icon name='encrypted' color={themes[theme].buttonText} />}
|
||||
underlayColor={themes[theme].tintActive}
|
||||
backgroundColor={themes[theme].actionTintColor}
|
||||
underlayColor={themes[theme].tintColor}
|
||||
backgroundColor={themes[theme].tintColor}
|
||||
color={themes[theme].buttonText}
|
||||
onPress={goEncryption}
|
||||
testID='listheader-encryption'
|
||||
|
|
|
@ -973,7 +973,7 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
|||
const { theme } = this.props;
|
||||
return (
|
||||
<View style={[styles.groupTitleContainer, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
<Text style={[styles.groupTitle, { color: themes[theme].controlText }]}>{I18n.t(header)}</Text>
|
||||
<Text style={[styles.groupTitle, { color: themes[theme].auxiliaryText }]}>{I18n.t(header)}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -62,7 +62,7 @@ class SelectListView extends React.Component<ISelectListViewProps, ISelectListVi
|
|||
super(props);
|
||||
const data = props.route?.params?.data;
|
||||
this.title = props.route?.params?.title;
|
||||
this.infoText = props.route?.params?.infoText ?? '';
|
||||
this.auxiliaryText = props.route?.params?.auxiliaryText ?? '';
|
||||
this.nextAction = props.route?.params?.nextAction;
|
||||
this.showAlert = props.route?.params?.showAlert ?? (() => {});
|
||||
this.isSearch = props.route?.params?.isSearch ?? false;
|
||||
|
@ -102,7 +102,7 @@ class SelectListView extends React.Component<ISelectListViewProps, ISelectListVi
|
|||
const { theme } = this.props;
|
||||
return (
|
||||
<View style={{ backgroundColor: themes[theme].backgroundColor }}>
|
||||
<Text style={[styles.buttonText, { color: themes[theme].bodyText }]}>{I18n.t(this.infoText)}</Text>
|
||||
<Text style={[styles.buttonText, { color: themes[theme].bodyText }]}>{I18n.t(this.auxiliaryText)}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
@ -153,7 +153,7 @@ class SelectListView extends React.Component<ISelectListViewProps, ISelectListVi
|
|||
<RadioButton
|
||||
testID={selected ? `radio-button-selected-${item.name}` : `radio-button-unselected-${item.name}`}
|
||||
selected={selected.includes(item.rid)}
|
||||
color={themes[theme].actionTintColor}
|
||||
color={themes[theme].tintColor}
|
||||
size={ICON_SIZE}
|
||||
/>
|
||||
);
|
||||
|
@ -162,7 +162,7 @@ class SelectListView extends React.Component<ISelectListViewProps, ISelectListVi
|
|||
<List.Icon
|
||||
testID={checked ? `${item.name}-checked` : `${item.name}-unchecked`}
|
||||
name={checked}
|
||||
color={themes[theme].actionTintColor}
|
||||
color={themes[theme].tintColor}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
|
@ -175,7 +175,7 @@ class SelectListView extends React.Component<ISelectListViewProps, ISelectListVi
|
|||
testID={`select-list-view-item-${item.name}`}
|
||||
onPress={() => (item.alert ? this.showAlert() : this.toggleItem(item.rid))}
|
||||
alert={item.alert}
|
||||
left={() => <List.Icon name={icon} color={themes[theme].controlText} />}
|
||||
left={() => <List.Icon name={icon} color={themes[theme].auxiliaryText} />}
|
||||
right={() => (this.isRadio ? showRadio() : showCheck())}
|
||||
/>
|
||||
</>
|
||||
|
|
|
@ -86,7 +86,7 @@ const SetUsernameView = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<KeyboardView style={{ backgroundColor: colors.auxiliaryBackground }} contentContainerStyle={sharedStyles.container}>
|
||||
<KeyboardView style={{ backgroundColor: colors.backgroundColor }} contentContainerStyle={sharedStyles.container}>
|
||||
<StatusBar />
|
||||
<ScrollView {...scrollPersistTaps} contentContainerStyle={sharedStyles.containerScrollView}>
|
||||
<SafeAreaView testID='set-username-view'>
|
||||
|
|
|
@ -7,7 +7,6 @@ import I18n from '../../../i18n';
|
|||
import { CustomIcon } from '../../../containers/CustomIcon';
|
||||
import { TextInput } from '../../../containers/TextInput';
|
||||
import { useTheme } from '../../../theme';
|
||||
import { isIOS } from '../../../lib/methods/helpers';
|
||||
import sharedStyles from '../../Styles';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
@ -63,13 +62,8 @@ const CancelButton = ({ onCancelPress }: { onCancelPress?: () => void }) => {
|
|||
const SearchBox = ({ hasCancel, onCancelPress, inputRef, ...props }: ISearchBox): React.ReactElement => {
|
||||
const { theme } = useTheme();
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
styles.container,
|
||||
{ backgroundColor: isIOS ? themes[theme].headerBackground : themes[theme].headerSecondaryBackground }
|
||||
]}
|
||||
>
|
||||
<View style={[styles.searchBox, { backgroundColor: themes[theme].searchboxBackground }]}>
|
||||
<View style={[styles.container, { backgroundColor: themes[theme].headerBackground }]}>
|
||||
<View style={[styles.searchBox, { backgroundColor: themes[theme].buttonBackgroundSecondaryDefault }]}>
|
||||
<CustomIcon name='search' size={14} color={themes[theme].auxiliaryText} />
|
||||
<TextInput
|
||||
ref={inputRef}
|
||||
|
|
|
@ -347,7 +347,7 @@ class ShareListView extends React.Component<IShareListViewProps, IState> {
|
|||
|
||||
return (
|
||||
<>
|
||||
<View style={[styles.headerContainer, { backgroundColor: themes[theme].auxiliaryBackground }]}>
|
||||
<View style={[styles.headerContainer, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
<Text style={[styles.headerText, { color: themes[theme].titleText }]}>{I18n.t(header)}</Text>
|
||||
</View>
|
||||
<List.Separator />
|
||||
|
@ -399,7 +399,7 @@ class ShareListView extends React.Component<IShareListViewProps, IState> {
|
|||
renderEmptyComponent = () => {
|
||||
const { theme } = this.props;
|
||||
return (
|
||||
<View style={[styles.container, styles.emptyContainer, { backgroundColor: themes[theme].auxiliaryBackground }]}>
|
||||
<View style={[styles.container, styles.emptyContainer, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
<Text style={[styles.title, { color: themes[theme].titleText }]}>{I18n.t('No_results_found')}</Text>
|
||||
</View>
|
||||
);
|
||||
|
@ -451,7 +451,7 @@ class ShareListView extends React.Component<IShareListViewProps, IState> {
|
|||
<FlatList
|
||||
data={searching ? searchResults : chats}
|
||||
keyExtractor={keyExtractor}
|
||||
style={[styles.flatlist, { backgroundColor: themes[theme].auxiliaryBackground }]}
|
||||
style={[styles.flatlist, { backgroundColor: themes[theme].backgroundColor }]}
|
||||
contentContainerStyle={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
renderItem={this.renderItem}
|
||||
getItemLayout={getItemLayout}
|
||||
|
|
|
@ -48,7 +48,7 @@ interface IIconPreview {
|
|||
|
||||
const IconPreview = React.memo(({ iconName, title, description, theme, width, height, danger }: IIconPreview) => (
|
||||
<ScrollView
|
||||
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
|
||||
style={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
contentContainerStyle={[styles.fileContainer, { width, height }]}
|
||||
>
|
||||
<CustomIcon name={iconName} size={56} color={danger ? themes[theme].dangerColor : themes[theme].tintColor} />
|
||||
|
|
|
@ -120,12 +120,12 @@ const Thumb = ({ item, theme, isShareExtension, onPress, onRemove }: IThumb) =>
|
|||
<ThumbContent item={item} theme={theme} isShareExtension={isShareExtension} />
|
||||
<RectButton
|
||||
hitSlop={BUTTON_HIT_SLOP}
|
||||
style={[styles.removeButton, { backgroundColor: themes[theme].bodyText, borderColor: themes[theme].auxiliaryBackground }]}
|
||||
style={[styles.removeButton, { backgroundColor: themes[theme].bodyText, borderColor: themes[theme].backgroundColor }]}
|
||||
activeOpacity={1}
|
||||
rippleColor={themes[theme].bannerBackground}
|
||||
rippleColor={themes[theme].buttonBackgroundSecondaryPress}
|
||||
onPress={() => onRemove(item)}
|
||||
>
|
||||
<View style={[styles.removeView, { borderColor: themes[theme].auxiliaryBackground }]}>
|
||||
<View style={[styles.removeView, { borderColor: themes[theme].backgroundColor }]}>
|
||||
<CustomIcon name='close' color={themes[theme].backgroundColor} size={14} />
|
||||
</View>
|
||||
</RectButton>
|
||||
|
|
|
@ -334,7 +334,7 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
|
|||
return (
|
||||
<FormTextInput
|
||||
containerStyle={styles.inputContainer}
|
||||
inputStyle={[styles.input, styles.textInput, { backgroundColor: themes[theme].focusedBackground }]}
|
||||
inputStyle={[styles.input, styles.textInput, { backgroundColor: themes[theme].backgroundColor }]}
|
||||
placeholder=''
|
||||
onChangeText={this.onChangeText}
|
||||
defaultValue=''
|
||||
|
|
|
@ -239,12 +239,12 @@ class Sidebar extends Component<ISidebarProps, ISidebarState> {
|
|||
return null;
|
||||
}
|
||||
return (
|
||||
<SafeAreaView testID='sidebar-view' style={{ backgroundColor: themes[theme!].focusedBackground }} vertical={isMasterDetail}>
|
||||
<SafeAreaView testID='sidebar-view' style={{ backgroundColor: themes[theme!].backgroundColor }} vertical={isMasterDetail}>
|
||||
<ScrollView
|
||||
style={[
|
||||
styles.container,
|
||||
{
|
||||
backgroundColor: isMasterDetail ? themes[theme!].backgroundColor : themes[theme!].focusedBackground
|
||||
backgroundColor: isMasterDetail ? themes[theme!].backgroundColor : themes[theme!].backgroundColor
|
||||
}
|
||||
]}
|
||||
{...scrollPersistTaps}
|
||||
|
|
|
@ -436,7 +436,7 @@ class TeamChannelsView extends React.Component<ITeamChannelsViewProps, ITeamChan
|
|||
} = this.props;
|
||||
const isAutoJoinChecked = item.teamDefault;
|
||||
const autoJoinIcon = isAutoJoinChecked ? 'checkbox-checked' : 'checkbox-unchecked';
|
||||
const autoJoinIconColor = isAutoJoinChecked ? themes[theme].tintActive : themes[theme].auxiliaryTintColor;
|
||||
const autoJoinIconColor = isAutoJoinChecked ? themes[theme].tintColor : themes[theme].auxiliaryText;
|
||||
|
||||
const options: TActionSheetOptionsItem[] = [];
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ const ServerAvatar = React.memo(({ theme, url, image }: IServerAvatar) => (
|
|||
resizeMode={FastImage.resizeMode.cover}
|
||||
indicator={Progress.Pie}
|
||||
indicatorProps={{
|
||||
color: themes[theme].actionTintColor
|
||||
color: themes[theme].tintColor
|
||||
}}
|
||||
renderError={() => <Fallback theme={theme} initial={getInitial(url)} />}
|
||||
/>
|
||||
|
|
|
@ -87,7 +87,7 @@ class WorkspaceView extends React.Component<IWorkSpaceProp, any> {
|
|||
<Button
|
||||
title={I18n.t('Create_account')}
|
||||
type='secondary'
|
||||
backgroundColor={themes[theme].chatComponentBackground}
|
||||
backgroundColor={themes[theme].buttonBackgroundSecondaryDefault}
|
||||
onPress={this.register}
|
||||
testID='workspace-view-register'
|
||||
/>
|
||||
|
|
|
@ -1654,7 +1654,7 @@
|
|||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
|
||||
$PODS_CONFIGURATION_BUILD_DIR/Firebase,
|
||||
"$PODS_CONFIGURATION_BUILD_DIR/Firebase",
|
||||
);
|
||||
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
|
@ -1722,7 +1722,7 @@
|
|||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
|
||||
$PODS_CONFIGURATION_BUILD_DIR/Firebase,
|
||||
"$PODS_CONFIGURATION_BUILD_DIR/Firebase",
|
||||
);
|
||||
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
|
|
Loading…
Reference in New Issue