Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: SlashCommands Preview #28065

Merged
merged 11 commits into from
Feb 16, 2023
11 changes: 11 additions & 0 deletions apps/meteor/app/lib/server/methods/executeSlashCommandPreview.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import type { IMessage, SlashCommandPreviewItem } from '@rocket.chat/core-typings';
import { Meteor } from 'meteor/meteor';

import { slashCommands } from '../../../utils/server';

declare module '@rocket.chat/ui-contexts' {
// eslint-disable-next-line @typescript-eslint/naming-convention
export interface ServerMethods {
executeSlashCommandPreview(
command: { cmd: string; params: string; msg: Pick<IMessage, 'rid' | 'tmid'> },
preview: SlashCommandPreviewItem,
): Promise<void>;
}
}

Meteor.methods({
executeSlashCommandPreview(command, preview) {
if (!Meteor.userId()) {
Expand Down
8 changes: 8 additions & 0 deletions apps/meteor/app/lib/server/methods/getSlashCommandPreviews.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import type { IMessage, SlashCommandPreviews } from '@rocket.chat/core-typings';
import { Meteor } from 'meteor/meteor';

import { slashCommands } from '../../../utils/server';

declare module '@rocket.chat/ui-contexts' {
// eslint-disable-next-line @typescript-eslint/naming-convention
export interface ServerMethods {
getSlashCommandPreviews(command: { cmd: string; params: string; msg: Pick<IMessage, 'rid' | 'tmid'> }): Promise<SlashCommandPreviews>;
}
}

Meteor.methods({
getSlashCommandPreviews(command) {
if (!Meteor.userId()) {
Expand Down
71 changes: 9 additions & 62 deletions apps/meteor/app/theme/client/imports/general/base_old.css
Original file line number Diff line number Diff line change
Expand Up @@ -1051,19 +1051,18 @@
}
}

.rc-old .message-popup-items.preview-items {
display: flex;
overflow-y: auto;
}

.rc-old .preview-items .popup-item {
padding: 5px;
margin: 2px;

line-height: unset;
}
padding: 0;

cursor: pointer;

user-select: none;

.rc-old .message-popup.popup-with-reply-preview {
border-radius: 5px 5px 0 0;
border: solid 1px transparent;

line-height: initial;
}

.rc-old .message-popup {
Expand All @@ -1079,58 +1078,6 @@
box-shadow: 0 -1px 10px 0 rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, 0.16);
}

.rc-old .popup-item {
padding: 0 20px;

cursor: pointer;
user-select: none;

line-height: 32px;
}

.rc-old .popup-user-avatar {
display: inline-block;

width: 24px;
height: 24px;
margin: -7px 4px;

border-radius: 3px;
background-size: contain;
}

.rc-old .popup-user-not_in_channel {
overflow: hidden;

white-space: nowrap;
text-overflow: ellipsis;
}

.rc-old .popup-user {
display: flex;
align-items: center;

&-avatar_wrap,
&-name {
margin-right: 4px;
flex-shrink: 0;
}
}

.rc-old .popup-user-notice {
min-width: 0;
margin-left: auto;
}

.rc-old .popup-user-status {
display: inline-block;

width: 10px;
height: 10px;

border-radius: 10px;
}

.messages-box {
position: relative;

Expand Down
20 changes: 0 additions & 20 deletions apps/meteor/app/theme/client/imports/general/theme_old.css
Original file line number Diff line number Diff line change
Expand Up @@ -103,26 +103,6 @@
border-color: var(--transparent-dark);
}

* {
-webkit-overflow-scrolling: touch;

&::-webkit-scrollbar {
width: 8px;
height: 8px;

background: var(--transparent-dark);
}

&::-webkit-scrollbar-thumb {
border-radius: 50px;
background-color: var(--custom-scrollbar-color);
}

&::-webkit-scrollbar-corner {
background-color: var(--transparent-dark);
}
}

.filter-item {
&:hover {
border-color: var(--info-font-color);
Expand Down
73 changes: 48 additions & 25 deletions apps/meteor/app/ui-message/client/popup/ComposerBoxPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { Box, Option, OptionSkeleton, Tile } from '@rocket.chat/fuselage';
import { useUniqueId } from '@rocket.chat/fuselage-hooks';
import type { UseQueryResult } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import React from 'react';
import React, { useEffect, memo, useMemo } from 'react';
import { useTranslation } from '@rocket.chat/ui-contexts';

type ComposerBoxPopupProps<
export type ComposerBoxPopupProps<
T extends {
_id: string;
sort?: number;
Expand All @@ -17,7 +18,7 @@ type ComposerBoxPopupProps<
renderItem?: ({ item }: { item: T }) => ReactElement;
};

export const ComposerBoxPopup = <
const ComposerBoxPopup = <
T extends {
_id: string;
sort?: number;
Expand All @@ -29,7 +30,33 @@ export const ComposerBoxPopup = <
select,
renderItem = ({ item }: { item: T }) => <>{JSON.stringify(item)}</>,
}: ComposerBoxPopupProps<T>): ReactElement | null => {
const t = useTranslation();
const id = useUniqueId();

const itemsFlat = useMemo(
() =>
items
.flatMap((item) => {
if (item.isSuccess) {
return item.data;
}
return [];
})
.sort((a, b) => (('sort' in a && a.sort) || 0) - (('sort' in b && b.sort) || 0)),
[items],
);

const isLoading = items.some((item) => item.isLoading && item.fetchStatus !== 'idle');

useEffect(() => {
if (focused) {
const element = document.getElementById(`popup-item-${focused._id}`);
if (element) {
element.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
}
}, [focused]);

return (
<Box className='message-popup-position' position='relative'>
<Tile className='message-popup' padding={0} role='menu' mbe='x2' maxHeight='20rem' aria-labelledby={id}>
Expand All @@ -39,30 +66,26 @@ export const ComposerBoxPopup = <
</Box>
)}
<Box pb='x8'>
{items
.flatMap((item) => {
if (item.isSuccess) {
return item.data;
}
return [];
})
.sort((a, b) => (('sort' in a && a.sort) || 0) - (('sort' in b && b.sort) || 0))
.map((item, index) => {
return (
<Option
onClick={() => select(item)}
selected={item === focused}
key={index}
id={`popup-item-${item._id}`}
tabIndex={item === focused ? 0 : -1}
>
{renderItem({ item })}
</Option>
);
})}
{items.some((item) => item.isLoading && item.fetchStatus !== 'idle') && <OptionSkeleton />}
{!isLoading && itemsFlat.length === 0 && <Option>{t('No_results_found')}</Option>}
{itemsFlat.map((item, index) => {
return (
<Option
onClick={() => select(item)}
selected={item === focused}
key={index}
id={`popup-item-${item._id}`}
tabIndex={item === focused ? 0 : -1}
aria-selected={item === focused}
>
{renderItem({ item })}
</Option>
);
})}
{isLoading && <OptionSkeleton />}
</Box>
</Tile>
</Box>
);
};

export default memo(ComposerBoxPopup);
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { OptionColumn, OptionContent } from '@rocket.chat/fuselage';

import Emoji from '../../../../../client/components/Emoji';
import Emoji from '../../../../../../client/components/Emoji';

export type ComposerBoxPopupEmojiProps = {
_id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { OptionColumn, OptionContent } from '@rocket.chat/fuselage';
import type { IRoom } from '@rocket.chat/core-typings';

import { RoomIcon } from '../../../../../client/components/RoomIcon';
import { RoomIcon } from '../../../../../../client/components/RoomIcon';

export type ComposerBoxPopupRoomProps = Pick<IRoom, 't' | 'name' | 'fname' | '_id' | 'prid' | 'teamMain' | 'u'>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react';
import { useTranslation } from '@rocket.chat/ui-contexts';
import { OptionAvatar, OptionColumn, OptionContent } from '@rocket.chat/fuselage';

import UserAvatar from '../../../../../client/components/avatar/UserAvatar';
import ReactiveUserStatus from '../../../../../client/components/UserStatus/ReactiveUserStatus';
import UserAvatar from '../../../../../../client/components/avatar/UserAvatar';
import ReactiveUserStatus from '../../../../../../client/components/UserStatus/ReactiveUserStatus';

export type ComposerBoxPopupUserProps = {
_id: string;
Expand All @@ -30,7 +30,8 @@ const ComposerBoxPopupUser = ({ _id, system, username, name, nickname, outside,
<ReactiveUserStatus uid={_id} />
</OptionColumn>
<OptionContent>
<strong>{name ?? username}</strong> {nickname && <span className='popup-user-nickname'>({nickname})</span>}
<strong>{name ?? username}</strong> {name && name !== username && username}
{nickname && <span className='popup-user-nickname'>({nickname})</span>}
</OptionContent>
</>
)}
Expand Down