mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-20 10:33:41 -05:00
web/composer: fix selecting autocomplete item when not at end of composer
This commit is contained in:
parent
573fc6a052
commit
a59d10ae0c
2 changed files with 14 additions and 4 deletions
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import { JSX, use, useEffect } from "react"
|
import { JSX, RefObject, use, useEffect } from "react"
|
||||||
import { getAvatarURL, getMediaURL } from "@/api/media.ts"
|
import { getAvatarURL, getMediaURL } from "@/api/media.ts"
|
||||||
import { RoomStateStore, useCustomEmojis } from "@/api/statestore"
|
import { RoomStateStore, useCustomEmojis } from "@/api/statestore"
|
||||||
import { Emoji, emojiToMarkdown, useSortedAndFilteredEmojis } from "@/util/emoji"
|
import { Emoji, emojiToMarkdown, useSortedAndFilteredEmojis } from "@/util/emoji"
|
||||||
|
@ -37,6 +37,7 @@ export interface AutocompleteQuery {
|
||||||
export interface AutocompleterProps {
|
export interface AutocompleterProps {
|
||||||
setState: (state: Partial<ComposerState>) => void
|
setState: (state: Partial<ComposerState>) => void
|
||||||
setAutocomplete: (params: AutocompleteQuery | null) => void
|
setAutocomplete: (params: AutocompleteQuery | null) => void
|
||||||
|
textInput: RefObject<HTMLTextAreaElement | null>
|
||||||
state: ComposerState
|
state: ComposerState
|
||||||
params: AutocompleteQuery
|
params: AutocompleteQuery
|
||||||
room: RoomStateStore
|
room: RoomStateStore
|
||||||
|
@ -52,7 +53,7 @@ interface InnerAutocompleterProps<T> extends AutocompleterProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function useAutocompleter<T>({
|
function useAutocompleter<T>({
|
||||||
params, state, setState, setAutocomplete,
|
params, state, setState, setAutocomplete, textInput,
|
||||||
items, getText, getKey, render,
|
items, getText, getKey, render,
|
||||||
}: InnerAutocompleterProps<T>) {
|
}: InnerAutocompleterProps<T>) {
|
||||||
const onSelect = useEvent((index: number) => {
|
const onSelect = useEvent((index: number) => {
|
||||||
|
@ -61,12 +62,20 @@ function useAutocompleter<T>({
|
||||||
}
|
}
|
||||||
index = positiveMod(index, items.length)
|
index = positiveMod(index, items.length)
|
||||||
const replacementText = getText(items[index])
|
const replacementText = getText(items[index])
|
||||||
|
const newText = state.text.slice(0, params.startPos) + replacementText + state.text.slice(params.endPos)
|
||||||
|
const endPos = params.startPos + replacementText.length
|
||||||
|
if (textInput.current) {
|
||||||
|
// React messes up the selection when changing the value for some reason,
|
||||||
|
// so bypass react here to avoid the caret jumping to the end and closing the autocompleter
|
||||||
|
textInput.current.value = newText
|
||||||
|
textInput.current.setSelectionRange(endPos, endPos)
|
||||||
|
}
|
||||||
setState({
|
setState({
|
||||||
text: state.text.slice(0, params.startPos) + replacementText + state.text.slice(params.endPos),
|
text: newText,
|
||||||
})
|
})
|
||||||
setAutocomplete({
|
setAutocomplete({
|
||||||
...params,
|
...params,
|
||||||
endPos: params.startPos + replacementText.length,
|
endPos,
|
||||||
frozenQuery: params.frozenQuery ?? params.query,
|
frozenQuery: params.frozenQuery ?? params.query,
|
||||||
})
|
})
|
||||||
document.querySelector(`div.autocompletion-item[data-index='${index}']`)?.scrollIntoView({ block: "nearest" })
|
document.querySelector(`div.autocompletion-item[data-index='${index}']`)?.scrollIntoView({ block: "nearest" })
|
||||||
|
|
|
@ -393,6 +393,7 @@ const MessageComposer = () => {
|
||||||
state={state}
|
state={state}
|
||||||
setState={setState}
|
setState={setState}
|
||||||
setAutocomplete={setAutocomplete}
|
setAutocomplete={setAutocomplete}
|
||||||
|
textInput={textInput}
|
||||||
/></div>}
|
/></div>}
|
||||||
<div className="message-composer" ref={composerRef}>
|
<div className="message-composer" ref={composerRef}>
|
||||||
{replyToEvt && <ReplyBody
|
{replyToEvt && <ReplyBody
|
||||||
|
|
Loading…
Add table
Reference in a new issue