From 00c0d1c276791ff992d6360d6ff6b5cf3552a0c8 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Fri, 28 Jul 2023 10:34:55 +0200 Subject: [PATCH] Add heading indicator for live locations Heading isn't covered by any MSC so far, so that is using Itinerary's vendor prefix for now. --- src/models/livelocationsmodel.cpp | 8 ++++++++ src/models/livelocationsmodel.h | 1 + src/qml/Component/FullScreenMap.qml | 1 + src/qml/Component/LocationMapItem.qml | 17 +++++++++++++++++ src/qml/Component/LocationPage.qml | 1 + src/qml/Component/Timeline/LocationDelegate.qml | 1 + 6 files changed, 29 insertions(+) diff --git a/src/models/livelocationsmodel.cpp b/src/models/livelocationsmodel.cpp index 1dcf5f309..636696776 100644 --- a/src/models/livelocationsmodel.cpp +++ b/src/models/livelocationsmodel.cpp @@ -8,6 +8,8 @@ #include +#include + using namespace Quotient; bool operator<(const LiveLocationData &lhs, const LiveLocationData &rhs) @@ -88,6 +90,11 @@ QVariant LiveLocationsModel::data(const QModelIndex &index, int roleName) const const auto timeout = data.beaconInfo.value("timeout"_ls).toDouble(600000); return lastTs + timeout >= QDateTime::currentDateTime().toMSecsSinceEpoch(); } + case HeadingRole: { + bool success = false; + const auto heading = data.beacon["org.matrix.msc3488.location"_ls].toObject()["org.kde.itinerary.heading"_ls].toString().toDouble(&success); + return success ? heading : NAN; + } } return {}; @@ -101,6 +108,7 @@ QHash LiveLocationsModel::roleNames() const r.insert(AssetRole, "asset"); r.insert(AuthorRole, "author"); r.insert(IsLiveRole, "isLive"); + r.insert(HeadingRole, "heading"); return r; } diff --git a/src/models/livelocationsmodel.h b/src/models/livelocationsmodel.h index 9f95d1b1c..3e1d7b09f 100644 --- a/src/models/livelocationsmodel.h +++ b/src/models/livelocationsmodel.h @@ -49,6 +49,7 @@ public: AssetRole, /**< Type of location event, e.g. self pin of the user location. */ AuthorRole, /**< The author of the event. */ IsLiveRole, /**< Boolean that indicates whether a live location beacon is still live. */ + HeadingRole, /**< Heading in degree (not part of any MSC yet, using an Itinerary extension). */ }; Q_ENUM(Roles) diff --git a/src/qml/Component/FullScreenMap.qml b/src/qml/Component/FullScreenMap.qml index a9ec96812..79bfc7a3b 100644 --- a/src/qml/Component/FullScreenMap.qml +++ b/src/qml/Component/FullScreenMap.qml @@ -46,6 +46,7 @@ ApplicationWindow { asset: root.asset author: root.author isLive: true + heading: NaN visible: !isNaN(root.latitude) && !isNaN(root.longitude) } MapItemView { diff --git a/src/qml/Component/LocationMapItem.qml b/src/qml/Component/LocationMapItem.qml index f069e34ee..3ba68521a 100644 --- a/src/qml/Component/LocationMapItem.qml +++ b/src/qml/Component/LocationMapItem.qml @@ -24,11 +24,14 @@ MapQuickItem { required property bool isLive + required property real heading + anchorPoint.x: sourceItem.width / 2 anchorPoint.y: sourceItem.height coordinate: QtPositioning.coordinate(root.latitude, root.longitude) autoFadeIn: false sourceItem: Kirigami.Icon { + id: mainIcon width: height height: Kirigami.Units.iconSizes.huge source: "gps" @@ -55,5 +58,19 @@ MapQuickItem { source: root.author.avatarSource color: root.author.color } + + Kirigami.Icon { + id: headingIcon + source: "go-up-symbolic" + color: parent.color + visible: !isNaN(root.heading) && root.isLive + anchors.bottom: mainIcon.top + anchors.horizontalCenter: mainIcon.horizontalCenter + transform: Rotation { + origin.x: headingIcon.width/2 + origin.y: headingIcon.height + mainIcon.height/2 + angle: root.heading + } + } } } diff --git a/src/qml/Component/LocationPage.qml b/src/qml/Component/LocationPage.qml index e3246bcf5..bc6b40c09 100644 --- a/src/qml/Component/LocationPage.qml +++ b/src/qml/Component/LocationPage.qml @@ -36,6 +36,7 @@ Kirigami.Page { } delegate: LocationMapItem { isLive: true + heading: NaN } } diff --git a/src/qml/Component/Timeline/LocationDelegate.qml b/src/qml/Component/Timeline/LocationDelegate.qml index 9939625cc..6b8e56f9f 100644 --- a/src/qml/Component/Timeline/LocationDelegate.qml +++ b/src/qml/Component/Timeline/LocationDelegate.qml @@ -57,6 +57,7 @@ TimelineContainer { asset: root.asset author: root.author isLive: true + heading: NaN } TapHandler {