mattermost-mobile/app/components/option_box/index.tsx
Elias Nahum 4573732fd2
[Gekidou] channel quick actions (#6288)
* Add hitSlop to navigation header right buttons

* Fix channel_item info muted style

* Fix team switch when global threads

* Wrap WS channel events in try/catch

* Group Box component and Animated Group Box

* SlideUpPanelItem style

* Fix return value of setCurrentTeamAndChannelId

* Add observeChannelSettings and include channel settings in prepareDeleteChannel

* update OPTIONS_HEIGHT reference in find channels quick options

* Fix DM limit in channel list

* Fix category header style and translate default categories

* Add snackbar for unmute/favorite/unfavorite

* Add toggleFavoriteChannel remote action

* Add makeDirectChannelVisible remote action

* Use makeDirectChannelVisible in switchToChannelById and update toggleMuteChannel snackbar

* Add channel actions common components

* Update channel intro to use channel action common components

* Rename ChannelDetails screen to ChannelInfo

* Add channel quick actions

* Update localization strings

* Fix addChannelToDefaultCategory

* Leave channel

* Add localization strings

* Fix snackBar screen event listener

* Feedback review
2022-05-19 14:30:55 -04:00

102 lines
3.2 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useState} from 'react';
import {Pressable, PressableStateCallbackType, StyleProp, Text, ViewStyle} from 'react-native';
import CompassIcon from '@components/compass_icon';
import {useTheme} from '@context/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
type OptionBoxProps = {
activeIconName?: string;
activeText?: string;
containerStyle?: StyleProp<ViewStyle>;
iconName: string;
isActive?: boolean;
onPress: () => void;
testID?: string;
text: string;
}
export const OPTIONS_HEIGHT = 62;
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
container: {
alignItems: 'center',
backgroundColor: changeOpacity(theme.centerChannelColor, 0.04),
borderRadius: 4,
flex: 1,
maxHeight: OPTIONS_HEIGHT,
justifyContent: 'center',
minWidth: 80,
},
text: {
color: changeOpacity(theme.centerChannelColor, 0.56),
paddingHorizontal: 5,
textTransform: 'capitalize',
...typography('Body', 50, 'SemiBold'),
},
}));
const OptionBox = ({activeIconName, activeText, containerStyle, iconName, isActive, onPress, testID, text}: OptionBoxProps) => {
const theme = useTheme();
const [activated, setActivated] = useState(isActive);
const styles = getStyleSheet(theme);
const pressedStyle = useCallback(({pressed}: PressableStateCallbackType) => {
const style = [styles.container, Boolean(containerStyle) && containerStyle];
if (activated) {
style.push({
backgroundColor: changeOpacity(theme.buttonBg, 0.08),
});
}
if (pressed) {
style.push({
backgroundColor: changeOpacity(theme.buttonBg, 0.16),
});
}
return style;
}, [activated, containerStyle, theme]);
const handleOnPress = useCallback(() => {
if (activeIconName || activeText) {
setActivated(!activated);
}
onPress();
}, [activated, activeIconName, activeText, onPress]);
useEffect(() => {
setActivated(isActive);
}, [isActive]);
return (
<Pressable
onPress={handleOnPress}
style={pressedStyle}
testID={testID}
>
{({pressed}) => (
<>
<CompassIcon
color={(pressed || activated) ? theme.buttonBg : changeOpacity(theme.centerChannelColor, 0.56)}
name={activated && activeIconName ? activeIconName : iconName}
size={24}
/>
<Text
numberOfLines={1}
style={[styles.text, {color: (pressed || activated) ? theme.buttonBg : changeOpacity(theme.centerChannelColor, 0.56)}]}
testID={`${testID}.label`}
>
{activated && activeText ? activeText : text}
</Text>
</>
)}
</Pressable>
);
};
export default OptionBox;