File indexing completed on 2024-12-08 07:33:44

0001 // SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
0002 // SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org>
0003 // SPDX-License-Identifier: GPL-2.0-or-later
0004 
0005 #pragma once
0006 
0007 #include "neochatroom.h"
0008 
0009 #include <QAbstractListModel>
0010 #include <QPointer>
0011 #include <QQmlEngine>
0012 #include <QRectF>
0013 
0014 struct LiveLocationData {
0015     QString eventId;
0016     QString senderId;
0017     QJsonObject beaconInfo;
0018     QJsonObject beacon;
0019 };
0020 bool operator<(const LiveLocationData &lhs, const LiveLocationData &rhs);
0021 
0022 /** Accumulates live location beacon events in a given room
0023  *  and provides the last known state for one or more live location beacons.
0024  */
0025 class LiveLocationsModel : public QAbstractListModel
0026 {
0027     Q_OBJECT
0028     QML_ELEMENT
0029 
0030     Q_PROPERTY(NeoChatRoom *room MEMBER m_room NOTIFY roomChanged)
0031     /** The event id of the beacon start event, ie. the one all suspequent
0032      *  events use to relate to the same beacon.
0033      *  If this is set only this specific beacon will be coverd by this model,
0034      *  if it is empty, all beacons in the room will be covered.
0035      */
0036     Q_PROPERTY(QString eventId MEMBER m_eventId NOTIFY eventIdChanged)
0037 
0038     /** Bounding box of all live location beacons covered by this model. */
0039     Q_PROPERTY(QRectF boundingBox READ boundingBox NOTIFY boundingBoxChanged)
0040 
0041 public:
0042     explicit LiveLocationsModel(QObject *parent = nullptr);
0043 
0044     enum Roles {
0045         LatitudeRole, /**< Latest latitude of a live locaction beacon. */
0046         LongitudeRole, /**< Latest longitude of a live locaction beacon. */
0047         AssetRole, /**< Type of location event, e.g. self pin of the user location. */
0048         AuthorRole, /**< The author of the event. */
0049         IsLiveRole, /**< Boolean that indicates whether a live location beacon is still live. */
0050         HeadingRole, /**< Heading in degree (not part of any MSC yet, using an Itinerary extension). */
0051     };
0052     Q_ENUM(Roles)
0053 
0054     int rowCount(const QModelIndex &parent = {}) const override;
0055     QVariant data(const QModelIndex &index, int roleName) const override;
0056     QHash<int, QByteArray> roleNames() const override;
0057 
0058     QRectF boundingBox() const;
0059 
0060 Q_SIGNALS:
0061     void roomChanged();
0062     void eventIdChanged();
0063     void boundingBoxChanged();
0064 
0065 private:
0066     void addEvent(const Quotient::RoomEvent *event);
0067     void updateLocationData(LiveLocationData &&data);
0068 
0069     QPointer<NeoChatRoom> m_room;
0070     QString m_eventId;
0071 
0072     QList<LiveLocationData> m_locations;
0073 };