diff --git a/src/python/matrix_client.py b/src/python/matrix_client.py index 60728025..aeba2e17 100644 --- a/src/python/matrix_client.py +++ b/src/python/matrix_client.py @@ -4,6 +4,7 @@ import html import io import logging as log import platform +import re import traceback from contextlib import suppress from dataclasses import dataclass @@ -13,6 +14,7 @@ from pathlib import Path from typing import ( Any, BinaryIO, DefaultDict, Dict, Optional, Set, Tuple, Type, Union, ) +from urllib.parse import urlparse from uuid import uuid4 import cairosvg @@ -450,6 +452,25 @@ class MatrixClient(nio.AsyncClient): return response.room_id + async def room_join(self, alias_or_id_or_url: str) -> str: + string = alias_or_id_or_url.strip() + + if re.match(r"^https?://", string): + for part in urlparse(string).fragment.split("/"): + if re.match(r"[#!].+:.+", part): + string = part + break + else: + raise ValueError(f"No alias or room id found in url {string}") + + response = await super().join(string) + + if isinstance(response, nio.JoinError): + raise RequestFailed(response.status_code) + + return response.room_id + + async def room_forget(self, room_id: str) -> None: await super().room_leave(room_id) diff --git a/src/qml/Pages/AddChat/AddChat.qml b/src/qml/Pages/AddChat/AddChat.qml index ca636ced..a6482526 100644 --- a/src/qml/Pages/AddChat/AddChat.qml +++ b/src/qml/Pages/AddChat/AddChat.qml @@ -48,7 +48,8 @@ HPage { Layout.fillWidth: true Item {} - Item {} + + JoinRoom {} CreateRoom { id: createRoom diff --git a/src/qml/Pages/AddChat/JoinRoom.qml b/src/qml/Pages/AddChat/JoinRoom.qml new file mode 100644 index 00000000..ca3e936f --- /dev/null +++ b/src/qml/Pages/AddChat/JoinRoom.qml @@ -0,0 +1,58 @@ +import QtQuick 2.12 +import QtQuick.Layouts 1.12 +import "../../Base" +import "../../utils.js" as Utils + +HBox { + id: addChatBox + clickButtonOnEnter: "join" + + onFocusChanged: roomField.forceActiveFocus() + + buttonModel: [ + { name: "apply", text: qsTr("Join"), iconName: "apply" }, + { name: "cancel", text: qsTr("Cancel"), iconName: "cancel" }, + ] + + buttonCallbacks: ({ + apply: button => { + button.loading = true + + let args = [roomField.text] + + py.callClientCoro(userId, "room_join", args, roomId => { + button.loading = false + pageLoader.showRoom(userId, roomId) + }) + }, + + cancel: button => { + roomField.text = "" + pageLoader.showPrevious() + } + }) + + + readonly property string userId: addChatPage.userId + + + HTextField { + id: roomField + placeholderText: qsTr("Alias (e.g. #example:matrix.org), URL or ID") + + Layout.fillWidth: true + } + + HLabel { + id: errorMessage + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter + color: theme.colors.errorText + + visible: Layout.maximumHeight > 0 + Layout.maximumHeight: text ? implicitHeight : 0 + Behavior on Layout.maximumHeight { HNumberAnimation {} } + + Layout.fillWidth: true + } +}