From b5bbcb60b77a5a74488d58f4a3125b600c75adfb Mon Sep 17 00:00:00 2001 From: Nikhil Kothari Date: Fri, 23 Feb 2024 05:21:11 +0530 Subject: [PATCH] fix: autofocus tiptap editor --- .../feature/chat/ChatInput/Tiptap.tsx | 22 +++++++++++-------- .../feature/chat/ChatInput/tiptap.styles.css | 9 ++++++-- .../feature/chat/ChatStream/ChatBoxBody.tsx | 5 +++++ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/raven-app/src/components/feature/chat/ChatInput/Tiptap.tsx b/raven-app/src/components/feature/chat/ChatInput/Tiptap.tsx index bce415780..ba0fb32c1 100644 --- a/raven-app/src/components/feature/chat/ChatInput/Tiptap.tsx +++ b/raven-app/src/components/feature/chat/ChatInput/Tiptap.tsx @@ -1,7 +1,7 @@ -import { Editor, EditorContent, EditorContext, Extension, ReactRenderer, useEditor } from '@tiptap/react' +import { EditorContent, EditorContext, Extension, ReactRenderer, useEditor } from '@tiptap/react' import StarterKit from '@tiptap/starter-kit' import Underline from '@tiptap/extension-underline' -import React, { useContext, useEffect, useState } from 'react' +import React, { useContext, useEffect } from 'react' import { TextFormattingMenu } from './TextFormattingMenu' import Highlight from '@tiptap/extension-highlight' import Link from '@tiptap/extension-link' @@ -27,6 +27,7 @@ import python from 'highlight.js/lib/languages/python' import { Plugin } from 'prosemirror-state' import { Box } from '@radix-ui/themes' import { useSessionStickyState } from '@/hooks/useStickyState' +import { Message } from '../../../../../../types/Messaging/Message' const lowlight = createLowlight(common) lowlight.register('html', html) @@ -49,7 +50,8 @@ type TiptapEditorProps = { fileProps?: ToolbarFileProps, onMessageSend: (message: string, json: any) => Promise, messageSending: boolean, - defaultText?: string + defaultText?: string, + replyMessage?: Message | null } export const UserMention = Mention.extend({ @@ -71,7 +73,7 @@ export const ChannelMention = Mention.extend({ pluginKey: new PluginKey('channelMention'), } }) -const Tiptap = ({ slotBefore, fileProps, onMessageSend, clearReplyMessage, placeholder = 'Type a message...', messageSending, sessionStorageKey = 'tiptap-editor', disableSessionStorage = false, defaultText = '' }: TiptapEditorProps) => { +const Tiptap = ({ slotBefore, fileProps, onMessageSend, replyMessage, clearReplyMessage, placeholder = 'Type a message...', messageSending, sessionStorageKey = 'tiptap-editor', disableSessionStorage = false, defaultText = '' }: TiptapEditorProps) => { const { enabledUsers } = useContext(UserListContext) @@ -424,23 +426,25 @@ const Tiptap = ({ slotBefore, fileProps, onMessageSend, clearReplyMessage, place content, editorProps: { attributes: { - class: 'tiptap-editor' + class: 'tiptap-editor' + (replyMessage ? ' replying' : '') } }, onUpdate({ editor }) { setContent(editor.getHTML()) } - }, [onMessageSend]) + }, [replyMessage]) useEffect(() => { - editor?.commands.setContent(content) - }, [onMessageSend]) + setTimeout(() => { + editor?.chain().focus().run() + }, 50) + }, [replyMessage, editor]) return ( - + {slotBefore} diff --git a/raven-app/src/components/feature/chat/ChatInput/tiptap.styles.css b/raven-app/src/components/feature/chat/ChatInput/tiptap.styles.css index 6b71d3347..0359f7829 100644 --- a/raven-app/src/components/feature/chat/ChatInput/tiptap.styles.css +++ b/raven-app/src/components/feature/chat/ChatInput/tiptap.styles.css @@ -12,8 +12,13 @@ max-height: 150px; overflow: auto; padding: var(--space-3); - border-top-left-radius: var(--radius-4); - border-top-right-radius: var(--radius-4); + border-top-left-radius: var(--radius-2); + border-top-right-radius: var(--radius-2); +} + +.tiptap-editor.replying.ProseMirror { + border-top-left-radius: 0; + border-top-right-radius: 0; } .tiptap-editor.ProseMirror:focus { diff --git a/raven-app/src/components/feature/chat/ChatStream/ChatBoxBody.tsx b/raven-app/src/components/feature/chat/ChatStream/ChatBoxBody.tsx index 075ea8ce4..00dee57af 100644 --- a/raven-app/src/components/feature/chat/ChatStream/ChatBoxBody.tsx +++ b/raven-app/src/components/feature/chat/ChatStream/ChatBoxBody.tsx @@ -18,6 +18,7 @@ import { Loader } from "@/components/common/Loader" import { Flex, Box, IconButton } from "@radix-ui/themes" import { ReplyMessageBox } from "../ChatMessage/ReplyMessageBox/ReplyMessageBox" import { BiX } from "react-icons/bi" +import { VirtuosoRefContext } from "@/utils/message/VirtuosoRefProvider" const Tiptap = lazy(() => import("../ChatInput/Tiptap")) @@ -39,6 +40,7 @@ interface ChatBoxBodyProps { export const ChatBoxBody = ({ channelData }: ChatBoxBodyProps) => { + const { virtuosoRef } = useContext(VirtuosoRefContext) const { currentUser } = useContext(UserContext) const { data, error, mutate, isLoading } = useFrappeGetCall<{ message: MessagesWithDate }>("raven.api.raven_message.get_messages_with_dates", { channel_id: channelData.name @@ -54,6 +56,8 @@ export const ChatBoxBody = ({ channelData }: ChatBoxBodyProps) => { //If the sender is not the current user if (data.sender !== currentUser) { mutate() + } else { + virtuosoRef?.current?.scrollToIndex({ index: 'LAST', align: 'end', behavior: 'smooth' }) } } }) @@ -138,6 +142,7 @@ export const ChatBoxBody = ({ channelData }: ChatBoxBodyProps) => { }} clearReplyMessage={handleCancelReply} placeholder={randomPlaceholder} + replyMessage={selectedMessage} sessionStorageKey={`tiptap-${channelData.name}`} onMessageSend={sendMessage} messageSending={loading}