summary refs log tree commit diff
path: root/src/timeline/TimelineViewManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/timeline/TimelineViewManager.cpp')
-rw-r--r--src/timeline/TimelineViewManager.cpp318
1 files changed, 318 insertions, 0 deletions
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
new file mode 100644

index 00000000..1decab35 --- /dev/null +++ b/src/timeline/TimelineViewManager.cpp
@@ -0,0 +1,318 @@ +/* + * 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/>. + */ + +#include <random> + +#include <QApplication> +#include <QFileInfo> +#include <QSettings> + +#include "Cache.h" +#include "Logging.h" +#include "timeline/TimelineView.h" +#include "timeline/TimelineViewManager.h" +#include "timeline/widgets/AudioItem.h" +#include "timeline/widgets/FileItem.h" +#include "timeline/widgets/ImageItem.h" +#include "timeline/widgets/VideoItem.h" + +TimelineViewManager::TimelineViewManager(QWidget *parent) + : QStackedWidget(parent) +{ + setStyleSheet("border: none;"); +} + +void +TimelineViewManager::removeTimelineEvent(const QString &room_id, const QString &event_id) +{ + auto view = views_[room_id]; + + if (view) + view->removeEvent(event_id); +} + +void +TimelineViewManager::queueTextMessage(const QString &msg) +{ + if (active_room_.isEmpty()) + return; + + auto room_id = active_room_; + auto view = views_[room_id]; + + view->addUserMessage(mtx::events::MessageType::Text, msg); +} + +void +TimelineViewManager::queueEmoteMessage(const QString &msg) +{ + if (active_room_.isEmpty()) + return; + + auto room_id = active_room_; + auto view = views_[room_id]; + + view->addUserMessage(mtx::events::MessageType::Emote, msg); +} + +void +TimelineViewManager::queueImageMessage(const QString &roomid, + const QString &filename, + const QString &url, + const QString &mime, + uint64_t size, + const QSize &dimensions) +{ + if (!timelineViewExists(roomid)) { + nhlog::ui()->warn("Cannot send m.image message to a non-managed view"); + return; + } + + auto view = views_[roomid]; + + view->addUserMessage<ImageItem, mtx::events::MessageType::Image>( + url, filename, mime, size, dimensions); +} + +void +TimelineViewManager::queueFileMessage(const QString &roomid, + const QString &filename, + const QString &url, + const QString &mime, + uint64_t size) +{ + if (!timelineViewExists(roomid)) { + nhlog::ui()->warn("cannot send m.file message to a non-managed view"); + return; + } + + auto view = views_[roomid]; + + view->addUserMessage<FileItem, mtx::events::MessageType::File>(url, filename, mime, size); +} + +void +TimelineViewManager::queueAudioMessage(const QString &roomid, + const QString &filename, + const QString &url, + const QString &mime, + uint64_t size) +{ + if (!timelineViewExists(roomid)) { + nhlog::ui()->warn("cannot send m.audio message to a non-managed view"); + return; + } + + auto view = views_[roomid]; + + view->addUserMessage<AudioItem, mtx::events::MessageType::Audio>(url, filename, mime, size); +} + +void +TimelineViewManager::queueVideoMessage(const QString &roomid, + const QString &filename, + const QString &url, + const QString &mime, + uint64_t size) +{ + if (!timelineViewExists(roomid)) { + nhlog::ui()->warn("cannot send m.video message to a non-managed view"); + return; + } + + auto view = views_[roomid]; + + view->addUserMessage<VideoItem, mtx::events::MessageType::Video>(url, filename, mime, size); +} + +void +TimelineViewManager::initialize(const mtx::responses::Rooms &rooms) +{ + for (auto it = rooms.join.cbegin(); it != rooms.join.cend(); ++it) { + addRoom(it->second, QString::fromStdString(it->first)); + } + + sync(rooms); +} + +void +TimelineViewManager::initWithMessages(const std::map<QString, mtx::responses::Timeline> &msgs) +{ + for (auto it = msgs.cbegin(); it != msgs.cend(); ++it) { + if (timelineViewExists(it->first)) + return; + + // Create a history view with the room events. + TimelineView *view = new TimelineView(it->second, it->first); + views_.emplace(it->first, QSharedPointer<TimelineView>(view)); + + connect(view, + &TimelineView::updateLastTimelineMessage, + this, + &TimelineViewManager::updateRoomsLastMessage); + + // Add the view in the widget stack. + addWidget(view); + } +} + +void +TimelineViewManager::initialize(const std::vector<std::string> &rooms) +{ + for (const auto &roomid : rooms) + addRoom(QString::fromStdString(roomid)); +} + +void +TimelineViewManager::addRoom(const mtx::responses::JoinedRoom &room, const QString &room_id) +{ + if (timelineViewExists(room_id)) + return; + + // Create a history view with the room events. + TimelineView *view = new TimelineView(room.timeline, room_id); + views_.emplace(room_id, QSharedPointer<TimelineView>(view)); + + connect(view, + &TimelineView::updateLastTimelineMessage, + this, + &TimelineViewManager::updateRoomsLastMessage); + + // Add the view in the widget stack. + addWidget(view); +} + +void +TimelineViewManager::addRoom(const QString &room_id) +{ + if (timelineViewExists(room_id)) + return; + + // Create a history view without any events. + TimelineView *view = new TimelineView(room_id); + views_.emplace(room_id, QSharedPointer<TimelineView>(view)); + + connect(view, + &TimelineView::updateLastTimelineMessage, + this, + &TimelineViewManager::updateRoomsLastMessage); + + // Add the view in the widget stack. + addWidget(view); +} + +void +TimelineViewManager::sync(const mtx::responses::Rooms &rooms) +{ + for (const auto &room : rooms.join) { + auto roomid = QString::fromStdString(room.first); + + if (!timelineViewExists(roomid)) { + nhlog::ui()->warn("ignoring event from unknown room: {}", + roomid.toStdString()); + continue; + } + + auto view = views_.at(roomid); + + view->addEvents(room.second.timeline); + } +} + +void +TimelineViewManager::setHistoryView(const QString &room_id) +{ + if (!timelineViewExists(room_id)) { + nhlog::ui()->warn("room from RoomList is not present in ViewManager: {}", + room_id.toStdString()); + return; + } + + active_room_ = room_id; + auto view = views_.at(room_id); + + setCurrentWidget(view.data()); + + view->fetchHistory(); + view->scrollDown(); +} + +QString +TimelineViewManager::chooseRandomColor() +{ + std::random_device random_device; + std::mt19937 engine{random_device()}; + std::uniform_real_distribution<float> dist(0, 1); + + float hue = dist(engine); + float saturation = 0.9; + float value = 0.7; + + int hue_i = hue * 6; + + float f = hue * 6 - hue_i; + + float p = value * (1 - saturation); + float q = value * (1 - f * saturation); + float t = value * (1 - (1 - f) * saturation); + + float r = 0; + float g = 0; + float b = 0; + + if (hue_i == 0) { + r = value; + g = t; + b = p; + } else if (hue_i == 1) { + r = q; + g = value; + b = p; + } else if (hue_i == 2) { + r = p; + g = value; + b = t; + } else if (hue_i == 3) { + r = p; + g = q; + b = value; + } else if (hue_i == 4) { + r = t; + g = p; + b = value; + } else if (hue_i == 5) { + r = value; + g = p; + b = q; + } + + int ri = r * 256; + int gi = g * 256; + int bi = b * 256; + + QColor color(ri, gi, bi); + + return color.name(); +} + +bool +TimelineViewManager::hasLoaded() const +{ + return std::all_of(views_.cbegin(), views_.cend(), [](const auto &view) { + return view.second->hasLoaded(); + }); +}