Rewrite : Message Thread metrics (#20051)
parent
201a8fb7bf
commit
5f79f37bbf
@ -0,0 +1,3 @@ |
||||
const { createTemplateForComponent } = require('./reactAdapters'); |
||||
|
||||
createTemplateForComponent('ThreadReply', () => import('./components/Message/Metrics/Thread')); |
@ -0,0 +1,30 @@ |
||||
import React from 'react'; |
||||
|
||||
import Metrics, { Reply, Content } from '.'; |
||||
|
||||
export default { |
||||
title: 'components/Message/Metrics', |
||||
component: Metrics, |
||||
}; |
||||
|
||||
export const Default = () => <Content> |
||||
<Reply/> |
||||
<Metrics> |
||||
<Metrics.Item> |
||||
<Metrics.Item.Icon name='thread'/> |
||||
<Metrics.Item.Label>3</Metrics.Item.Label> |
||||
</Metrics.Item> |
||||
<Metrics.Item> |
||||
<Metrics.Item.Icon name='user'/> |
||||
<Metrics.Item.Label>3</Metrics.Item.Label> |
||||
</Metrics.Item> |
||||
<Metrics.Item> |
||||
<Metrics.Item.Icon name='clock'/> |
||||
<Metrics.Item.Label>sunday</Metrics.Item.Label> |
||||
</Metrics.Item> |
||||
<Metrics.Item> |
||||
<Metrics.Item.Icon name='bell'/> |
||||
<Metrics.Item.Label>3</Metrics.Item.Label> |
||||
</Metrics.Item> |
||||
</Metrics> |
||||
</Content>; |
@ -0,0 +1,60 @@ |
||||
import React, { useCallback, FC } from 'react'; |
||||
|
||||
import { useEndpoint } from '../../../contexts/ServerContext'; |
||||
import { useTranslation } from '../../../contexts/TranslationContext'; |
||||
import { useTimeAgo } from '../../../hooks/useTimeAgo'; |
||||
import * as NotificationStatus from '../NotificationStatus'; |
||||
import { followStyle, anchor } from '../helpers/followSyle'; |
||||
import Metrics, { Reply, Content } from '..'; |
||||
|
||||
|
||||
type ThreadReplyOptions = { |
||||
unread: boolean; |
||||
mention: boolean; |
||||
all: boolean; lm: |
||||
Date; |
||||
mid: string; |
||||
rid: string; |
||||
counter: number; |
||||
participants: number; |
||||
following: boolean; |
||||
openThread: () => any; |
||||
}; |
||||
|
||||
const ReplyBlock: FC<ThreadReplyOptions> = ({ unread, mention, all, rid, mid, counter, participants, following, lm, openThread }) => { |
||||
const t = useTranslation(); |
||||
|
||||
const followMessage = useEndpoint('POST', 'chat.followMessage'); |
||||
const unfollowMessage = useEndpoint('POST', 'chat.unfollowMessage'); |
||||
const format = useTimeAgo(); |
||||
|
||||
const handleFollow = useCallback(() => (following ? unfollowMessage({ mid }) : followMessage({ mid })), [followMessage, following, mid, unfollowMessage]); |
||||
|
||||
return <Content className={followStyle}> |
||||
<Reply data-rid={rid} data-mid={mid} onClick={openThread} /> |
||||
<Metrics> |
||||
<Metrics.Item title={t('Replies')}> |
||||
<Metrics.Item.Icon name='thread'/> |
||||
<Metrics.Item.Label>{counter}</Metrics.Item.Label> |
||||
</Metrics.Item> |
||||
{ participants && <Metrics.Item title={t('Participants')}> |
||||
<Metrics.Item.Icon name='user'/> |
||||
<Metrics.Item.Label>{participants}</Metrics.Item.Label> |
||||
</Metrics.Item> } |
||||
<Metrics.Item> |
||||
<Metrics.Item.Icon name='clock'/> |
||||
<Metrics.Item.Label>{format(lm)}</Metrics.Item.Label> |
||||
</Metrics.Item> |
||||
<Metrics.Item className={!following ? anchor : undefined} title={t(following ? 'Following' : 'Not_following')} data-rid={rid} onClick={handleFollow}> |
||||
<Metrics.Following name={following ? 'bell' : 'bell-off'}/> |
||||
<Metrics.Item.Label>{ |
||||
(mention && <NotificationStatus.Me t={t} />) |
||||
|| (all && <NotificationStatus.All t={t} />) |
||||
|| (unread && <NotificationStatus.Unread t={t} />)} |
||||
</Metrics.Item.Label> |
||||
</Metrics.Item> |
||||
</Metrics> |
||||
</Content>; |
||||
}; |
||||
|
||||
export default ReplyBlock; |
@ -0,0 +1,15 @@ |
||||
import { css } from '@rocket.chat/css-in-js'; |
||||
|
||||
|
||||
export const anchor = 'rcx-contextual-message__follow'; |
||||
|
||||
export const followStyle = css` |
||||
& .${ anchor } { |
||||
opacity: 0; |
||||
} |
||||
.${ anchor }:focus, |
||||
&:hover .${ anchor }, |
||||
&:focus .${ anchor } { |
||||
opacity: 1; |
||||
} |
||||
`;
|
@ -0,0 +1,29 @@ |
||||
import React, { FC } from 'react'; |
||||
import { ActionButton, Box, BoxProps, Button, ButtonProps, Icon } from '@rocket.chat/fuselage'; |
||||
|
||||
import { useTranslation } from '../../contexts/TranslationContext'; |
||||
|
||||
export const Content: FC<BoxProps> = (props) => <Box display='flex' mb='x4' mi='neg-x4' {...props} />; |
||||
const ContentItem: FC = (props) => <Box display='flex' mb='x4' mi='x4' {...props} />; |
||||
|
||||
export const Reply: FC<ButtonProps> = (props) => { |
||||
const t = useTranslation(); |
||||
return <ContentItem><Button {...props} small primary>{t('Reply')}</Button></ContentItem>; |
||||
}; |
||||
|
||||
type IconProps = { name: 'thread' | 'user' | 'clock' | 'discussion' }; |
||||
type FollowingProps = { name: 'bell' | 'bell-off' }; |
||||
|
||||
const MetricsItemIcon: FC<IconProps> = (props) => <Icon size='x20' {...props} />; |
||||
const MetricsItemLabel: FC<BoxProps> = (props) => <Box mis='x4'{...props} />; |
||||
const MetricsItem: FC<BoxProps> & { Icon: FC<IconProps>; Label: FC<BoxProps> } = (props) => <Box display='flex' justifyContent='center' alignItems='center' fontScale='micro' color='info' mi='x4'{...props} />; |
||||
const Metrics: FC<BoxProps> & { Item: FC<BoxProps> & { Icon: FC<IconProps>; Label: FC }; Following: FC<FollowingProps> } = (props) => <ContentItem><Box display='flex' mi='neg-x4' {...props} /></ContentItem>; |
||||
const MetricsFollowing: FC<FollowingProps> = ({ name }) => <ActionButton color='info' small ghost icon={name} />; |
||||
|
||||
Metrics.Item = MetricsItem; |
||||
Metrics.Following = MetricsFollowing; |
||||
|
||||
MetricsItem.Label = MetricsItemLabel; |
||||
MetricsItem.Icon = MetricsItemIcon; |
||||
|
||||
export default Metrics; |
Loading…
Reference in new issue