Handle matrix scheme

Link opening only works on Linux for now.

See https://github.com/matrix-org/matrix-doc/pull/2312
This commit is contained in:
Nicolas Werner 2021-01-10 18:36:06 +01:00
parent cc9de7f3b0
commit 39f9b7d90a
7 changed files with 216 additions and 17 deletions

View file

@ -918,6 +918,8 @@ ChatPage::joinRoom(const QString &room)
} catch (const lmdb::error &e) {
emit showNotification(tr("Failed to remove invite: %1").arg(e.what()));
}
room_list_->highlightSelectedRoom(QString::fromStdString(room_id));
});
}
@ -1268,3 +1270,141 @@ ChatPage::decryptDownloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescriptio
cache::storeSecret(secretName, decrypted);
}
}
void
ChatPage::startChat(QString userid)
{
auto joined_rooms = cache::joinedRooms();
auto room_infos = cache::getRoomInfo(joined_rooms);
for (std::string room_id : joined_rooms) {
if (room_infos[QString::fromStdString(room_id)].member_count == 2) {
auto room_members = cache::roomMembers(room_id);
if (std::find(room_members.begin(),
room_members.end(),
(userid).toStdString()) != room_members.end()) {
room_list_->highlightSelectedRoom(QString::fromStdString(room_id));
return;
}
}
}
mtx::requests::CreateRoom req;
req.preset = mtx::requests::Preset::PrivateChat;
req.visibility = mtx::requests::Visibility::Private;
if (utils::localUser() != userid)
req.invite = {userid.toStdString()};
emit ChatPage::instance()->createRoom(req);
}
static QString
mxidFromSegments(QStringRef sigil, QStringRef mxid)
{
if (mxid.isEmpty())
return "";
auto mxid_ = QUrl::fromPercentEncoding(mxid.toUtf8());
if (sigil == "user") {
return "@" + mxid_;
} else if (sigil == "roomid") {
return "!" + mxid_;
} else if (sigil == "room") {
return "#" + mxid_;
} else if (sigil == "group") {
return "+" + mxid_;
} else {
return "";
}
}
void
ChatPage::handleMatrixUri(const QByteArray &uri)
{
nhlog::ui()->info("Received uri! {}", uri.toStdString());
QUrl uri_{QString::fromUtf8(uri)};
if (uri_.scheme() != "matrix")
return;
auto tempPath = uri_.path(QUrl::ComponentFormattingOption::FullyEncoded);
if (tempPath.startsWith('/'))
tempPath.remove(0, 1);
auto segments = tempPath.splitRef('/');
if (segments.size() != 2 && segments.size() != 4)
return;
auto sigil1 = segments[0];
auto mxid1 = mxidFromSegments(sigil1, segments[1]);
if (mxid1.isEmpty())
return;
QString mxid2;
if (segments.size() == 4 && segments[2] == "event") {
if (segments[3].isEmpty())
return;
else
mxid2 = "$" + QUrl::fromPercentEncoding(segments[3].toUtf8());
}
std::vector<std::string> vias;
QString action;
for (QString item : uri_.query(QUrl::ComponentFormattingOption::FullyEncoded).split('&')) {
nhlog::ui()->info("item: {}", item.toStdString());
if (item.startsWith("action=")) {
action = item.remove("action=");
} else if (item.startsWith("via=")) {
vias.push_back(
QUrl::fromPercentEncoding(item.remove("via=").toUtf8()).toStdString());
}
}
if (sigil1 == "user") {
if (action.isEmpty()) {
view_manager_->activeTimeline()->openUserProfile(mxid1);
} else if (action == "chat") {
this->startChat(mxid1);
}
} else if (sigil1 == "roomid") {
auto joined_rooms = cache::joinedRooms();
auto targetRoomId = mxid1.toStdString();
for (auto roomid : joined_rooms) {
if (roomid == targetRoomId) {
room_list_->highlightSelectedRoom(mxid1);
break;
}
}
if (action == "join") {
joinRoom(mxid1);
}
} else if (sigil1 == "room") {
auto joined_rooms = cache::joinedRooms();
auto targetRoomAlias = mxid1.toStdString();
for (auto roomid : joined_rooms) {
auto aliases = cache::client()->getRoomAliases(roomid);
if (aliases) {
if (aliases->alias == targetRoomAlias) {
room_list_->highlightSelectedRoom(
QString::fromStdString(roomid));
break;
}
}
}
if (action == "join") {
joinRoom(mxid1);
}
}
}
void
ChatPage::handleMatrixUri(const QUrl &uri)
{
handleMatrixUri(uri.toString(QUrl::ComponentFormattingOption::FullyEncoded).toUtf8());
}