File indexing completed on 2024-04-21 04:59:30

0001 // SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org>
0002 // SPDX-License-Identifier: LGPL-2.0-or-later
0003 
0004 #pragma once
0005 
0006 #include <QJsonArray>
0007 #include <QJsonObject>
0008 #include <QObject>
0009 #include <QPair>
0010 #include <QQmlEngine>
0011 
0012 #include <Quotient/events/roomevent.h>
0013 
0014 #include "events/pollevent.h"
0015 
0016 class NeoChatRoom;
0017 
0018 /**
0019  * @class PollHandler
0020  *
0021  * A class to help manage a poll in a room.
0022  *
0023  * A poll is made up of a start event that poses the question and possible answers,
0024  * and is followed by a series of response events as users in the room select
0025  * their choice. This purpose of the poll handler is to keep track of all this as
0026  * the poll is displayed as a single event in the timeline which merges all this
0027  * information.
0028  */
0029 class PollHandler : public QObject
0030 {
0031     Q_OBJECT
0032     QML_ELEMENT
0033 
0034     /**
0035      * @brief The question for the poll.
0036      */
0037     Q_PROPERTY(QString question READ question NOTIFY questionChanged)
0038 
0039     /**
0040      * @brief The list of possible answers to the poll.
0041      */
0042     Q_PROPERTY(QJsonArray options READ options NOTIFY optionsChanged)
0043 
0044     /**
0045      * @brief The list of answer responses to the poll from users in the room.
0046      */
0047     Q_PROPERTY(QJsonObject answers READ answers NOTIFY answersChanged)
0048 
0049     /**
0050      * @brief The list number of votes for each answer in the poll.
0051      */
0052     Q_PROPERTY(QJsonObject counts READ counts NOTIFY answersChanged)
0053 
0054     /**
0055      * @brief Whether the poll has ended.
0056      */
0057     Q_PROPERTY(bool hasEnded READ hasEnded NOTIFY hasEndedChanged)
0058 
0059     /**
0060      * @brief The total number of answers to the poll.
0061      */
0062     Q_PROPERTY(int answerCount READ answerCount NOTIFY answersChanged)
0063 
0064     /**
0065      * @brief The kind of the poll.
0066      */
0067     Q_PROPERTY(QString kind READ kind CONSTANT)
0068 
0069 public:
0070     PollHandler() = default;
0071     PollHandler(NeoChatRoom *room, const Quotient::PollStartEvent *pollStartEvent);
0072 
0073     bool hasEnded() const;
0074     int answerCount() const;
0075 
0076     QString question() const;
0077     QJsonArray options() const;
0078     QJsonObject answers() const;
0079     QJsonObject counts() const;
0080     QString kind() const;
0081 
0082     /**
0083      * @brief Send an answer to the poll.
0084      */
0085     Q_INVOKABLE void sendPollAnswer(const QString &eventId, const QString &answerId);
0086 
0087 Q_SIGNALS:
0088     void questionChanged();
0089     void optionsChanged();
0090     void answersChanged();
0091     void hasEndedChanged();
0092 
0093 private:
0094     const Quotient::PollStartEvent *m_pollStartEvent;
0095 
0096     void updatePoll(Quotient::RoomEventsRange events);
0097 
0098     void checkLoadRelations();
0099     void handleAnswer(const QJsonObject &object, const QString &sender, QDateTime timestamp);
0100     QMap<QString, QDateTime> m_answerTimestamps;
0101     QJsonObject m_answers;
0102     int m_maxVotes = 1;
0103     bool m_hasEnded = false;
0104     QDateTime m_endedTimestamp;
0105 };