MM-44663/tappable-channel-names (#6997)

* ADD: channel name tappable in post with channel name fields

* touchable feedback added to the channel name

* rippple effect added in toucable

* Text color of channel name changes as its presses

* ui colors and borderRadius fixed in channelinfo

* comments resolved: dependency added, function name changed

* comment resolved: condition added onChannelNamePressed
This commit is contained in:
Tanmay Vardhaman Thole 2023-03-09 14:47:05 +05:30 committed by GitHub
parent 07aa748cd7
commit 66c7a70e49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 25 deletions

View file

@ -1,11 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import React, {useCallback, useMemo, useState} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {switchToChannelById} from '@actions/remote/channel';
import TouchableWithFeedback from '@app/components/touchable_with_feedback';
import {useServerUrl} from '@app/context/server';
import {useTheme} from '@context/theme';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import type ChannelModel from '@typings/database/models/servers/channel';
@ -15,51 +18,88 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
container: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
marginVertical: 8,
paddingHorizontal: 16,
paddingHorizontal: 8,
},
channelContainer: {
borderRadius: 4,
overflow: 'hidden',
},
channel: {
...typography('Body', 75, 'SemiBold'),
color: theme.centerChannelColor,
marginRight: 5,
color: changeOpacity(theme.centerChannelColor, 0.72),
flexShrink: 1,
paddingHorizontal: 8,
paddingVertical: 4,
},
teamContainer: {
borderColor: theme.centerChannelColor,
borderLeftWidth: StyleSheet.hairlineWidth,
flexShrink: 1,
},
team: {
...typography('Body', 75, 'Light'),
color: theme.centerChannelColor,
marginLeft: 5,
...typography('Body', 75, 'Regular'),
color: changeOpacity(theme.centerChannelColor, 0.72),
marginLeft: 8,
},
}));
type Props = {
channelId: ChannelModel['id'];
channelName: ChannelModel['displayName'];
teamName: TeamModel['displayName'];
testID?: string;
}
function ChannelInfo({channelName, teamName, testID}: Props) {
function ChannelInfo({channelId, channelName, teamName, testID}: Props) {
const theme = useTheme();
const styles = getStyleSheet(theme);
const serverUrl = useServerUrl();
const [isPressed, setIsPressed] = useState<Boolean>(false);
const channelNameStyle = useMemo(() => (
[styles.channel, isPressed ? {color: theme.buttonBg} : null]
), [isPressed, styles, theme]);
const teamContainerStyle = useMemo(() => (
[styles.teamContainer, isPressed ? null : {borderLeftWidth: StyleSheet.hairlineWidth}]
), [isPressed, styles]);
const onChannelNamePressed = useCallback(() => {
if (channelId) {
switchToChannelById(serverUrl, channelId);
}
}, [serverUrl, channelId]);
const togglePressed = useCallback(() => {
setIsPressed((prevState) => !prevState);
}, []);
return (
<View
style={styles.container}
testID={testID}
>
<Text
style={styles.channel}
testID='channel_display_name'
numberOfLines={1}
>
{channelName}
</Text>
<View style={styles.channelContainer}>
<TouchableWithFeedback
onPress={onChannelNamePressed}
type={'native'}
underlayColor={changeOpacity(theme.buttonBg, 0.08)}
onPressIn={togglePressed}
onPressOut={togglePressed}
>
<Text
style={channelNameStyle}
testID='channel_display_name'
numberOfLines={1}
>
{channelName}
</Text>
</TouchableWithFeedback>
</View>
{Boolean(teamName) && (
<View style={styles.teamContainer}>
<View style={teamContainerStyle}>
<Text
style={styles.team}
testID='team_display_name'

View file

@ -17,6 +17,9 @@ const enhance = withObservables(['post'], ({post, database}: {post: PostModel} &
const channel = observeChannel(database, post.channelId);
return {
channelId: channel.pipe(
switchMap((chan) => (chan ? of$(chan.id) : '')),
),
channelName: channel.pipe(
switchMap((chan) => (chan ? of$(chan.displayName) : '')),
),

View file

@ -1,11 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback} from 'react';
import React, {useCallback, useMemo, useState} from 'react';
import {useIntl} from 'react-intl';
import {Text, TouchableHighlight, View} from 'react-native';
import {switchToChannelById} from '@actions/remote/channel';
import {fetchAndSwitchToThread} from '@actions/remote/thread';
import TouchableWithFeedback from '@app/components/touchable_with_feedback';
import FormattedText from '@components/formatted_text';
import FriendlyDate from '@components/friendly_date';
import RemoveMarkdown from '@components/remove_markdown';
@ -129,10 +131,26 @@ const Thread = ({author, channel, location, post, teammateNameDisplay, testID, t
const textStyles = getMarkdownTextStyles(theme);
const serverUrl = useServerUrl();
const [isChannelNamePressed, setIsChannelNamePressed] = useState<Boolean>(false);
const channelNameStyle = useMemo(() => (
[styles.channelName, isChannelNamePressed ? {color: theme.buttonBg} : null]
), [isChannelNamePressed, styles, theme]);
const togglePressed = useCallback(() => {
setIsChannelNamePressed((prevState) => !prevState);
}, []);
const showThread = useCallback(preventDoubleTap(() => {
fetchAndSwitchToThread(serverUrl, thread.id);
}), [serverUrl, thread.id]);
const onChannelNamePressed = useCallback(() => {
if (channel?.id) {
switchToChannelById(serverUrl, channel?.id);
}
}, [serverUrl, channel?.id]);
const showThreadOptions = useCallback(() => {
const passProps = {thread};
const title = isTablet ? intl.formatMessage({id: 'thread.options.title', defaultMessage: 'Thread Actions'}) : '';
@ -229,13 +247,21 @@ const Thread = ({author, channel, location, post, teammateNameDisplay, testID, t
{name}
{threadStarterName !== channel?.displayName && (
<View style={styles.channelNameContainer}>
<Text
style={styles.channelName}
numberOfLines={1}
testID={`${threadItemTestId}.thread_starter.channel_display_name`}
<TouchableWithFeedback
onPress={onChannelNamePressed}
type={'native'}
underlayColor={changeOpacity(theme.buttonBg, 0.08)}
onPressIn={togglePressed}
onPressOut={togglePressed}
>
{channel?.displayName}
</Text>
<Text
style={channelNameStyle}
numberOfLines={1}
testID={`${threadItemTestId}.thread_starter.channel_display_name`}
>
{channel?.displayName}
</Text>
</TouchableWithFeedback>
</View>
)}
</View>