diff --git a/gateway/platforms/matrix.py b/gateway/platforms/matrix.py index 816d88b034..4aebd92b15 100644 --- a/gateway/platforms/matrix.py +++ b/gateway/platforms/matrix.py @@ -729,6 +729,14 @@ class MatrixAdapter(BasePlatformAdapter): except Exception: pass + async def stop_typing(self, chat_id: str) -> None: + """Stop the Matrix typing indicator.""" + if self._client: + try: + await self._client.set_typing(RoomID(chat_id), timeout=0) + except Exception: + pass + async def edit_message( self, chat_id: str, message_id: str, content: str ) -> SendResult: diff --git a/tests/gateway/test_matrix.py b/tests/gateway/test_matrix.py index 5097ab6330..90d8200469 100644 --- a/tests/gateway/test_matrix.py +++ b/tests/gateway/test_matrix.py @@ -335,6 +335,29 @@ def _make_adapter(): return adapter +# --------------------------------------------------------------------------- +# Typing indicator +# --------------------------------------------------------------------------- + +class TestMatrixTypingIndicator: + def setup_method(self): + self.adapter = _make_adapter() + self.adapter._client = MagicMock() + self.adapter._client.set_typing = AsyncMock() + + @pytest.mark.asyncio + async def test_stop_typing_clears_matrix_typing_state(self): + """stop_typing() should send typing=false instead of waiting for timeout expiry.""" + from gateway.platforms.matrix import RoomID + + await self.adapter.stop_typing("!room:example.org") + + self.adapter._client.set_typing.assert_awaited_once_with( + RoomID("!room:example.org"), + timeout=0, + ) + + # --------------------------------------------------------------------------- # mxc:// URL conversion # --------------------------------------------------------------------------- @@ -1831,4 +1854,3 @@ class TestMatrixPresence: assert result is False -