feat: emojies

This commit is contained in:
Nevo David 2024-12-27 17:50:03 +07:00
parent 528383a71d
commit 4079a42f09
5 changed files with 306 additions and 761 deletions

View File

@ -1,10 +1,14 @@
import { forwardRef } from 'react'; import { forwardRef, useCallback, useRef, useState } from 'react';
import type { MDEditorProps } from '@uiw/react-md-editor/src/Types'; import type { MDEditorProps } from '@uiw/react-md-editor/src/Types';
import { RefMDEditor } from '@uiw/react-md-editor/src/Editor'; import { RefMDEditor } from '@uiw/react-md-editor/src/Editor';
import { useCopilotAction, useCopilotReadable } from '@copilotkit/react-core'; import { useCopilotAction, useCopilotReadable } from '@copilotkit/react-core';
import { CopilotTextarea } from '@copilotkit/react-textarea'; import { CopilotTextarea } from '@copilotkit/react-textarea';
import clsx from 'clsx'; import clsx from 'clsx';
import { useUser } from '@gitroom/frontend/components/layout/user.context'; import { useUser } from '@gitroom/frontend/components/layout/user.context';
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
import { Transforms } from 'slate';
import EmojiPicker from 'emoji-picker-react';
import { Theme } from 'emoji-picker-react';
export const Editor = forwardRef< export const Editor = forwardRef<
RefMDEditor, RefMDEditor,
@ -19,6 +23,10 @@ export const Editor = forwardRef<
ref: React.ForwardedRef<RefMDEditor> ref: React.ForwardedRef<RefMDEditor>
) => { ) => {
const user = useUser(); const user = useUser();
const [id] = useState(makeId(10));
const newRef = useRef(null);
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
useCopilotReadable({ useCopilotReadable({
description: 'Content of the post number ' + (props.order + 1), description: 'Content of the post number ' + (props.order + 1),
value: props.value, value: props.value,
@ -38,24 +46,55 @@ export const Editor = forwardRef<
}, },
}); });
const addText = useCallback(
(emoji: string) => {
// @ts-ignore
Transforms.insertText(newRef?.current?.editor!, emoji);
},
[props.value, id]
);
return ( return (
<div className="relative bg-customColor2"> <>
<CopilotTextarea <div className="flex justify-end -mt-[30px]">
disableBranding={true} <div
className={clsx( className="select-none cursor-pointer bg-customColor2 w-[40px] p-[5px] text-center rounded-tl-lg rounded-tr-lg"
'!min-h-40 !max-h-80 p-2 overflow-x-hidden scrollbar scrollbar-thumb-[#612AD5] bg-customColor2 outline-none' onClick={() => setEmojiPickerOpen(!emojiPickerOpen)}
)} >
value={props.value} 😀
onChange={(e) => props?.onChange?.(e.target.value)} </div>
onPaste={props.onPaste} </div>
placeholder="Write your reply..." <div className="absolute z-[200] right-0">
autosuggestionsConfig={{ <EmojiPicker
textareaPurpose: `Assist me in writing social media posts.`, theme={localStorage.getItem('mode') as Theme || Theme.DARK}
chatApiConfigs: {}, onEmojiClick={(e) => {
disabled: !user?.tier?.ai, addText(e.emoji);
}} setEmojiPickerOpen(false);
/> }}
</div> open={emojiPickerOpen}
/>
</div>
<div className="relative bg-customColor2" id={id}>
<CopilotTextarea
disableBranding={true}
ref={newRef}
className={clsx(
'!min-h-40 !max-h-80 p-2 overflow-x-hidden scrollbar scrollbar-thumb-[#612AD5] bg-customColor2 outline-none'
)}
value={props.value}
onChange={(e) => {
props?.onChange?.(e.target.value);
}}
onPaste={props.onPaste}
placeholder="Write your reply..."
autosuggestionsConfig={{
textareaPurpose: `Assist me in writing social media posts.`,
chatApiConfigs: {},
disabled: !user?.tier?.ai,
}}
/>
</div>
</>
); );
} }
); );

View File

@ -413,7 +413,7 @@ export const withProvider = function <T extends object>(
<div> <div>
<div className="flex gap-[4px]"> <div className="flex gap-[4px]">
<div className="flex-1 text-textColor editor"> <div className="flex-1 text-textColor editor">
{integration?.identifier === 'linkedin' && ( {(integration?.identifier === 'linkedin' || integration?.identifier === 'linkedin-page') && (
<Button <Button
className="mb-[5px]" className="mb-[5px]"
onClick={tagPersonOrCompany( onClick={tagPersonOrCompany(

View File

@ -4,11 +4,14 @@ export const useClickOutside = (callback: () => Promise<void>) => {
const handleClick = (event: MouseEvent) => { const handleClick = (event: MouseEvent) => {
const selector = document.querySelector('#add-edit-modal'); const selector = document.querySelector('#add-edit-modal');
const copilotkit = document.querySelector('.copilotKitPopup'); const copilotkit = document.querySelector('.copilotKitPopup');
const emoji = document.querySelector('.EmojiPickerReact');
if ( if (
selector && selector &&
!selector.contains(event.target as HTMLElement) && !selector.contains(event.target as HTMLElement) &&
copilotkit && copilotkit &&
!copilotkit.contains(event.target as HTMLElement) !copilotkit.contains(event.target as HTMLElement) &&
emoji &&
!emoji.contains(event.target as HTMLElement)
) { ) {
callback(); callback();
} }

984
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -115,6 +115,7 @@
"copy-to-clipboard": "^3.3.3", "copy-to-clipboard": "^3.3.3",
"crypto-hash": "^3.0.0", "crypto-hash": "^3.0.0",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"emoji-picker-react": "^4.12.0",
"facebook-nodejs-business-sdk": "^21.0.5", "facebook-nodejs-business-sdk": "^21.0.5",
"google-auth-library": "^9.11.0", "google-auth-library": "^9.11.0",
"googleapis": "^137.1.0", "googleapis": "^137.1.0",