Skip to content

Commit

Permalink
merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
imf-ali committed Nov 29, 2023
1 parent b1614cb commit 8435f90
Show file tree
Hide file tree
Showing 12 changed files with 305 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { Meteor } from 'meteor/meteor';

import type { ComposerAPI } from '../../../../client/lib/chats/ChatAPI';
import { withDebouncing } from '../../../../lib/utils/highOrderFunctions';
import buildMarkdown from '../../../ui-utils/client/lib/buildMarkDown';
import type { FormattingButton } from './messageBoxFormatting';
import { formattingButtons } from './messageBoxFormatting';

export const createComposerAPI = (input: HTMLTextAreaElement, storageID: string): ComposerAPI => {
export const createComposerAPI = (input: any, storageID: string): ComposerAPI => {
const triggerEvent = (input: HTMLTextAreaElement, evt: string): void => {
const event = new Event(evt, { bubbles: true });
// TODO: Remove this hack for react to trigger onChange
Expand Down Expand Up @@ -93,6 +94,9 @@ export const createComposerAPI = (input: HTMLTextAreaElement, storageID: string)
};

const clear = (): void => {
while (input.childNodes[0].firstChild) {
input.childNodes[0].removeChild(input.childNodes[0].firstChild);
}
setText('');
};

Expand Down Expand Up @@ -260,6 +264,12 @@ export const createComposerAPI = (input: HTMLTextAreaElement, storageID: string)
focus();
};

const wrapSelectionV2 = (_?: string): void => {
// console.log(input.innerHTML);
setText(buildMarkdown(input));
// console.log(pattern);
};

const insertNewLine = (): void => insertText('\n');

setText(Meteor._localStorage.getItem(storageID) ?? '', {
Expand Down Expand Up @@ -314,6 +324,7 @@ export const createComposerAPI = (input: HTMLTextAreaElement, storageID: string)
},
release,
wrapSelection,
wrapSelectionV2,
get text(): string {
return input.value;
},
Expand Down
50 changes: 50 additions & 0 deletions apps/meteor/app/ui-utils/client/lib/buildMarkDown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const elementTagMaps = {
strong: '*',
em: '_',
s: '~',
li: '- ',
p: '\n',
br: '',
span: '',
};

const makeListMarkDown = (element: HTMLElement) => {
let text = '';
for (let i = 0; i < element.childNodes.length - 1; i++) {
const child = element.childNodes[i];
if (element.nodeName.toLowerCase() === 'ol') {
text += `${i + 1}. `;
} else {
const mdSymbol = elementTagMaps[child.nodeName.toLowerCase() as keyof typeof elementTagMaps] || '';
text += mdSymbol;
}
text += parseMarkdown(child as HTMLElement);
text += '\n';
}
return text;
};

const parseMarkdown = (element: HTMLElement) => {
let text = '';
for (const child of element.childNodes) {
if (child.nodeType === Node.TEXT_NODE) {
text += child.textContent || '';
} else if (child.nodeType === Node.ELEMENT_NODE) {
if (child.nodeName.toLowerCase() === 'ul' || child.nodeName.toLowerCase() === 'ol') {
text += makeListMarkDown(child as HTMLElement);
continue;
}
const mdSymbol = elementTagMaps[child.nodeName.toLowerCase() as keyof typeof elementTagMaps] || '';
text += mdSymbol;
text += parseMarkdown(child as HTMLElement);
if (child.nodeName.toLowerCase() !== 'p') text += mdSymbol;
}
}
return text;
};

const buildMarkdown = (element: HTMLElement) => {
return parseMarkdown(element.childNodes[0] as HTMLElement);
};

export default buildMarkdown;
1 change: 1 addition & 0 deletions apps/meteor/client/lib/chats/ChatAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type ComposerAPI = {
},
): void;
wrapSelection(pattern: string): void;
wrapSelectionV2(pattern?: string): void;
insertText(text: string): void;
insertNewLine(): void;
clear(): void;
Expand Down
49 changes: 28 additions & 21 deletions apps/meteor/client/views/room/composer/messageBox/MessageBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
MessageComposerActionsDivider,
MessageComposerToolbarSubmit,
} from '@rocket.chat/ui-composer';
import { useTranslation, useUserPreference, useLayout } from '@rocket.chat/ui-contexts';
import { useTranslation, useUserPreference, useLayout, useQuill } from '@rocket.chat/ui-contexts';
import { useMutation } from '@tanstack/react-query';
import type { ReactElement, MouseEventHandler, FormEvent, KeyboardEventHandler, KeyboardEvent, Ref, ClipboardEventHandler } from 'react';
import React, { memo, useRef, useReducer, useCallback } from 'react';
Expand All @@ -26,7 +26,6 @@ import { useEnablePopupPreview } from '../../../../../app/ui-message/client/popu
import { getImageExtensionFromMime } from '../../../../../lib/getImageExtensionFromMime';
import { useFormatDateAndTime } from '../../../../hooks/useFormatDateAndTime';
import { useReactiveValue } from '../../../../hooks/useReactiveValue';
import type { ComposerAPI } from '../../../../lib/chats/ChatAPI';
import { roomCoordinator } from '../../../../lib/rooms/roomCoordinator';
import { keyCodes } from '../../../../lib/utils/keyCodes';
import AudioMessageRecorder from '../../../composer/AudioMessageRecorder';
Expand All @@ -42,6 +41,7 @@ import MessageBoxFormattingToolbar from './MessageBoxFormattingToolbar';
import MessageBoxReplies from './MessageBoxReplies';
import { useMessageBoxAutoFocus } from './hooks/useMessageBoxAutoFocus';
import { useMessageBoxPlaceholder } from './hooks/useMessageBoxPlaceholder';
import 'quill/dist/quill.snow.css';

const reducer = (_: unknown, event: FormEvent<HTMLInputElement>): boolean => {
const target = event.target as HTMLInputElement;
Expand All @@ -52,7 +52,7 @@ const reducer = (_: unknown, event: FormEvent<HTMLInputElement>): boolean => {
const handleFormattingShortcut = (
event: KeyboardEvent<HTMLTextAreaElement>,
formattingButtons: FormattingButton[],
composer: ComposerAPI,
// composer: ComposerAPI,
) => {
const isMacOS = navigator.platform.indexOf('Mac') !== -1;
const isCmdOrCtrlPressed = (isMacOS && event.metaKey) || (!isMacOS && event.ctrlKey);
Expand All @@ -69,7 +69,10 @@ const handleFormattingShortcut = (
return false;
}

composer.wrapSelection(formatter.pattern);
// const input = event.target as any;
// console.log(input.innerText);

// composer.wrapSelectionV2(formatter.pattern);
return true;
};

Expand Down Expand Up @@ -124,14 +127,19 @@ const MessageBox = ({
throw new Error('Chat context not found');
}

const { quillRef } = useQuill({
modules: {
toolbar: '#toolbar',
},
});
const textareaRef = useRef<HTMLTextAreaElement>(null);
const messageComposerRef = useRef<HTMLElement>(null);
const shadowRef = useRef(null);

const storageID = `${room._id}${tmid ? `-${tmid}` : ''}`;

const callbackRef = useCallback(
(node: HTMLTextAreaElement) => {
(node: any) => {
if (node === null) {
return;
}
Expand All @@ -157,6 +165,7 @@ const MessageBox = ({
});

const handleSendMessage = useMutableCallback(() => {
chat.composer?.wrapSelectionV2();
const text = chat.composer?.text ?? '';
chat.composer?.clear();
clearPopup();
Expand All @@ -171,7 +180,7 @@ const MessageBox = ({
const handler: KeyboardEventHandler<HTMLTextAreaElement> = useMutableCallback((event) => {
const { which: keyCode } = event;

const input = event.target as HTMLTextAreaElement;
const input = event.target as any;

const isSubmitKey = keyCode === keyCodes.CARRIAGE_RETURN || keyCode === keyCodes.NEW_LINE;

Expand Down Expand Up @@ -231,14 +240,15 @@ const MessageBox = ({
}

case 'ArrowDown': {
if (input.selectionEnd === input.value.length) {
console.log(input.selectionEnd, input.innerText.length);
if (input.selectionEnd === input.innerText.length) {
event.preventDefault();
event.stopPropagation();

onNavigateToNextMessage?.();

if (event.altKey) {
input.setSelectionRange(input.value.length, input.value.length);
input.setSelectionRange(input.innerText.length, input.innerText.length);
}
}
}
Expand Down Expand Up @@ -333,15 +343,15 @@ const MessageBox = ({
ariaActiveDescendant,
suspended,
select,
clearPopup,
commandsRef,
callbackRef: c,
filter,
clearPopup,
} = useComposerBoxPopup<{ _id: string; sort?: number }>({
configurations: composerPopupConfig,
});

const mergedRefs = useMessageComposerMergedRefs(c, textareaRef, callbackRef, autofocusRef);
const mergedRefs = useMessageComposerMergedRefs(c, quillRef, callbackRef, autofocusRef);

const shouldPopupPreview = useEnablePopupPreview(filter, popup);

Expand Down Expand Up @@ -381,7 +391,7 @@ const MessageBox = ({
<MessageComposer ref={messageComposerRef} variant={isEditing ? 'editing' : undefined}>
{isRecordingAudio && <AudioMessageRecorder rid={room._id} isMicrophoneDenied={isMicrophoneDenied} />}
<MessageComposerInput
ref={mergedRefs as unknown as Ref<HTMLInputElement>}
ref={mergedRefs as unknown as Ref<any>}
aria-label={composerPlaceholder}
name='msg'
disabled={isRecording || !canSend}
Expand Down Expand Up @@ -427,16 +437,13 @@ const MessageBox = ({
{t('Join')}
</Button>
)}
{canSend && (
<MessageComposerAction
aria-label={t('Send')}
icon='send'
disabled={!canSend || (!typing && !isEditing)}
onClick={handleSendMessage}
secondary={typing || isEditing}
info={typing || isEditing}
/>
)}
<MessageComposerAction
aria-label={t('Send')}
icon='send'
onClick={handleSendMessage}
secondary={typing || isEditing}
info={typing || isEditing}
/>
</MessageComposerToolbarSubmit>
</MessageComposerToolbar>
</MessageComposer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import type { ComposerAPI } from '../../../../../lib/chats/ChatAPI';
import { useDropdownVisibility } from '../../../../../sidebar/header/hooks/useDropdownVisibility';

type FormattingToolbarDropdownProps = {
composer: ComposerAPI;
composer?: ComposerAPI;
items: FormattingButton[];
};

const FormattingToolbarDropdown = ({ composer, items, ...props }: FormattingToolbarDropdownProps) => {
const FormattingToolbarDropdown = ({ composer: _, items, ...props }: FormattingToolbarDropdownProps) => {
const t = useTranslation();
const reference = useRef(null);
const target = useRef(null);
Expand All @@ -28,9 +28,9 @@ const FormattingToolbarDropdown = ({ composer, items, ...props }: FormattingTool
const handleFormattingAction = () => {
if ('link' in formatter) {
window.open(formatter.link, '_blank', 'rel=noreferrer noopener');
return;
// return;
}
composer.wrapSelection(formatter.pattern);
// composer.wrapSelectionV2(formatter.pattern);
};

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Box } from '@rocket.chat/fuselage';
import { MessageComposerAction } from '@rocket.chat/ui-composer';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { memo } from 'react';
Expand All @@ -16,40 +17,41 @@ type MessageBoxFormattingToolbarProps = {
const MessageBoxFormattingToolbar = ({ items, variant = 'large', composer, ...props }: MessageBoxFormattingToolbarProps) => {
const t = useTranslation();

if (variant === 'small') {
if (variant === 'large') {
const collapsedItems = [...items];
const featuredFormatter = collapsedItems.splice(0, 1)[0];

return (
<>
<Box id='toolbar' style={{ display: 'flex', flexDirection: 'row', border: 0, padding: 0 }}>
{'icon' in featuredFormatter && (
<MessageComposerAction
{...props}
onClick={() => composer.wrapSelection(featuredFormatter.pattern)}
className={`ql-${featuredFormatter.icon}`}
// onClick={() => composer.wrapSelectionV2(featuredFormatter.pattern)}
icon={featuredFormatter.icon}
/>
)}
<FormattingToolbarDropdown {...props} composer={composer} items={collapsedItems} />
</>
</Box>
);
}

return (
<>
{items.map((formatter) =>
<Box id='toolbar' style={{ display: 'flex', flexDirection: 'row', border: 0, padding: 0 }}>
{items.slice(0, 3).map((formatter) =>
'icon' in formatter ? (
<MessageComposerAction
{...props}
className={`ql-${formatter.icon}`}
icon={formatter.icon}
key={formatter.label}
data-id={formatter.label}
title={t(formatter.label)}
onClick={(): void => {
if ('link' in formatter) {
window.open(formatter.link, '_blank', 'rel=noreferrer noopener');
return;
}
composer.wrapSelection(formatter.pattern);
// composer.wrapSelectionV2(formatter.pattern);
}}
/>
) : (
Expand All @@ -66,7 +68,7 @@ const MessageBoxFormattingToolbar = ({ items, variant = 'large', composer, ...pr
</span>
),
)}
</>
</Box>
);
};

Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@
"@types/lodash.debounce": "^4.0.8",
"@types/object-path": "^0.11.3",
"@types/proxy-from-env": "^1.0.3",
"@types/quill": "^2.0.11",
"@types/speakeasy": "^2.0.9",
"@xmldom/xmldom": "^0.8.10",
"adm-zip": "0.5.10",
Expand Down Expand Up @@ -398,6 +399,7 @@
"psl": "^1.8.0",
"query-string": "^7.1.3",
"queue-fifo": "^0.2.6",
"quill": "^1.3.7",
"rc-scrollbars": "^1.1.6",
"react": "~17.0.2",
"react-aria": "~3.23.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const MessageComposerInput = forwardRef(function MessageComposerInput(
pi={12}
mb={16}
borderWidth={0}
is='textarea'
/>
</Box>
);
Expand Down
2 changes: 2 additions & 0 deletions packages/ui-contexts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
"@rocket.chat/fuselage-hooks": "^0.32.1",
"@rocket.chat/rest-typings": "workspace:^",
"@types/jest": "~29.5.7",
"@types/quill": "^2.0.11",
"@types/react": "~17.0.69",
"@types/react-dom": "~17.0.22",
"@types/use-sync-external-store": "^0.0.5",
"eslint": "~8.45.0",
"eslint-plugin-react-hooks": "^4.6.0",
"jest": "~29.6.4",
"mongodb": "^4.17.1",
"quill": "^1.3.7",
"react": "~17.0.2",
"ts-jest": "~29.0.5",
"typescript": "~5.2.2",
Expand Down
Loading

0 comments on commit 8435f90

Please sign in to comment.