From ad9f9a165c8e9128c57052aac2950d3c568a7196 Mon Sep 17 00:00:00 2001 From: newt Date: Fri, 2 May 2025 21:09:09 +0900 Subject: [PATCH 1/5] feat: improve message area height --- .../[channel_id]/_components/Channel/Channel.module.css | 7 +++---- .../channels/[channel_id]/_components/Channel/Channel.tsx | 4 +--- src/app/globals.css | 5 +++++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/channels/[channel_id]/_components/Channel/Channel.module.css b/src/app/channels/[channel_id]/_components/Channel/Channel.module.css index a8bf2f3..f527acb 100644 --- a/src/app/channels/[channel_id]/_components/Channel/Channel.module.css +++ b/src/app/channels/[channel_id]/_components/Channel/Channel.module.css @@ -3,13 +3,12 @@ flex-direction: column; max-width: 100%; height: 100svh; - min-height: 100vh; - padding-top: 3rem; } .message-area { display: flex; flex-direction: column; - height: 100%; + height: 100svh; + padding-top: 10rem; overflow-y: scroll; -} \ No newline at end of file +} diff --git a/src/app/channels/[channel_id]/_components/Channel/Channel.tsx b/src/app/channels/[channel_id]/_components/Channel/Channel.tsx index 52b45aa..f8dd64c 100644 --- a/src/app/channels/[channel_id]/_components/Channel/Channel.tsx +++ b/src/app/channels/[channel_id]/_components/Channel/Channel.tsx @@ -31,8 +31,6 @@ const Channel: React.FC = ({ channel_id, messages, user_id }) => { // TODO: onloadの自動スクロールがうまくいかないため無限スクロールを実装するタイミングで検証します const messagesEndRef = useRef(null); - const is_joined = messages.some((message) => message.user.id === user_id); - useLayoutEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: "instant" }); }, [messages]); @@ -54,7 +52,7 @@ const Channel: React.FC = ({ channel_id, messages, user_id }) => { ); diff --git a/src/app/globals.css b/src/app/globals.css index be6d7d5..814adf1 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,3 +1,8 @@ +html { + height: 100svh; + overflow: hidden; +} + body { padding: 0; margin: 0; From ca9ddb8a94d05765d6dbbdad47b2ba0c3d012266 Mon Sep 17 00:00:00 2001 From: newt Date: Fri, 2 May 2025 21:59:39 +0900 Subject: [PATCH 2/5] fix: message area height --- .../_components/Channel/Channel.module.css | 2 +- .../TextEditor/TextEditor.module.css | 46 ++++++- .../_components/TextEditor/TextEditor.tsx | 127 +++++++++++------- 3 files changed, 122 insertions(+), 53 deletions(-) diff --git a/src/app/channels/[channel_id]/_components/Channel/Channel.module.css b/src/app/channels/[channel_id]/_components/Channel/Channel.module.css index f527acb..f09f0f7 100644 --- a/src/app/channels/[channel_id]/_components/Channel/Channel.module.css +++ b/src/app/channels/[channel_id]/_components/Channel/Channel.module.css @@ -9,6 +9,6 @@ display: flex; flex-direction: column; height: 100svh; - padding-top: 10rem; + padding-top: 80svh; overflow-y: scroll; } diff --git a/src/app/channels/[channel_id]/_components/TextEditor/TextEditor.module.css b/src/app/channels/[channel_id]/_components/TextEditor/TextEditor.module.css index c4742ad..babb405 100644 --- a/src/app/channels/[channel_id]/_components/TextEditor/TextEditor.module.css +++ b/src/app/channels/[channel_id]/_components/TextEditor/TextEditor.module.css @@ -1,7 +1,10 @@ .editor { + position: relative; + width: 100%; margin-top: 0; background-color: var(--mantine-color-white); border: 2px solid var(--mantine-color-gray-3); + border-radius: 0.5rem; &:hover { border-color: var(--mantine-color-gray-4); @@ -13,10 +16,47 @@ } .content { + box-sizing: border-box; + width: 100%; max-height: 50vh; - padding: 0.5rem; - padding-bottom: 0; + padding: 0.5rem 3.5rem 0.5rem 0.5rem; overflow-y: scroll; + font-size: 1rem; + resize: none; + background: transparent; + border: none; +} + +.textareaWrapper { + position: relative; +} + +.previewOverlay { + position: absolute; + top: 0; + left: 0; + z-index: 10; + box-sizing: border-box; + width: 100%; + min-height: 100%; + padding: 0.75rem; + overflow-y: auto; + background: #f8f9fa; + border: 1px solid #eee; + border-radius: 0.5rem; +} + +.hideWhenPreview { + visibility: hidden; +} + +.actionArea { + position: absolute; + top: 0.5rem; + right: 0.5rem; + z-index: 2; + display: flex; + gap: 0.25rem; } .toolbar { @@ -61,4 +101,4 @@ background-color: var(--mantine-color-gray-3); border: none; border-radius: 0.5rem; -} \ No newline at end of file +} diff --git a/src/app/channels/[channel_id]/_components/TextEditor/TextEditor.tsx b/src/app/channels/[channel_id]/_components/TextEditor/TextEditor.tsx index fe698c5..41ffa72 100644 --- a/src/app/channels/[channel_id]/_components/TextEditor/TextEditor.tsx +++ b/src/app/channels/[channel_id]/_components/TextEditor/TextEditor.tsx @@ -1,24 +1,20 @@ "use client"; +import dynamic from "next/dynamic"; import React, { useState, useTransition } from "react"; -import { ActionIcon, Image } from "@mantine/core"; -import { Link, RichTextEditor } from "@mantine/tiptap"; +import { ActionIcon, Box, Image, Textarea, Tooltip } from "@mantine/core"; import { Asset } from "@prisma/client"; -import { IconSend2, IconTrash } from "@tabler/icons-react"; -import { default as TipTapImage } from "@tiptap/extension-image"; -import { useEditor } from "@tiptap/react"; -import StarterKit from "@tiptap/starter-kit"; +import { IconEye, IconEyeOff, IconSend2, IconTrash } from "@tabler/icons-react"; -import "@mantine/tiptap/styles.css"; -import EmojiPickerControl from "../EmojiPicker/EmojiPickerControl"; import FileUploadControl from "../FileUploadControl"; -import "./TextEditor.css"; import styles from "./TextEditor.module.css"; import { sendMessage } from "#/libs/actions"; +const Markdown = dynamic(() => import("#/components/Markdown"), { ssr: false }); + type TextEditorProps = { user_id: string; channel_id: string; @@ -26,16 +22,9 @@ type TextEditorProps = { const TextEditor: React.FC = ({ user_id, channel_id }) => { const [value, setValue] = useState(""); - const editor = useEditor({ - extensions: [StarterKit, Link, TipTapImage], - content: value, - onUpdate: ({ editor }) => { - setValue(editor.getHTML()); - }, - immediatelyRender: false, - }); const [isPending, startTransition] = useTransition(); const [assets, setAssets] = useState[]>([]); + const [showPreview, setShowPreview] = useState(false); const handleClick = () => { startTransition(async () => { @@ -46,15 +35,14 @@ const TextEditor: React.FC = ({ user_id, channel_id }) => { content: value, assets, }); - editor?.commands.clearContent(); setAssets([]); setValue(""); + setShowPreview(false); }); }; const handleUpload = (file: File[]) => { startTransition(async () => { - // TODO: 複数ファイルのアップロードをサポートする const formData = new FormData(); formData.append("file", file[0]); const res = await fetch("/api/file", { @@ -69,26 +57,79 @@ const TextEditor: React.FC = ({ user_id, channel_id }) => { }; return ( - - - - - - - - - - - - - - - - + + +
+