1
0
Fork 0
forked from Mirrors/gomuks

web/composer: send typing notifications

This commit is contained in:
Tulir Asokan 2024-10-15 00:40:06 +03:00
parent c16a2c2c80
commit 3c596a200f
4 changed files with 27 additions and 5 deletions

2
go.mod
View file

@ -13,7 +13,7 @@ require (
golang.org/x/crypto v0.27.0
gopkg.in/yaml.v3 v3.0.1
maunium.net/go/mauflag v1.0.0
maunium.net/go/mautrix v0.21.1-0.20241014142315-efc532bfb2ce
maunium.net/go/mautrix v0.21.1-0.20241014212413-e2c698098862
)
require (

4
go.sum
View file

@ -66,5 +66,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
maunium.net/go/mautrix v0.21.1-0.20241014142315-efc532bfb2ce h1:7fgaFJvpsy11S8KcZhbcwhg4kPzFid9aRNgqJjNpOHE=
maunium.net/go/mautrix v0.21.1-0.20241014142315-efc532bfb2ce/go.mod h1:yIs8uVcl3ZiTuDzAYmk/B4/z9dQqegF0rcOWV4ncgko=
maunium.net/go/mautrix v0.21.1-0.20241014212413-e2c698098862 h1:L+UmRjYbb7Y1R/iOpVCFksH9oGI59o8qI07S3hy+hq4=
maunium.net/go/mautrix v0.21.1-0.20241014212413-e2c698098862/go.mod h1:yIs8uVcl3ZiTuDzAYmk/B4/z9dQqegF0rcOWV4ncgko=

View file

@ -131,6 +131,10 @@ export default abstract class RPCClient {
return this.request("mark_read", { room_id, event_id, receipt_type })
}
setTyping(room_id: RoomID, timeout: number): Promise<boolean> {
return this.request("set_typing", { room_id, timeout })
}
ensureGroupSessionShared(room_id: RoomID): Promise<boolean> {
return this.request("ensure_group_session_shared", { room_id })
}

View file

@ -37,6 +37,7 @@ const MessageComposer = ({ room, replyTo, setTextRows, closeReply }: MessageComp
const client = use(ClientContext)!
const [text, setText] = useState("")
const textRows = useRef(1)
const typingSentAt = useRef(0)
const fullSetText = useCallback((text: string, setDraft: boolean) => {
setText(text)
textRows.current = text === "" ? 1 : text.split("\n").length
@ -74,12 +75,29 @@ const MessageComposer = ({ room, replyTo, setTextRows, closeReply }: MessageComp
}, [sendMessage])
const onChange = useCallback((evt: React.ChangeEvent<HTMLTextAreaElement>) => {
fullSetText(evt.target.value, true)
}, [fullSetText])
const now = Date.now()
if (evt.target.value !== "" && typingSentAt.current + 5_000 < now) {
typingSentAt.current = now
client.rpc.setTyping(room.roomID, 10_000)
.catch(err => console.error("Failed to send typing notification:", err))
} else if (evt.target.value == "" && typingSentAt.current > 0) {
typingSentAt.current = 0
client.rpc.setTyping(room.roomID, 0)
.catch(err => console.error("Failed to send stop typing notification:", err))
}
}, [client, room.roomID, fullSetText])
// 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(() => {
fullSetText(draftStore.get(room.roomID), false)
}, [room.roomID, fullSetText])
return () => {
if (typingSentAt.current > 0) {
typingSentAt.current = 0
client.rpc.setTyping(room.roomID, 0)
.catch(err => console.error("Failed to send stop typing notification due to room switch:", err))
}
}
}, [client, room.roomID, fullSetText])
return <div className="message-composer">
{replyTo && <ReplyBody room={room} event={replyTo} onClose={closeReply}/>}
<div className="input-area">