143 lines
3.5 KiB
C++
143 lines
3.5 KiB
C++
// SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org>
|
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <QJsonArray>
|
|
#include <QJsonObject>
|
|
#include <QObject>
|
|
#include <QPair>
|
|
#include <QQmlEngine>
|
|
|
|
#include <Quotient/events/roomevent.h>
|
|
|
|
#include "events/pollevent.h"
|
|
#include "models/pollanswermodel.h"
|
|
|
|
namespace Quotient
|
|
{
|
|
class PollResponseEvent;
|
|
}
|
|
|
|
class NeoChatRoom;
|
|
|
|
/**
|
|
* @class PollHandler
|
|
*
|
|
* A class to help manage a poll in a room.
|
|
*
|
|
* A poll is made up of a start event that poses the question and possible answers,
|
|
* and is followed by a series of response events as users in the room select
|
|
* their choice. This purpose of the poll handler is to keep track of all this as
|
|
* the poll is displayed as a single event in the timeline which merges all this
|
|
* information.
|
|
*/
|
|
class PollHandler : public QObject
|
|
{
|
|
Q_OBJECT
|
|
QML_ELEMENT
|
|
QML_UNCREATABLE("Use NeoChatRoom::poll")
|
|
|
|
/**
|
|
* @brief The kind of the poll.
|
|
*/
|
|
Q_PROPERTY(PollKind::Kind kind READ kind CONSTANT)
|
|
|
|
/**
|
|
* @brief The question for the poll.
|
|
*/
|
|
Q_PROPERTY(QString question READ question NOTIFY questionChanged)
|
|
|
|
/**
|
|
* @brief Whether the poll has ended.
|
|
*/
|
|
Q_PROPERTY(bool hasEnded READ hasEnded NOTIFY hasEndedChanged)
|
|
|
|
/**
|
|
* @brief The model to visualize the answers to this poll.
|
|
*/
|
|
Q_PROPERTY(PollAnswerModel *answerModel READ answerModel CONSTANT)
|
|
|
|
/**
|
|
* @brief The total number of vote responses to the poll.
|
|
*/
|
|
Q_PROPERTY(int totalCount READ totalCount NOTIFY totalCountChanged)
|
|
|
|
public:
|
|
PollHandler() = default;
|
|
PollHandler(NeoChatRoom *room, const QString &pollStartId);
|
|
|
|
NeoChatRoom *room() const;
|
|
|
|
PollKind::Kind kind() const;
|
|
QString question() const;
|
|
bool hasEnded() const;
|
|
PollAnswerModel *answerModel();
|
|
|
|
/**
|
|
* @brief The total number of answer options.
|
|
*/
|
|
int numAnswers() const;
|
|
|
|
/**
|
|
* @brief The answer at the given row.
|
|
*/
|
|
Quotient::EventContent::Answer answerAtRow(int row) const;
|
|
|
|
/**
|
|
* @brief The number of responders who gave the answer ID.
|
|
*/
|
|
int answerCountAtId(const QString &id) const;
|
|
|
|
/**
|
|
* @brief Check whether the given member has selected the given ID in their response.
|
|
*/
|
|
bool checkMemberSelectedId(const QString &memberId, const QString &id) const;
|
|
|
|
int totalCount() const;
|
|
|
|
/**
|
|
* @brief The current answer IDs with the most votes.
|
|
*/
|
|
QStringList winningAnswerIds() const;
|
|
|
|
/**
|
|
* @brief Send an answer to the poll.
|
|
*/
|
|
Q_INVOKABLE void sendPollAnswer(const QString &eventId, const QString &answerId);
|
|
|
|
/**
|
|
* @brief Send the PollEndEvent.
|
|
*/
|
|
Q_INVOKABLE void endPoll() const;
|
|
|
|
Q_SIGNALS:
|
|
void questionChanged();
|
|
void hasEndedChanged();
|
|
void answersChanged();
|
|
void totalCountChanged();
|
|
|
|
/**
|
|
* @brief Emitted when the selected answers to the poll change.
|
|
*/
|
|
void selectionsChanged();
|
|
|
|
private:
|
|
QString m_pollStartId;
|
|
QPointer<NeoChatRoom> m_room;
|
|
|
|
void updatePoll(Quotient::RoomEventsRange events);
|
|
|
|
void checkLoadRelations(const QString &nextBatch = {});
|
|
void handleEvent(Quotient::RoomEvent *event);
|
|
void handleResponse(const Quotient::PollResponseEvent *event);
|
|
QHash<QString, QDateTime> m_selectionTimestamps;
|
|
QHash<QString, QStringList> m_selections;
|
|
|
|
bool m_hasEnded = false;
|
|
QDateTime m_endedTimestamp;
|
|
QString endText() const;
|
|
|
|
QPointer<PollAnswerModel> m_answerModel;
|
|
};
|