Show a map for location events
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,3 +10,4 @@ kate.project.ctags.*
|
|||||||
*.user
|
*.user
|
||||||
.flatpak-builder/
|
.flatpak-builder/
|
||||||
.idea/
|
.idea/
|
||||||
|
cmake-build-debug
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
|
|||||||
roles[IsRedactedRole] = "isRedacted";
|
roles[IsRedactedRole] = "isRedacted";
|
||||||
roles[GenericDisplayRole] = "genericDisplay";
|
roles[GenericDisplayRole] = "genericDisplay";
|
||||||
roles[IsPendingRole] = "isPending";
|
roles[IsPendingRole] = "isPending";
|
||||||
|
roles[LatitudeRole] = "latitude";
|
||||||
|
roles[LongitudeRole] = "longitude";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,6 +512,8 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
|||||||
return DelegateType::Audio;
|
return DelegateType::Audio;
|
||||||
case MessageEventType::Video:
|
case MessageEventType::Video:
|
||||||
return DelegateType::Video;
|
return DelegateType::Video;
|
||||||
|
case MessageEventType::Location:
|
||||||
|
return DelegateType::Location;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -564,6 +568,9 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (auto e = eventCast<const RoomMessageEvent>(&evt)) {
|
if (auto e = eventCast<const RoomMessageEvent>(&evt)) {
|
||||||
|
if(e->msgtype() == Quotient::MessageEventType::Location) {
|
||||||
|
return e->contentJson();
|
||||||
|
}
|
||||||
// Cannot use e.contentJson() here because some
|
// Cannot use e.contentJson() here because some
|
||||||
// EventContent classes inject values into the copy of the
|
// EventContent classes inject values into the copy of the
|
||||||
// content JSON stored in EventContent::Base
|
// content JSON stored in EventContent::Base
|
||||||
@@ -810,6 +817,24 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (role == LatitudeRole) {
|
||||||
|
const auto geoUri = evt.contentJson()["geo_uri"_ls].toString();
|
||||||
|
if (geoUri.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const auto latitude = geoUri.split(u':')[1].split(u',')[0];
|
||||||
|
return latitude.toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == LongitudeRole) {
|
||||||
|
const auto geoUri = evt.contentJson()["geo_uri"_ls].toString();
|
||||||
|
if (geoUri.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const auto latitude = geoUri.split(u':')[1].split(u',')[1];
|
||||||
|
return latitude.toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
if (role == ReadMarkersRole) {
|
if (role == ReadMarkersRole) {
|
||||||
#ifdef QUOTIENT_07
|
#ifdef QUOTIENT_07
|
||||||
auto userIds = room()->userIdsAtEvent(evt.id());
|
auto userIds = room()->userIdsAtEvent(evt.id());
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public:
|
|||||||
Encrypted,
|
Encrypted,
|
||||||
ReadMarker,
|
ReadMarker,
|
||||||
Poll,
|
Poll,
|
||||||
|
Location,
|
||||||
Other,
|
Other,
|
||||||
};
|
};
|
||||||
Q_ENUM(DelegateType);
|
Q_ENUM(DelegateType);
|
||||||
@@ -75,6 +76,8 @@ public:
|
|||||||
AuthorDisplayNameRole,
|
AuthorDisplayNameRole,
|
||||||
IsRedactedRole,
|
IsRedactedRole,
|
||||||
IsPendingRole,
|
IsPendingRole,
|
||||||
|
LatitudeRole,
|
||||||
|
LongitudeRole,
|
||||||
LastRole, // Keep this last
|
LastRole, // Keep this last
|
||||||
};
|
};
|
||||||
Q_ENUM(EventRoles)
|
Q_ENUM(EventRoles)
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ DelegateChooser {
|
|||||||
delegate: PollDelegate {}
|
delegate: PollDelegate {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DelegateChoice {
|
||||||
|
roleValue: MessageEventModel.Location
|
||||||
|
delegate: LocationDelegate {}
|
||||||
|
}
|
||||||
|
|
||||||
DelegateChoice {
|
DelegateChoice {
|
||||||
roleValue: MessageEventModel.Other
|
roleValue: MessageEventModel.Other
|
||||||
delegate: Item {}
|
delegate: Item {}
|
||||||
|
|||||||
67
src/qml/Component/Timeline/LocationDelegate.qml
Normal file
67
src/qml/Component/Timeline/LocationDelegate.qml
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2021 Tobias Fella <fella@posteo.de>
|
||||||
|
// 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.kirigami 2.15 as Kirigami
|
||||||
|
|
||||||
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
|
TimelineContainer {
|
||||||
|
id: locationDelegate
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.maximumWidth: locationDelegate.contentMaxWidth
|
||||||
|
Layout.preferredWidth: locationDelegate.contentMaxWidth
|
||||||
|
Map {
|
||||||
|
id: map
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: locationDelegate.contentMaxWidth / 16 * 9
|
||||||
|
|
||||||
|
center: QtPositioning.coordinate(model.latitude, model.longitude)
|
||||||
|
zoomLevel: 15
|
||||||
|
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/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onCopyrightLinkActivated: Qt.openUrlExternally(link)
|
||||||
|
|
||||||
|
|
||||||
|
MapQuickItem {
|
||||||
|
id: point
|
||||||
|
|
||||||
|
anchorPoint.x: sourceItem.width / 2
|
||||||
|
anchorPoint.y: sourceItem.height / 2
|
||||||
|
coordinate: QtPositioning.coordinate(model.latitude, model.longitude)
|
||||||
|
autoFadeIn: false
|
||||||
|
|
||||||
|
sourceItem: Kirigami.Icon {
|
||||||
|
width: height
|
||||||
|
height: Kirigami.Units.iconSizes.medium
|
||||||
|
source: "flag-blue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
onLongPressed: openMessageContext(model, "", model.message)
|
||||||
|
}
|
||||||
|
TapHandler {
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
onTapped: openMessageContext(model, "", model.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -107,5 +107,6 @@
|
|||||||
<file alias="EmojiDelegate.qml">qml/Component/Emoji/EmojiDelegate.qml</file>
|
<file alias="EmojiDelegate.qml">qml/Component/Emoji/EmojiDelegate.qml</file>
|
||||||
<file alias="EmojiGrid.qml">qml/Component/Emoji/EmojiGrid.qml</file>
|
<file alias="EmojiGrid.qml">qml/Component/Emoji/EmojiGrid.qml</file>
|
||||||
<file alias="SearchPage.qml">qml/Page/SearchPage.qml</file>
|
<file alias="SearchPage.qml">qml/Page/SearchPage.qml</file>
|
||||||
|
<file alias="LocationDelegate.qml">qml/Component/Timeline/LocationDelegate.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
Reference in New Issue
Block a user