diff --git a/src/neochatroom.cpp b/src/neochatroom.cpp index 461810f22..62476aeae 100644 --- a/src/neochatroom.cpp +++ b/src/neochatroom.cpp @@ -1884,3 +1884,27 @@ NeoChatUser *NeoChatRoom::directChatRemoteUser() const { return dynamic_cast(connection()->directChatUsers(this)[0]); } + +void NeoChatRoom::sendLocation(float lat, float lon, const QString &description) +{ + QJsonObject locationContent{ + {"uri", "geo:%1,%2"_ls.arg(QString::number(lat), QString::number(lon))}, + }; + + if (!description.isEmpty()) { + locationContent["description"] = description; + } + + QJsonObject content{ + {"body", i18nc("'Lat' and 'Lon' as in Latitude and Longitude", "Lat: %1, Lon: %2", lat, lon)}, + {"msgtype", "m.location"}, + {"geo_uri", "geo:%1,%2"_ls.arg(QString::number(lat), QString::number(lon))}, + {"org.matrix.msc3488.location", locationContent}, + {"org.matrix.msc3488.asset", + QJsonObject{ + {"type", "m.pin"}, + }}, + {"org.matrix.msc1767.text", i18nc("'Lat' and 'Lon' as in Latitude and Longitude", "Lat: %1, Lon: %2", lat, lon)}, + }; + postJson("m.room.message", content); +} diff --git a/src/neochatroom.h b/src/neochatroom.h index 2621af037..9c048b48a 100644 --- a/src/neochatroom.h +++ b/src/neochatroom.h @@ -901,4 +901,13 @@ public Q_SLOTS: * This will delete all messages by that user in this room that are currently loaded. */ void deleteMessagesByUser(const QString &user, const QString &reason); + + /** + * @brief Sends a location to a room + * The event is sent in the migration format as specified in MSC3488 + * @param lat latitude + * @param lon longitude + * @param description description for the location + */ + void sendLocation(float lat, float lon, const QString &description); }; diff --git a/src/qml/Component/ChatBox/ChatBar.qml b/src/qml/Component/ChatBox/ChatBar.qml index 1cdfef473..303ff3c87 100644 --- a/src/qml/Component/ChatBox/ChatBar.qml +++ b/src/qml/Component/ChatBox/ChatBar.qml @@ -65,8 +65,17 @@ QQC2.Control { emojiDialog.open() } } + }, + Kirigami.Action { + id: mapButton + icon.name: "globe" + property bool isBusy: false + text: i18n("Send a Location") + displayHint: QQC2.AbstractButton.IconOnly - tooltip: text + onTriggered: { + locationChooserComponent.createObject(QQC2.ApplicationWindow.overlay, {room: currentRoom}).open() + } }, Kirigami.Action { id: sendAction @@ -473,4 +482,9 @@ QQC2.Control { textField.cursorPosition = index + format.start.length + format.end.length; } } + + Component { + id: locationChooserComponent + LocationChooser {} + } } diff --git a/src/qml/Component/ChatBox/LocationChooser.qml b/src/qml/Component/ChatBox/LocationChooser.qml new file mode 100644 index 000000000..276b357b0 --- /dev/null +++ b/src/qml/Component/ChatBox/LocationChooser.qml @@ -0,0 +1,83 @@ +// SPDX-FileCopyrightText: 2021 Tobias Fella +// SPDX-License-Identifier: GPL-2.0-or-later + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import QtLocation 5.15 +import QtPositioning 5.15 + +import org.kde.kirigamiaddons.labs.components 1.0 as Components + +import org.kde.kirigami 2.15 as Kirigami + +Components.AbstractMaximizeComponent { + id: root + + required property var room + property var location + + title: i18n("Choose a Location") + + actions: [ + Kirigami.Action { + icon.name: "document-send" + text: i18n("Send this location") + onTriggered: { + root.room.sendLocation(root.location.latitude, root.location.longitude, ""); + root.close(); + } + enabled: !!root.location + } + ] + + content: Map { + id: map + plugin: Plugin { + name: "osm" + PluginParameter { + name: "osm.useragent" + value: Application.name + "/" + Application.version + " (kde-devel@kde.org)" + } + PluginParameter { + name: "osm.mapping.providersrepository.address" + value: "https://autoconfig.kde.org/qtlocation/" + } + } + + MouseArea { + anchors.fill: parent + onClicked: { + root.location = map.toCoordinate(Qt.point(mouseX, mouseY), false) + } + } + + MapQuickItem { + id: point + + visible: root.location + anchorPoint.x: sourceItem.width / 2 + anchorPoint.y: sourceItem.height * 0.85 + coordinate: root.location + autoFadeIn: false + + sourceItem: Kirigami.Icon { + width: height + height: Kirigami.Units.iconSizes.huge + source: "gps" + isMask: true + color: Kirigami.Theme.highlightColor + + Kirigami.Icon { + anchors.centerIn: parent + anchors.verticalCenterOffset: -parent.height / 8 + width: height + height: parent.height / 3 + 1 + source: "pin" + isMask: true + color: Kirigami.Theme.highlightColor + } + } + } + } +} diff --git a/src/res.qrc b/src/res.qrc index 4cc2b8f78..53dc4f2eb 100644 --- a/src/res.qrc +++ b/src/res.qrc @@ -108,5 +108,6 @@ qml/Component/Emoji/EmojiGrid.qml qml/Page/SearchPage.qml qml/Component/Timeline/LocationDelegate.qml + qml/Component/ChatBox/LocationChooser.qml