mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-19 18:13:41 -05:00
web/composer: surround selection with markdown when pasting link
This commit is contained in:
parent
7c95ce35fd
commit
7e793ec0ba
3 changed files with 45 additions and 10 deletions
|
@ -17,6 +17,7 @@ import { JSX, use, useEffect } from "react"
|
|||
import { getAvatarURL, getMediaURL } from "@/api/media.ts"
|
||||
import { RoomStateStore, useCustomEmojis } from "@/api/statestore"
|
||||
import { Emoji, emojiToMarkdown, useSortedAndFilteredEmojis } from "@/util/emoji"
|
||||
import { escapeMarkdown } from "@/util/markdown.ts"
|
||||
import useEvent from "@/util/useEvent.ts"
|
||||
import ClientContext from "../ClientContext.ts"
|
||||
import type { ComposerState } from "./MessageComposer.tsx"
|
||||
|
@ -111,11 +112,7 @@ export const EmojiAutocompleter = ({ params, room, ...rest }: AutocompleterProps
|
|||
return useAutocompleter({ params, room, ...rest, items, ...emojiFuncs })
|
||||
}
|
||||
|
||||
const escapeDisplayname = (input: string) => input
|
||||
.replace("\n", " ")
|
||||
.replace(/([\\`*_[\]])/g, "\\$1")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
const escapeDisplayname = (input: string) => escapeMarkdown(input).replace("\n", " ")
|
||||
|
||||
const userFuncs = {
|
||||
getText: (user: AutocompleteUser) =>
|
||||
|
|
|
@ -26,6 +26,7 @@ import type {
|
|||
RoomID,
|
||||
} from "@/api/types"
|
||||
import { PartialEmoji, emojiToMarkdown } from "@/util/emoji"
|
||||
import { escapeMarkdown } from "@/util/markdown.ts"
|
||||
import useEvent from "@/util/useEvent.ts"
|
||||
import ClientContext from "../ClientContext.ts"
|
||||
import EmojiPicker from "../emojipicker/EmojiPicker.tsx"
|
||||
|
@ -266,11 +267,26 @@ const MessageComposer = () => {
|
|||
const onAttachFile = useEvent(
|
||||
(evt: React.ChangeEvent<HTMLInputElement>) => doUploadFile(evt.target.files?.[0]),
|
||||
)
|
||||
useEffect(() => {
|
||||
const listener = (evt: ClipboardEvent) => doUploadFile(evt.clipboardData?.files?.[0])
|
||||
document.addEventListener("paste", listener)
|
||||
return () => document.removeEventListener("paste", listener)
|
||||
}, [doUploadFile])
|
||||
const onPaste = useEvent((evt: React.ClipboardEvent<HTMLTextAreaElement>) => {
|
||||
const file = evt.clipboardData?.files?.[0]
|
||||
const text = evt.clipboardData.getData("text/plain")
|
||||
const input = evt.currentTarget
|
||||
if (file) {
|
||||
doUploadFile(file)
|
||||
} else if (
|
||||
input.selectionStart !== input.selectionEnd
|
||||
&& (text.startsWith("http://") || text.startsWith("https://") || text.startsWith("matrix:"))
|
||||
) {
|
||||
setState({
|
||||
text: `${state.text.slice(0, input.selectionStart)}[${
|
||||
escapeMarkdown(state.text.slice(input.selectionStart, input.selectionEnd))
|
||||
}](${escapeMarkdown(text)})${state.text.slice(input.selectionEnd)}`,
|
||||
})
|
||||
} else {
|
||||
return
|
||||
}
|
||||
evt.preventDefault()
|
||||
})
|
||||
// To ensure the cursor jumps to the end, do this in an effect rather than as the initial value of useState
|
||||
// To try to avoid the input bar flashing, use useLayoutEffect instead of useEffect
|
||||
useLayoutEffect(() => {
|
||||
|
@ -370,6 +386,7 @@ const MessageComposer = () => {
|
|||
onKeyDown={onComposerKeyDown}
|
||||
onKeyUp={onComposerCaretChange}
|
||||
onClick={onComposerCaretChange}
|
||||
onPaste={onPaste}
|
||||
onChange={onChange}
|
||||
placeholder="Send a message"
|
||||
id="message-composer"
|
||||
|
|
21
web/src/util/markdown.ts
Normal file
21
web/src/util/markdown.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
// gomuks - A Matrix client written in Go.
|
||||
// Copyright (C) 2024 Tulir Asokan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
export const escapeMarkdown = (input: string) => input
|
||||
.replace(/([\\`*_[\]])/g, "\\$1")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
Loading…
Add table
Reference in a new issue