Migrate to matrix-structs for event and response parsing

This commit is contained in:
Konstantinos Sideris 2017-12-04 18:41:19 +02:00
parent 1976a3280c
commit a605e4486f
77 changed files with 648 additions and 4962 deletions

View file

@ -24,9 +24,7 @@
#include <QTimer>
#include <QWidget>
#include "MemberEventContent.h"
#include "MessageEvent.h"
#include "StateEvent.h"
#include <mtx.hpp>
class Cache;
class MatrixClient;
@ -37,14 +35,11 @@ class RoomSettings;
class RoomState;
class SideBarActions;
class Splitter;
class SyncResponse;
class TextInputWidget;
class TimelineViewManager;
class TopRoomBar;
class TypingDisplay;
class UserInfoWidget;
class JoinedRoom;
class LeftRoom;
constexpr int CONSENSUS_TIMEOUT = 1000;
constexpr int SHOW_CONTENT_TIMEOUT = 3000;
@ -76,8 +71,8 @@ private slots:
void updateTopBarAvatar(const QString &roomid, const QPixmap &img);
void updateOwnProfileInfo(const QUrl &avatar_url, const QString &display_name);
void setOwnAvatar(const QPixmap &img);
void initialSyncCompleted(const SyncResponse &response);
void syncCompleted(const SyncResponse &response);
void initialSyncCompleted(const mtx::responses::Sync &response);
void syncCompleted(const mtx::responses::Sync &response);
void syncFailed(const QString &msg);
void changeTopRoomInfo(const QString &room_id);
void logout();
@ -87,26 +82,34 @@ private slots:
private:
using UserID = QString;
using RoomStates = QMap<UserID, RoomState>;
using JoinedRooms = QMap<UserID, JoinedRoom>;
using LeftRooms = QMap<UserID, LeftRoom>;
using Membership = matrix::events::StateEvent<matrix::events::MemberEventContent>;
using Memberships = QMap<UserID, Membership>;
using Membership = mtx::events::StateEvent<mtx::events::state::Member>;
using Memberships = std::map<std::string, Membership>;
using JoinedRooms = std::map<std::string, mtx::responses::JoinedRoom>;
using LeftRooms = std::map<std::string, mtx::responses::LeftRoom>;
void removeLeftRooms(const LeftRooms &rooms);
void updateJoinedRooms(const JoinedRooms &rooms);
Memberships getMemberships(const QJsonArray &events) const;
RoomStates generateMembershipDifference(const JoinedRooms &rooms,
const RoomStates &states) const;
void updateTypingUsers(const QString &roomid, const QList<QString> &user_ids);
void updateUserMetadata(const QJsonArray &events);
void updateUserDisplayName(const Membership &event);
void updateUserAvatarUrl(const Membership &event);
void updateTypingUsers(const QString &roomid, const std::vector<std::string> &user_ids);
using MemberEvent = mtx::events::StateEvent<mtx::events::state::Member>;
void updateUserDisplayName(const MemberEvent &event);
void updateUserAvatarUrl(const MemberEvent &event);
void loadStateFromCache();
void deleteConfigs();
void resetUI();
template<class Collection>
Memberships getMemberships(const std::vector<Collection> &events) const;
template<class Collection>
void updateUserMetadata(const std::vector<Collection> &collection);
QHBoxLayout *topLayout_;
Splitter *splitter;
@ -153,3 +156,37 @@ private:
// return to the login page.
int initialSyncFailures = 0;
};
template<class Collection>
void
ChatPage::updateUserMetadata(const std::vector<Collection> &collection)
{
using Member = mtx::events::StateEvent<mtx::events::state::Member>;
for (auto &event : collection) {
if (mpark::holds_alternative<Member>(event)) {
auto member = mpark::get<Member>(event);
updateUserAvatarUrl(member);
updateUserDisplayName(member);
}
}
}
template<class Collection>
std::map<std::string, mtx::events::StateEvent<mtx::events::state::Member>>
ChatPage::getMemberships(const std::vector<Collection> &collection) const
{
std::map<std::string, mtx::events::StateEvent<mtx::events::state::Member>> memberships;
using Member = mtx::events::StateEvent<mtx::events::state::Member>;
for (auto &event : collection) {
if (mpark::holds_alternative<Member>(event)) {
auto member = mpark::get<Member>(event);
memberships.emplace(member.state_key, member);
}
}
return memberships;
}

View file

@ -20,12 +20,7 @@
#include <QFileInfo>
#include <QNetworkAccessManager>
#include <QUrl>
#include "MessageEvent.h"
class SyncResponse;
class Profile;
class RoomMessages;
#include <mtx.hpp>
/*
* MatrixClient provides the high level API to communicate with
@ -40,7 +35,7 @@ public:
// Client API.
void initialSync() noexcept;
void sync() noexcept;
void sendRoomMessage(matrix::events::MessageEventType ty,
void sendRoomMessage(mtx::events::MessageType ty,
int txnId,
const QString &roomid,
const QString &msg,
@ -107,15 +102,15 @@ signals:
// Returned profile data for the user's account.
void getOwnProfileResponse(const QUrl &avatar_url, const QString &display_name);
void initialSyncCompleted(const SyncResponse &response);
void initialSyncCompleted(const mtx::responses::Sync &response);
void initialSyncFailed(const QString &msg);
void syncCompleted(const SyncResponse &response);
void syncCompleted(const mtx::responses::Sync &response);
void syncFailed(const QString &msg);
void joinFailed(const QString &msg);
void messageSent(const QString &event_id, const QString &roomid, const int txn_id);
void messageSendFailed(const QString &roomid, const int txn_id);
void emoteSent(const QString &event_id, const QString &roomid, const int txn_id);
void messagesRetrieved(const QString &room_id, const RoomMessages &msgs);
void messagesRetrieved(const QString &room_id, const mtx::responses::Messages &msgs);
void joinedRoom(const QString &room_id);
void leftRoom(const QString &room_id);

View file

@ -21,28 +21,14 @@
#include <QPixmap>
#include <QUrl>
#include "AliasesEventContent.h"
#include "AvatarEventContent.h"
#include "CanonicalAliasEventContent.h"
#include "CreateEventContent.h"
#include "HistoryVisibilityEventContent.h"
#include "JoinRulesEventContent.h"
#include "MemberEventContent.h"
#include "NameEventContent.h"
#include "PowerLevelsEventContent.h"
#include "TopicEventContent.h"
#include "Event.h"
#include "RoomEvent.h"
#include "StateEvent.h"
namespace events = matrix::events;
#include <mtx.hpp>
class RoomState
{
public:
RoomState();
RoomState(const QJsonArray &events);
RoomState(const mtx::responses::Timeline &timeline);
RoomState(const mtx::responses::State &state);
// Calculate room data that are not immediatly accessible. Like room name and
// avatar.
@ -50,32 +36,37 @@ public:
// e.g If the room is 1-on-1 name and avatar should be extracted from a user.
void resolveName();
void resolveAvatar();
void parse(const QJsonObject &object);
void parse(const nlohmann::json &object);
QUrl getAvatar() const { return avatar_; };
QString getName() const { return name_; };
QString getTopic() const { return topic.content().topic().simplified(); };
QString getTopic() const
{
return QString::fromStdString(topic.content.topic).simplified();
};
void removeLeaveMemberships();
void update(const RoomState &state);
void updateFromEvents(const QJsonArray &events);
QJsonObject serialize() const;
template<class Collection>
void updateFromEvents(const std::vector<Collection> &collection);
std::string serialize() const;
// The latest state events.
events::StateEvent<events::AliasesEventContent> aliases;
events::StateEvent<events::AvatarEventContent> avatar;
events::StateEvent<events::CanonicalAliasEventContent> canonical_alias;
events::StateEvent<events::CreateEventContent> create;
events::StateEvent<events::HistoryVisibilityEventContent> history_visibility;
events::StateEvent<events::JoinRulesEventContent> join_rules;
events::StateEvent<events::NameEventContent> name;
events::StateEvent<events::PowerLevelsEventContent> power_levels;
events::StateEvent<events::TopicEventContent> topic;
mtx::events::StateEvent<mtx::events::state::Aliases> aliases;
mtx::events::StateEvent<mtx::events::state::Avatar> avatar;
mtx::events::StateEvent<mtx::events::state::CanonicalAlias> canonical_alias;
mtx::events::StateEvent<mtx::events::state::Create> create;
mtx::events::StateEvent<mtx::events::state::HistoryVisibility> history_visibility;
mtx::events::StateEvent<mtx::events::state::JoinRules> join_rules;
mtx::events::StateEvent<mtx::events::state::Name> name;
mtx::events::StateEvent<mtx::events::state::PowerLevels> power_levels;
mtx::events::StateEvent<mtx::events::state::Topic> topic;
// Contains the m.room.member events for all the joined users.
using UserID = QString;
QMap<UserID, events::StateEvent<events::MemberEventContent>> memberships;
using UserID = std::string;
std::map<UserID, mtx::events::StateEvent<mtx::events::state::Member>> memberships;
private:
QUrl avatar_;
@ -85,3 +76,44 @@ private:
// avatar event this should be empty.
QString userAvatar_;
};
template<class Collection>
void
RoomState::updateFromEvents(const std::vector<Collection> &collection)
{
using Aliases = mtx::events::StateEvent<mtx::events::state::Aliases>;
using Avatar = mtx::events::StateEvent<mtx::events::state::Avatar>;
using CanonicalAlias = mtx::events::StateEvent<mtx::events::state::CanonicalAlias>;
using Create = mtx::events::StateEvent<mtx::events::state::Create>;
using HistoryVisibility = mtx::events::StateEvent<mtx::events::state::HistoryVisibility>;
using JoinRules = mtx::events::StateEvent<mtx::events::state::JoinRules>;
using Member = mtx::events::StateEvent<mtx::events::state::Member>;
using Name = mtx::events::StateEvent<mtx::events::state::Name>;
using PowerLevels = mtx::events::StateEvent<mtx::events::state::PowerLevels>;
using Topic = mtx::events::StateEvent<mtx::events::state::Topic>;
for (const auto &event : collection) {
if (mpark::holds_alternative<Aliases>(event)) {
this->aliases = mpark::get<Aliases>(event);
} else if (mpark::holds_alternative<Avatar>(event)) {
this->avatar = mpark::get<Avatar>(event);
} else if (mpark::holds_alternative<CanonicalAlias>(event)) {
this->canonical_alias = mpark::get<CanonicalAlias>(event);
} else if (mpark::holds_alternative<Create>(event)) {
this->create = mpark::get<Create>(event);
} else if (mpark::holds_alternative<HistoryVisibility>(event)) {
this->history_visibility = mpark::get<HistoryVisibility>(event);
} else if (mpark::holds_alternative<JoinRules>(event)) {
this->join_rules = mpark::get<JoinRules>(event);
} else if (mpark::holds_alternative<Name>(event)) {
this->name = mpark::get<Name>(event);
} else if (mpark::holds_alternative<Member>(event)) {
auto membership = mpark::get<Member>(event);
this->memberships.emplace(membership.state_key, membership);
} else if (mpark::holds_alternative<PowerLevels>(event)) {
this->power_levels = mpark::get<PowerLevels>(event);
} else if (mpark::holds_alternative<Topic>(event)) {
this->topic = mpark::get<Topic>(event);
}
}
}

View file

@ -1,131 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonArray>
#include <QMap>
#include "Deserializable.h"
class Event : public Deserializable
{
public:
QJsonObject content() const { return content_; };
QJsonObject unsigned_content() const { return unsigned_; };
QString sender() const { return sender_; };
QString state_key() const { return state_key_; };
QString type() const { return type_; };
QString eventId() const { return event_id_; };
uint64_t timestamp() const { return origin_server_ts_; };
void deserialize(const QJsonValue &data) override;
private:
QJsonObject content_;
QJsonObject unsigned_;
QString sender_;
QString state_key_;
QString type_;
QString event_id_;
uint64_t origin_server_ts_;
};
class State : public Deserializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonArray events() const { return events_; };
private:
QJsonArray events_;
};
class Timeline : public Deserializable
{
public:
QJsonArray events() const { return events_; };
QString previousBatch() const { return prev_batch_; };
bool limited() const { return limited_; };
void deserialize(const QJsonValue &data) override;
private:
QJsonArray events_;
QString prev_batch_;
bool limited_;
};
// TODO: Add support for account_data, undread_notifications
class JoinedRoom : public Deserializable
{
public:
State state() const { return state_; };
Timeline timeline() const { return timeline_; };
QList<QString> typingUserIDs() const { return typingUserIDs_; };
void deserialize(const QJsonValue &data) override;
private:
State state_;
Timeline timeline_;
QList<QString> typingUserIDs_;
/* AccountData account_data_; */
/* UnreadNotifications unread_notifications_; */
};
class LeftRoom : public Deserializable
{
public:
State state() const { return state_; };
Timeline timeline() const { return timeline_; };
void deserialize(const QJsonValue &data) override;
private:
State state_;
Timeline timeline_;
};
// TODO: Add support for invited and left rooms.
class Rooms : public Deserializable
{
public:
QMap<QString, JoinedRoom> join() const { return join_; };
QMap<QString, LeftRoom> leave() const { return leave_; };
void deserialize(const QJsonValue &data) override;
private:
QMap<QString, JoinedRoom> join_;
QMap<QString, LeftRoom> leave_;
};
class SyncResponse : public Deserializable
{
public:
void deserialize(const QJsonDocument &data) override;
QString nextBatch() const { return next_batch_; };
Rooms rooms() const { return rooms_; };
private:
QString next_batch_;
Rooms rooms_;
};

View file

@ -25,13 +25,10 @@
#include <QWidget>
#include "FlatButton.h"
#include "Image.h"
#include "LoadingIndicator.h"
#include "emoji/PickButton.h"
namespace msgs = matrix::events::messages;
class FilteredTextEdit : public QTextEdit
{
Q_OBJECT

View file

@ -1,42 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include <QList>
#include "Deserializable.h"
namespace matrix {
namespace events {
class AliasesEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
QList<QString> aliases() const { return aliases_; };
private:
QList<QString> aliases_;
};
} // namespace events
} // namespace matrix

View file

@ -1,46 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include <QUrl>
#include "Deserializable.h"
namespace matrix {
namespace events {
/*
* A picture that is associated with the room.
*/
class AvatarEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
QUrl url() const { return url_; };
private:
QUrl url_;
};
} // namespace events
} // namespace matrix

View file

@ -1,48 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include "CanonicalAliasEventContent.h"
#include "Deserializable.h"
namespace matrix {
namespace events {
/*
* This event is used to inform the room about which alias should be considered
* the canonical one. This could be for display purposes or as suggestion to
* users which alias to use to advertise the room.
*/
class CanonicalAliasEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
QString alias() const { return alias_; };
private:
QString alias_;
};
} // namespace events
} // namespace matrix

View file

@ -1,47 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include "Deserializable.h"
namespace matrix {
namespace events {
/*
* This is the first event in a room and cannot be changed. It acts as the root
* of all other events.
*/
class CreateEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
QString creator() const { return creator_; };
private:
// The user_id of the room creator. This is set by the homeserver.
QString creator_;
};
} // namespace events
} // namespace matrix

View file

@ -1,183 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QDebug>
#include <QJsonValue>
#include "Deserializable.h"
namespace matrix {
namespace events {
enum class EventType
{
/// m.room.aliases
RoomAliases,
/// m.room.avatar
RoomAvatar,
/// m.room.canonical_alias
RoomCanonicalAlias,
/// m.room.create
RoomCreate,
/// m.room.history_visibility
RoomHistoryVisibility,
/// m.room.join_rules
RoomJoinRules,
/// m.room.member
RoomMember,
/// m.room.message
RoomMessage,
/// m.room.name
RoomName,
/// m.room.power_levels
RoomPowerLevels,
/// m.room.topic
RoomTopic,
// Unsupported event
Unsupported,
};
EventType
extractEventType(const QJsonObject &data);
bool
isMessageEvent(EventType type);
bool
isStateEvent(EventType type);
class UnsignedData
: public Deserializable
, public Serializable
{
public:
double age() const { return age_; }
QString transactionId() const { return transaction_id_; }
bool isEmpty() const { return age_ <= 0 && transaction_id_.isEmpty(); }
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
private:
double age_ = 0;
QString transaction_id_;
};
template<class Content>
class Event
: public Deserializable
, public Serializable
{
public:
Content content() const;
EventType eventType() const;
UnsignedData unsignedData() const { return unsignedData_; }
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
private:
Content content_;
EventType type_;
UnsignedData unsignedData_;
};
template<class Content>
inline Content
Event<Content>::content() const
{
return content_;
}
template<class Content>
inline EventType
Event<Content>::eventType() const
{
return type_;
}
template<class Content>
void
Event<Content>::deserialize(const QJsonValue &data)
{
if (!data.isObject())
throw DeserializationException("Event is not a JSON object");
auto object = data.toObject();
content_.deserialize(object.value("content"));
type_ = extractEventType(object);
if (object.contains("unsigned"))
unsignedData_.deserialize(object.value("unsigned"));
}
template<class Content>
QJsonObject
Event<Content>::serialize() const
{
QJsonObject object;
switch (type_) {
case EventType::RoomAliases:
object["type"] = "m.room.aliases";
break;
case EventType::RoomAvatar:
object["type"] = "m.room.avatar";
break;
case EventType::RoomCanonicalAlias:
object["type"] = "m.room.canonical_alias";
break;
case EventType::RoomCreate:
object["type"] = "m.room.create";
break;
case EventType::RoomHistoryVisibility:
object["type"] = "m.room.history_visibility";
break;
case EventType::RoomJoinRules:
object["type"] = "m.room.join_rules";
break;
case EventType::RoomMember:
object["type"] = "m.room.member";
break;
case EventType::RoomMessage:
object["type"] = "m.room.message";
break;
case EventType::RoomName:
object["type"] = "m.room.name";
break;
case EventType::RoomPowerLevels:
object["type"] = "m.room.power_levels";
break;
case EventType::RoomTopic:
object["type"] = "m.room.topic";
break;
case EventType::Unsupported:
qWarning() << "Unsupported type to serialize";
break;
}
object["content"] = content_.serialize();
if (!unsignedData_.isEmpty())
object["unsigned"] = unsignedData_.serialize();
return object;
}
} // namespace events
} // namespace matrix

View file

@ -1,49 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include "Deserializable.h"
namespace matrix {
namespace events {
enum class HistoryVisibility
{
Invited,
Joined,
Shared,
WorldReadable,
};
class HistoryVisibilityEventContent
: public Deserializable
, public Serializable
{
public:
HistoryVisibility historyVisibility() const { return history_visibility_; };
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
private:
HistoryVisibility history_visibility_;
};
} // namespace events
} // namespace matrix

View file

@ -1,61 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include "Deserializable.h"
namespace matrix {
namespace events {
enum class JoinRule
{
// A user who wishes to join the room must first receive
// an invite to the room from someone already inside of the room.
Invite,
// Reserved but not yet implemented by the Matrix specification.
Knock,
// Reserved but not yet implemented by the Matrix specification.
Private,
/// Anyone can join the room without any prior action.
Public,
};
/*
* Describes how users are allowed to join the room.
*/
class JoinRulesEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
JoinRule joinRule() const { return join_rule_; };
private:
JoinRule join_rule_;
};
} // namespace events
} // namespace matrix

View file

@ -1,68 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include <QUrl>
#include "Deserializable.h"
namespace matrix {
namespace events {
enum class Membership
{
// The user is banned.
Ban,
// The user has been invited.
Invite,
// The user has joined.
Join,
// The user has requested to join.
Knock,
// The user has left.
Leave,
};
/*
* The current membership state of a user in the room.
*/
class MemberEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
QUrl avatarUrl() const { return avatar_url_; };
QString displayName() const { return display_name_; };
Membership membershipState() const { return membership_state_; };
private:
QUrl avatar_url_;
QString display_name_;
Membership membership_state_;
};
} // namespace events
} // namespace matrix

View file

@ -1,64 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "MessageEventContent.h"
#include "RoomEvent.h"
namespace matrix {
namespace events {
template<class MsgContent>
class MessageEvent : public RoomEvent<MessageEventContent>
{
public:
MsgContent msgContent() const;
void deserialize(const QJsonValue &data) override;
private:
MsgContent msg_content_;
};
template<class MsgContent>
inline MsgContent
MessageEvent<MsgContent>::msgContent() const
{
return msg_content_;
}
template<class MsgContent>
void
MessageEvent<MsgContent>::deserialize(const QJsonValue &data)
{
RoomEvent<MessageEventContent>::deserialize(data);
msg_content_.deserialize(data.toObject().value("content").toObject());
}
namespace messages {
struct ThumbnailInfo
{
int h;
int w;
int size = 0;
QString mimetype;
};
} // namespace messages
} // namespace events
} // namespace matrix

View file

@ -1,74 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include "Deserializable.h"
namespace matrix {
namespace events {
enum class MessageEventType
{
// m.audio
Audio,
// m.emote
Emote,
// m.file
File,
// m.image
Image,
// m.location
Location,
// m.notice
Notice,
// m.text
Text,
// m.video
Video,
// Unrecognized message type
Unknown,
};
MessageEventType
extractMessageEventType(const QJsonObject &data);
class MessageEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
QString body() const { return body_; };
private:
QString body_;
};
} // namespace events
} // namespace matrix

View file

@ -1,45 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include "Deserializable.h"
namespace matrix {
namespace events {
/*
* A human-friendly room name designed to be displayed to the end-user.
*/
class NameEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
QString name() const { return name_; };
private:
QString name_;
};
} // namespace events
} // namespace matrix

View file

@ -1,73 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include <QMap>
#include "Deserializable.h"
namespace matrix {
namespace events {
enum class PowerLevels
{
User = 0,
Moderator = 50,
Admin = 100,
};
/*
* Defines the power levels (privileges) of users in the room.
*/
class PowerLevelsEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
int banLevel() const { return ban_; };
int inviteLevel() const { return invite_; };
int kickLevel() const { return kick_; };
int redactLevel() const { return redact_; };
int eventsDefaultLevel() const { return events_default_; };
int stateDefaultLevel() const { return state_default_; };
int usersDefaultLevel() const { return users_default_; };
int eventLevel(QString event_type) const;
int userLevel(QString user_id) const;
private:
int ban_ = static_cast<int>(PowerLevels::Moderator);
int invite_ = static_cast<int>(PowerLevels::Moderator);
int kick_ = static_cast<int>(PowerLevels::Moderator);
int redact_ = static_cast<int>(PowerLevels::Moderator);
int events_default_ = static_cast<int>(PowerLevels::User);
int state_default_ = static_cast<int>(PowerLevels::Moderator);
int users_default_ = static_cast<int>(PowerLevels::User);
QMap<QString, int> events_;
QMap<QString, int> users_;
};
} // namespace events
} // namespace matrix

View file

@ -1,116 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include <QString>
#include "Event.h"
namespace matrix {
namespace events {
template<class Content>
class RoomEvent : public Event<Content>
{
public:
QString eventId() const;
QString roomId() const;
QString sender() const;
uint64_t timestamp() const;
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
private:
QString event_id_;
QString room_id_;
QString sender_;
uint64_t origin_server_ts_;
};
template<class Content>
inline QString
RoomEvent<Content>::eventId() const
{
return event_id_;
}
template<class Content>
inline QString
RoomEvent<Content>::roomId() const
{
return room_id_;
}
template<class Content>
inline QString
RoomEvent<Content>::sender() const
{
return sender_;
}
template<class Content>
inline uint64_t
RoomEvent<Content>::timestamp() const
{
return origin_server_ts_;
}
template<class Content>
void
RoomEvent<Content>::deserialize(const QJsonValue &data)
{
Event<Content>::deserialize(data);
auto object = data.toObject();
if (!object.contains("event_id"))
throw DeserializationException("event_id key is missing");
if (!object.contains("origin_server_ts"))
throw DeserializationException("origin_server_ts key is missing");
// FIXME: Synapse doesn't include room id?!
/* if (!object.contains("room_id")) */
/* throw DeserializationException("room_id key is missing"); */
if (!object.contains("sender"))
throw DeserializationException("sender key is missing");
event_id_ = object.value("event_id").toString();
room_id_ = object.value("room_id").toString();
sender_ = object.value("sender").toString();
origin_server_ts_ = object.value("origin_server_ts").toDouble();
}
template<class Content>
QJsonObject
RoomEvent<Content>::serialize() const
{
QJsonObject object = Event<Content>::serialize();
object["event_id"] = event_id_;
object["room_id"] = room_id_;
object["sender"] = sender_;
object["origin_server_ts"] = QJsonValue(static_cast<qint64>(origin_server_ts_));
return object;
}
} // namespace events
} // namespace matrix

View file

@ -1,88 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include "RoomEvent.h"
namespace matrix {
namespace events {
template<class Content>
class StateEvent : public RoomEvent<Content>
{
public:
QString stateKey() const;
Content previousContent() const;
void deserialize(const QJsonValue &data);
QJsonObject serialize() const;
private:
QString state_key_;
Content prev_content_;
};
template<class Content>
inline QString
StateEvent<Content>::stateKey() const
{
return state_key_;
}
template<class Content>
inline Content
StateEvent<Content>::previousContent() const
{
return prev_content_;
}
template<class Content>
void
StateEvent<Content>::deserialize(const QJsonValue &data)
{
RoomEvent<Content>::deserialize(data);
auto object = data.toObject();
if (!object.contains("state_key"))
throw DeserializationException("state_key key is missing");
state_key_ = object.value("state_key").toString();
if (object.contains("prev_content"))
prev_content_.deserialize(object.value("prev_content"));
}
template<class Content>
QJsonObject
StateEvent<Content>::serialize() const
{
QJsonObject object = RoomEvent<Content>::serialize();
object["state_key"] = state_key_;
auto prev = prev_content_.serialize();
if (!prev.isEmpty())
object["prev_content"] = prev;
return object;
}
} // namespace events
} // namespace matrix

View file

@ -1,46 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonValue>
#include "Deserializable.h"
namespace matrix {
namespace events {
/*
* A topic is a short message detailing what is currently being discussed in the
* room.
*/
class TopicEventContent
: public Deserializable
, public Serializable
{
public:
void deserialize(const QJsonValue &data) override;
QJsonObject serialize() const override;
QString topic() const { return topic_; };
private:
QString topic_;
};
} // namespace events
} // namespace matrix

View file

@ -1,50 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include "Deserializable.h"
namespace matrix {
namespace events {
namespace messages {
struct AudioInfo
{
uint64_t duration;
int size = 0;
QString mimetype;
};
class Audio : public Deserializable
{
public:
QString url() const { return url_; };
AudioInfo info() const { return info_; };
void deserialize(const QJsonObject &object) override;
private:
QString url_;
AudioInfo info_;
};
} // namespace messages
} // namespace events
} // namespace matrix

View file

@ -1,34 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include "Deserializable.h"
namespace matrix {
namespace events {
namespace messages {
class Emote : public Deserializable
{
public:
void deserialize(const QJsonObject &obj) override;
};
} // namespace messages
} // namespace events
} // namespace matrix

View file

@ -1,55 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include "Deserializable.h"
#include "MessageEvent.h"
namespace matrix {
namespace events {
namespace messages {
struct FileInfo
{
int size = 0;
QString mimetype;
QString thumbnail_url;
ThumbnailInfo thumbnail_info;
};
class File : public Deserializable
{
public:
QString url() const { return url_; };
QString filename() const { return filename_; };
FileInfo info() const { return info_; };
void deserialize(const QJsonObject &object) override;
private:
QString url_;
QString filename_;
FileInfo info_;
};
} // namespace messages
} // namespace events
} // namespace matrix

View file

@ -1,54 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include "Deserializable.h"
#include "MessageEvent.h"
namespace matrix {
namespace events {
namespace messages {
struct ImageInfo
{
int h;
int w;
int size = 0;
QString mimetype;
QString thumbnail_url;
ThumbnailInfo thumbnail_info;
};
class Image : public Deserializable
{
public:
QString url() const { return url_; };
ImageInfo info() const { return info_; };
void deserialize(const QJsonObject &object) override;
private:
QString url_;
ImageInfo info_;
};
} // namespace messages
} // namespace events
} // namespace matrix

View file

@ -1,50 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include "Deserializable.h"
#include "MessageEvent.h"
namespace matrix {
namespace events {
namespace messages {
struct LocationInfo
{
QString thumbnail_url;
ThumbnailInfo thumbnail_info;
};
class Location : public Deserializable
{
public:
QString geoUri() const { return geo_uri_; };
LocationInfo info() const { return info_; };
void deserialize(const QJsonObject &object) override;
private:
QString geo_uri_;
LocationInfo info_;
};
} // namespace messages
} // namespace events
} // namespace matrix

View file

@ -1,34 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include "Deserializable.h"
namespace matrix {
namespace events {
namespace messages {
class Notice : public Deserializable
{
public:
void deserialize(const QJsonObject &obj) override;
};
} // namespace messages
} // namespace events
} // namespace matrix

View file

@ -1,34 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include "Deserializable.h"
namespace matrix {
namespace events {
namespace messages {
class Text : public Deserializable
{
public:
void deserialize(const QJsonObject &obj) override;
};
} // namespace messages
} // namespace events
} // namespace matrix

View file

@ -1,55 +0,0 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include "Deserializable.h"
#include "MessageEvent.h"
namespace matrix {
namespace events {
namespace messages {
struct VideoInfo
{
int h;
int w;
int size = 0;
int duration;
QString mimetype;
QString thumbnail_url;
ThumbnailInfo thumbnail_info;
};
class Video : public Deserializable
{
public:
QString url() const { return url_; };
VideoInfo info() const { return info_; };
void deserialize(const QJsonObject &object) override;
private:
QString url_;
VideoInfo info_;
};
} // namespace messages
} // namespace events
} // namespace matrix

View file

@ -25,16 +25,7 @@
#include <QStyle>
#include <QStyleOption>
#include "Audio.h"
#include "Emote.h"
#include "File.h"
#include "Image.h"
#include "Notice.h"
#include "Text.h"
#include "Video.h"
#include "AvatarProvider.h"
#include "MessageEvent.h"
#include "RoomInfoListItem.h"
#include "TimelineViewManager.h"
@ -44,26 +35,23 @@ class VideoItem;
class FileItem;
class Avatar;
namespace events = matrix::events;
namespace msgs = matrix::events::messages;
class TimelineItem : public QWidget
{
Q_OBJECT
public:
TimelineItem(const events::MessageEvent<msgs::Notice> &e,
TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Notice> &e,
bool with_sender,
QWidget *parent = 0);
TimelineItem(const events::MessageEvent<msgs::Text> &e,
TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Text> &e,
bool with_sender,
QWidget *parent = 0);
TimelineItem(const events::MessageEvent<msgs::Emote> &e,
TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Emote> &e,
bool with_sender,
QWidget *parent = 0);
// For local messages.
// m.text & m.emote
TimelineItem(events::MessageEventType ty,
TimelineItem(mtx::events::MessageType ty,
const QString &userid,
QString body,
bool withSender,
@ -75,19 +63,19 @@ public:
TimelineItem(VideoItem *item, const QString &userid, bool withSender, QWidget *parent = 0);
TimelineItem(ImageItem *img,
const events::MessageEvent<msgs::Image> &e,
const mtx::events::RoomEvent<mtx::events::msg::Image> &e,
bool with_sender,
QWidget *parent);
TimelineItem(FileItem *file,
const events::MessageEvent<msgs::File> &e,
const mtx::events::RoomEvent<mtx::events::msg::File> &e,
bool with_sender,
QWidget *parent);
TimelineItem(AudioItem *audio,
const events::MessageEvent<msgs::Audio> &e,
const mtx::events::RoomEvent<mtx::events::msg::Audio> &e,
bool with_sender,
QWidget *parent);
TimelineItem(VideoItem *video,
const events::MessageEvent<msgs::Video> &e,
const mtx::events::RoomEvent<mtx::events::msg::Video> &e,
bool with_sender,
QWidget *parent);
@ -185,16 +173,17 @@ TimelineItem::setupWidgetLayout(Widget *widget,
{
init();
event_id_ = event.eventId();
event_id_ = QString::fromStdString(event.event_id);
const auto sender = QString::fromStdString(event.sender);
auto timestamp = QDateTime::fromMSecsSinceEpoch(event.timestamp());
auto displayName = TimelineViewManager::displayName(event.sender());
auto timestamp = QDateTime::fromMSecsSinceEpoch(event.origin_server_ts);
auto displayName = TimelineViewManager::displayName(sender);
QSettings settings;
descriptionMsg_ = {event.sender() == settings.value("auth/user_id") ? "You" : displayName,
event.sender(),
descriptionMsg_ = {sender == settings.value("auth/user_id") ? "You" : displayName,
sender,
msgDescription,
descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.timestamp()))};
descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.origin_server_ts))};
generateTimestamp(timestamp);
@ -209,7 +198,7 @@ TimelineItem::setupWidgetLayout(Widget *widget,
mainLayout_->addLayout(headerLayout_);
AvatarProvider::resolve(event.sender(), this);
AvatarProvider::resolve(sender, this);
} else {
setupSimpleLayout();
}

View file

@ -27,39 +27,27 @@
#include <QStyle>
#include <QStyleOption>
#include "Audio.h"
#include "Emote.h"
#include "File.h"
#include "Image.h"
#include "Notice.h"
#include "Text.h"
#include "Video.h"
#include <mtx.hpp>
#include "MatrixClient.h"
#include "MessageEvent.h"
#include "TimelineItem.h"
class FloatingButton;
class RoomMessages;
class ScrollBar;
class Timeline;
struct DescInfo;
namespace msgs = matrix::events::messages;
namespace events = matrix::events;
// Contains info about a message shown in the history view
// but not yet confirmed by the homeserver through sync.
struct PendingMessage
{
matrix::events::MessageEventType ty;
mtx::events::MessageType ty;
int txn_id;
QString body;
QString filename;
QString event_id;
TimelineItem *widget;
PendingMessage(matrix::events::MessageEventType ty,
PendingMessage(mtx::events::MessageType ty,
int txn_id,
QString body,
QString filename,
@ -86,7 +74,7 @@ class TimelineView : public QWidget
Q_OBJECT
public:
TimelineView(const Timeline &timeline,
TimelineView(const mtx::responses::Timeline &timeline,
QSharedPointer<MatrixClient> client,
const QString &room_id,
QWidget *parent = 0);
@ -95,10 +83,10 @@ public:
QWidget *parent = 0);
// Add new events at the end of the timeline.
int addEvents(const Timeline &timeline);
void addUserMessage(matrix::events::MessageEventType ty, const QString &msg);
int addEvents(const mtx::responses::Timeline &timeline);
void addUserMessage(mtx::events::MessageType ty, const QString &msg);
template<class Widget, events::MessageEventType MsgType>
template<class Widget, mtx::events::MessageType MsgType>
void addUserMessage(const QString &url, const QString &filename);
void updatePendingMessage(int txn_id, QString event_id);
void scrollDown();
@ -109,7 +97,7 @@ public slots:
void fetchHistory();
// Add old events at the top of the timeline.
void addBackwardsEvents(const QString &room_id, const RoomMessages &msgs);
void addBackwardsEvents(const QString &room_id, const mtx::responses::Messages &msgs);
// Whether or not the initial batch has been loaded.
bool hasLoaded() { return scroll_layout_->count() > 1 || isTimelineFinished; }
@ -135,13 +123,14 @@ private:
void notifyForLastEvent();
void readLastEvent() const;
QString getLastEventId() const;
QString getEventSender(const mtx::events::collections::TimelineEvents &event) const;
template<class Event, class Widget>
TimelineItem *processMessageEvent(const QJsonObject &event, TimelineDirection direction);
TimelineItem *processMessageEvent(const Event &event, TimelineDirection direction);
// TODO: Remove this eventually.
template<class Event>
TimelineItem *processMessageEvent(const QJsonObject &event, TimelineDirection direction);
TimelineItem *processMessageEvent(const Event &event, TimelineDirection direction);
// For events with custom display widgets.
template<class Event, class Widget>
@ -164,7 +153,8 @@ private:
void handleNewUserMessage(PendingMessage msg);
// Return nullptr if the event couldn't be parsed.
TimelineItem *parseMessageEvent(const QJsonObject &event, TimelineDirection direction);
TimelineItem *parseMessageEvent(const mtx::events::collections::TimelineEvents &event,
TimelineDirection direction);
QVBoxLayout *top_layout_;
QVBoxLayout *scroll_layout_;
@ -207,7 +197,7 @@ private:
QSharedPointer<MatrixClient> client_;
};
template<class Widget, events::MessageEventType MsgType>
template<class Widget, mtx::events::MessageType MsgType>
void
TimelineView::addUserMessage(const QString &url, const QString &filename)
{
@ -252,62 +242,50 @@ TimelineView::createTimelineItem(const Event &event, bool withSender)
template<class Event>
TimelineItem *
TimelineView::processMessageEvent(const QJsonObject &data, TimelineDirection direction)
TimelineView::processMessageEvent(const Event &event, TimelineDirection direction)
{
Event event;
const auto event_id = QString::fromStdString(event.event_id);
const auto sender = QString::fromStdString(event.sender);
try {
event.deserialize(data);
} catch (const DeserializationException &e) {
qWarning() << e.what() << data;
return nullptr;
}
if (isDuplicate(event.eventId()))
if (isDuplicate(event_id))
return nullptr;
eventIds_[event.eventId()] = true;
eventIds_[event_id] = true;
QString txnid = event.unsignedData().transactionId();
if (!txnid.isEmpty() && isPendingMessage(txnid, event.sender(), local_user_)) {
const QString txnid = QString::fromStdString(event.unsigned_data.transaction_id);
if (!txnid.isEmpty() && isPendingMessage(txnid, sender, local_user_)) {
removePendingMessage(txnid);
return nullptr;
}
auto with_sender = isSenderRendered(event.sender(), direction);
auto with_sender = isSenderRendered(sender, direction);
updateLastSender(event.sender(), direction);
updateLastSender(sender, direction);
return createTimelineItem<Event>(event, with_sender);
}
template<class Event, class Widget>
TimelineItem *
TimelineView::processMessageEvent(const QJsonObject &data, TimelineDirection direction)
TimelineView::processMessageEvent(const Event &event, TimelineDirection direction)
{
Event event;
const auto event_id = QString::fromStdString(event.event_id);
const auto sender = QString::fromStdString(event.sender);
try {
event.deserialize(data);
} catch (const DeserializationException &e) {
qWarning() << e.what() << data;
return nullptr;
}
if (isDuplicate(event.eventId()))
if (isDuplicate(event_id))
return nullptr;
eventIds_[event.eventId()] = true;
eventIds_[event_id] = true;
QString txnid = event.unsignedData().transactionId();
if (!txnid.isEmpty() && isPendingMessage(txnid, event.sender(), local_user_)) {
const QString txnid = QString::fromStdString(event.unsigned_data.transaction_id);
if (!txnid.isEmpty() && isPendingMessage(txnid, sender, local_user_)) {
removePendingMessage(txnid);
return nullptr;
}
auto with_sender = isSenderRendered(event.sender(), direction);
auto with_sender = isSenderRendered(sender, direction);
updateLastSender(event.sender(), direction);
updateLastSender(sender, direction);
return createTimelineItem<Event, Widget>(event, with_sender);
}

View file

@ -21,12 +21,10 @@
#include <QSharedPointer>
#include <QStackedWidget>
#include "MessageEvent.h"
#include <mtx.hpp>
class JoinedRoom;
class MatrixClient;
class RoomInfoListItem;
class Rooms;
class TimelineView;
struct DescInfo;
@ -39,14 +37,14 @@ public:
~TimelineViewManager();
// Initialize with timeline events.
void initialize(const Rooms &rooms);
void initialize(const mtx::responses::Rooms &rooms);
// Empty initialization.
void initialize(const QList<QString> &rooms);
void addRoom(const JoinedRoom &room, const QString &room_id);
void addRoom(const mtx::responses::JoinedRoom &room, const QString &room_id);
void addRoom(const QString &room_id);
void sync(const Rooms &rooms);
void sync(const mtx::responses::Rooms &rooms);
void clearAll();
// Check if all the timelines have been loaded.

View file

@ -24,12 +24,9 @@
#include <QSharedPointer>
#include <QWidget>
#include "Audio.h"
#include "MatrixClient.h"
#include "MessageEvent.h"
namespace events = matrix::events;
namespace msgs = matrix::events::messages;
#include <mtx.hpp>
class AudioItem : public QWidget
{
@ -46,7 +43,7 @@ class AudioItem : public QWidget
public:
AudioItem(QSharedPointer<MatrixClient> client,
const events::MessageEvent<msgs::Audio> &event,
const mtx::events::RoomEvent<mtx::events::msg::Audio> &event,
QWidget *parent = nullptr);
AudioItem(QSharedPointer<MatrixClient> client,
@ -94,7 +91,7 @@ private:
QString readableFileSize_;
QString filenameToSave_;
events::MessageEvent<msgs::Audio> event_;
mtx::events::RoomEvent<mtx::events::msg::Audio> event_;
QSharedPointer<MatrixClient> client_;
QMediaPlayer *player_;

View file

@ -23,12 +23,9 @@
#include <QSharedPointer>
#include <QWidget>
#include "File.h"
#include "MatrixClient.h"
#include "MessageEvent.h"
#include <mtx.hpp>
namespace events = matrix::events;
namespace msgs = matrix::events::messages;
#include "MatrixClient.h"
class FileItem : public QWidget
{
@ -40,7 +37,7 @@ class FileItem : public QWidget
public:
FileItem(QSharedPointer<MatrixClient> client,
const events::MessageEvent<msgs::File> &event,
const mtx::events::RoomEvent<mtx::events::msg::File> &event,
QWidget *parent = nullptr);
FileItem(QSharedPointer<MatrixClient> client,
@ -75,7 +72,7 @@ private:
QString readableFileSize_;
QString filenameToSave_;
events::MessageEvent<msgs::File> event_;
mtx::events::RoomEvent<mtx::events::msg::File> event_;
QSharedPointer<MatrixClient> client_;
QIcon icon_;

View file

@ -22,19 +22,16 @@
#include <QSharedPointer>
#include <QWidget>
#include "Image.h"
#include "MatrixClient.h"
#include "MessageEvent.h"
#include <mtx.hpp>
namespace events = matrix::events;
namespace msgs = matrix::events::messages;
#include "MatrixClient.h"
class ImageItem : public QWidget
{
Q_OBJECT
public:
ImageItem(QSharedPointer<MatrixClient> client,
const events::MessageEvent<msgs::Image> &event,
const mtx::events::RoomEvent<mtx::events::msg::Image> &event,
QWidget *parent = nullptr);
ImageItem(QSharedPointer<MatrixClient> client,
@ -72,7 +69,7 @@ private:
int bottom_height_ = 30;
events::MessageEvent<msgs::Image> event_;
mtx::events::RoomEvent<mtx::events::msg::Image> event_;
QSharedPointer<MatrixClient> client_;
};

View file

@ -23,11 +23,8 @@
#include <QWidget>
#include "MatrixClient.h"
#include "MessageEvent.h"
#include "Video.h"
namespace events = matrix::events;
namespace msgs = matrix::events::messages;
#include <mtx.hpp>
class VideoItem : public QWidget
{
@ -35,7 +32,7 @@ class VideoItem : public QWidget
public:
VideoItem(QSharedPointer<MatrixClient> client,
const events::MessageEvent<msgs::Video> &event,
const mtx::events::RoomEvent<mtx::events::msg::Video> &event,
QWidget *parent = nullptr);
VideoItem(QSharedPointer<MatrixClient> client,
@ -53,6 +50,6 @@ private:
QLabel *label_;
events::MessageEvent<msgs::Video> event_;
mtx::events::RoomEvent<mtx::events::msg::Video> event_;
QSharedPointer<MatrixClient> client_;
};