Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/strong-countries-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rocket.chat/meteor': minor
---

feat: `Bubble` on new messages indicators
<img width="825" alt="image" src="https://github.com/RocketChat/Rocket.Chat/assets/60678893/6fabd9a9-c3af-446c-b523-045b06615cf7">
2 changes: 1 addition & 1 deletion apps/meteor/app/theme/client/imports/general/base_old.css
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@
overflow: hidden;
flex-direction: column;

margin: 5px 10px 0;
margin: 8px 10px 0;

transition: transform 0.4s ease, visibility 0.3s ease, opacity 0.3s ease;
transform: translateY(-10px);
Expand Down
34 changes: 13 additions & 21 deletions apps/meteor/client/views/room/body/JumpToRecentMessageButton.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { css } from '@rocket.chat/css-in-js';
import { Box, Icon } from '@rocket.chat/fuselage';
import type { ReactElement, UIEvent } from 'react';
import { Box, Bubble } from '@rocket.chat/fuselage';
import type { ReactElement } from 'react';
import React, { useState } from 'react';

import { isTruthy } from '../../../../lib/isTruthy';

type JumpToRecentMessageButtonProps = {
visible: boolean;
onClick: (event: UIEvent) => void;
onClick: () => void;
text: string;
};

Expand All @@ -18,9 +18,6 @@ const buttonStyle = css`
left: 50%;
user-select: none;
transform: translate(-50%, 0);
text-align: center;
border-radius: 20px;
cursor: pointer;

&.not {
visibility: hidden;
Expand All @@ -47,21 +44,16 @@ const JumpToRecentMessageButton = ({ visible, onClick, text }: JumpToRecentMessa
const [clicked, setClicked] = useState(false);

return (
<Box
is='button'
fontScale='c2'
minWidth='x130'
bg='status-background-info'
h='x30'
pi={16}
className={[buttonStyle, !visible && 'not', clicked && 'clicked'].filter(isTruthy)}
onClick={(e) => {
onClick(e);
setClicked(true);
}}
>
{text}
<Icon name='arrow-down' size='x16' />
<Box className={[buttonStyle, !visible && 'not', clicked && 'clicked'].filter(isTruthy)}>
<Bubble
icon='arrow-down'
onClick={() => {
onClick();
setClicked(true);
}}
>
{text}
</Bubble>
</Box>
);
};
Expand Down
18 changes: 8 additions & 10 deletions apps/meteor/client/views/room/body/RoomBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -545,16 +545,7 @@ const RoomBody = (): ReactElement => {
<div className='messages-container-wrapper'>
<div className='messages-container-main' {...fileUploadTriggerProps}>
<DropTargetOverlay {...fileUploadOverlayProps} />
<div className={['container-bars', (unread || uploads.length) && 'show'].filter(isTruthy).join(' ')}>
{unread && (
<UnreadMessagesIndicator
count={unread.count}
since={unread.since}
onJumpButtonClick={handleUnreadBarJumpToButtonClick}
onMarkAsReadButtonClick={handleMarkAsReadButtonClick}
/>
)}

<div className={['container-bars', uploads.length && 'show'].filter(isTruthy).join(' ')}>
{uploads.map((upload) => (
<UploadProgressIndicator
key={upload.id}
Expand All @@ -566,6 +557,13 @@ const RoomBody = (): ReactElement => {
/>
))}
</div>
{unread && (
<UnreadMessagesIndicator
count={unread.count}
onJumpButtonClick={handleUnreadBarJumpToButtonClick}
onMarkAsReadButtonClick={handleMarkAsReadButtonClick}
/>
)}
<div
ref={messagesBoxRef}
className={['messages-box', roomLeader && !hideLeaderHeader && 'has-leader'].filter(isTruthy).join(' ')}
Expand Down
41 changes: 21 additions & 20 deletions apps/meteor/client/views/room/body/UnreadMessagesIndicator.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
import { Grid, GridItem } from '@rocket.chat/fuselage';
import { css } from '@rocket.chat/css-in-js';
import { Box, Bubble } from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React from 'react';

import { useTimeAgo } from '../../../hooks/useTimeAgo';

type UnreadMessagesIndicatorProps = {
count: number;
since?: Date;
onJumpButtonClick: () => void;
onMarkAsReadButtonClick: () => void;
};

const UnreadMessagesIndicator = ({
count,
since,
onJumpButtonClick,
onMarkAsReadButtonClick,
}: UnreadMessagesIndicatorProps): ReactElement => {
const indicatorStyle = css`
position: absolute;
top: 8px;
left: 50%;
translate: -50%;
z-index: 1;
`;

const UnreadMessagesIndicator = ({ count, onJumpButtonClick, onMarkAsReadButtonClick }: UnreadMessagesIndicatorProps): ReactElement => {
const t = useTranslation();
const formatTimeAgo = useTimeAgo();

return (
<Grid color='pure-black' bg='status-background-info'>
<GridItem is='button' fontWeight={700} onClick={onJumpButtonClick}>
{t('Jump_to_first_unread')}
</GridItem>
<GridItem textAlign='center'>{t('S_new_messages_since_s', count, since ? formatTimeAgo(since) : undefined)}</GridItem>
<GridItem textAlign='end' is='button' fontWeight={700} onClick={onMarkAsReadButtonClick}>
{t('Mark_as_read')}
</GridItem>
</Grid>
<Box className={indicatorStyle}>
<Bubble
onClick={onJumpButtonClick}
onDismiss={onMarkAsReadButtonClick}
icon='arrow-up'
dismissProps={{ 'title': t('Mark_as_read'), 'aria-label': `${t('Mark_as_read')}` }}
>
{t('S_unread_messages', count)}
</Bubble>
</Box>
);
};

Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -4488,6 +4488,7 @@
"Running_Instances": "Running Instances",
"Runtime_Environment": "Runtime Environment",
"S_new_messages_since_s": "%s new messages since %s",
"S_new_messages": "%s new messages",
"Same_As_Token_Sent_Via": "Same as \"Token Sent Via\"",
"Same_Style_For_Mentions": "Same style for mentions",
"SAML": "SAML",
Expand Down Expand Up @@ -5363,6 +5364,7 @@
"Unread_Count_DM": "Unread Count for Direct Messages",
"Unread_Count_Omni": "Unread Count for Omnichannel Chats",
"Unread_Messages": "Unread Messages",
"S_unread_messages": "%s unread messages",
"Unread_on_top": "Unread on top",
"Unread_Rooms": "Unread Rooms",
"Unread_Rooms_Mode": "Unread Rooms Mode",
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9147,6 +9147,18 @@ __metadata:
languageName: node
linkType: hard

"@rocket.chat/fuselage-hooks@npm:^0.33.0":
version: 0.33.0
resolution: "@rocket.chat/fuselage-hooks@npm:0.33.0"
dependencies:
use-sync-external-store: ~1.2.0
peerDependencies:
"@rocket.chat/fuselage-tokens": "*"
react: ^17.0.2
checksum: addf78db893c3185d4d5fc347e1aa81710e0939505a08db77e524740d05555c5e8556d2b6f0e6425270621bdd7230d13278add77ce38197c048af30207cce853
languageName: node
linkType: hard

"@rocket.chat/fuselage-polyfills@npm:~0.31.25":
version: 0.31.25
resolution: "@rocket.chat/fuselage-polyfills@npm:0.31.25"
Expand Down