diff --git a/src/Cache.cpp b/src/Cache.cpp
index 3a388bb9..1061e60e 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -915,8 +915,8 @@ Cache::saveState(const mtx::responses::Sync &res)
bool has_new_tags = false;
for (const auto &evt : room.second.account_data.events) {
// for now only fetch tag events
- if (std::holds_alternative<Event<account_data::Tag>>(evt)) {
- auto tags_evt = std::get<Event<account_data::Tag>>(evt);
+ if (std::holds_alternative<Event<account_data::Tags>>(evt)) {
+ auto tags_evt = std::get<Event<account_data::Tags>>(evt);
has_new_tags = true;
for (const auto &tag : tags_evt.content.tags) {
updatedInfo.tags.push_back(tag.first);
@@ -1081,7 +1081,7 @@ Cache::roomsWithTagUpdates(const mtx::responses::Sync &res)
for (const auto &room : res.rooms.join) {
bool hasUpdates = false;
for (const auto &evt : room.second.account_data.events) {
- if (std::holds_alternative<Event<account_data::Tag>>(evt)) {
+ if (std::holds_alternative<Event<account_data::Tags>>(evt)) {
hasUpdates = true;
}
}
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 6670532c..1e06da5d 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -301,6 +301,29 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
connect(text_input_, &TextInputWidget::sendUnbanRoomRequest, this, &ChatPage::unbanUser);
connect(
+ text_input_, &TextInputWidget::changeRoomNick, this, [this](const QString &displayName) {
+ mtx::events::state::Member member;
+ member.display_name = displayName.toStdString();
+ member.avatar_url =
+ cache::avatarUrl(currentRoom(),
+ QString::fromStdString(http::client()->user_id().to_string()))
+ .toStdString();
+ member.membership = mtx::events::state::Membership::Join;
+
+ http::client()
+ ->send_state_event<mtx::events::state::Member,
+ mtx::events::EventType::RoomMember>(
+ currentRoom().toStdString(),
+ http::client()->user_id().to_string(),
+ member,
+ [](mtx::responses::EventId, mtx::http::RequestErr err) {
+ if (err)
+ nhlog::net()->error("Failed to set room displayname: {}",
+ err->matrix_error.error);
+ });
+ });
+
+ connect(
text_input_,
&TextInputWidget::uploadMedia,
this,
diff --git a/src/ChatPage.h b/src/ChatPage.h
index 94a5db59..b6b72319 100644
--- a/src/ChatPage.h
+++ b/src/ChatPage.h
@@ -77,6 +77,8 @@ public:
QSharedPointer<UserSettings> userSettings() { return userSettings_; }
void deleteConfigs();
+ CommunitiesList *communitiesList() { return communitiesList_; }
+
//! Calculate the width of the message timeline.
uint64_t timelineWidth();
bool isSideBarExpanded();
diff --git a/src/CommunitiesList.cpp b/src/CommunitiesList.cpp
index bb57ca40..8a938646 100644
--- a/src/CommunitiesList.cpp
+++ b/src/CommunitiesList.cpp
@@ -257,6 +257,18 @@ CommunitiesList::roomList(const QString &id) const
return {};
}
+std::vector<std::string>
+CommunitiesList::currentTags() const
+{
+ std::vector<std::string> tags;
+ for (auto &entry : communities_) {
+ CommunitiesListItem *item = entry.second.data();
+ if (item->is_tag())
+ tags.push_back(entry.first.mid(4).toStdString());
+ }
+ return tags;
+}
+
void
CommunitiesList::sortEntries()
{
diff --git a/src/CommunitiesList.h b/src/CommunitiesList.h
index d3cbeeff..63f7af07 100644
--- a/src/CommunitiesList.h
+++ b/src/CommunitiesList.h
@@ -28,6 +28,7 @@ public:
void syncTags(const std::map<QString, RoomInfo> &info);
void setTagsForRoom(const QString &id, const std::vector<std::string> &tags);
+ std::vector<std::string> currentTags() const;
signals:
void communityChanged(const QString &id);
diff --git a/src/CommunitiesListItem.cpp b/src/CommunitiesListItem.cpp
index 274271e5..c56c74a2 100644
--- a/src/CommunitiesListItem.cpp
+++ b/src/CommunitiesListItem.cpp
@@ -137,6 +137,8 @@ CommunitiesListItem::updateTooltip()
setToolTip(tr("Favourite rooms"));
else if (tag == "m.lowpriority")
setToolTip(tr("Low priority rooms"));
+ else if (tag == "m.server_notice")
+ setToolTip(tr("Server Notices", "Tag translation for m.server_notice"));
else if (tag.startsWith("u."))
setToolTip(tag.right(tag.size() - 2) + tr(" (tag)"));
else
diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp
index ee8d532d..ad774360 100644
--- a/src/RoomInfoListItem.cpp
+++ b/src/RoomInfoListItem.cpp
@@ -16,6 +16,7 @@
*/
#include <QDateTime>
+#include <QInputDialog>
#include <QMouseEvent>
#include <QPainter>
#include <QSettings>
@@ -23,7 +24,10 @@
#include "AvatarProvider.h"
#include "Cache.h"
+#include "ChatPage.h"
#include "Config.h"
+#include "Logging.h"
+#include "MatrixClient.h"
#include "RoomInfoListItem.h"
#include "Splitter.h"
#include "UserSettingsPage.h"
@@ -97,7 +101,106 @@ RoomInfoListItem::init(QWidget *parent)
menu_ = new Menu(this);
leaveRoom_ = new QAction(tr("Leave room"), this);
connect(leaveRoom_, &QAction::triggered, this, [this]() { emit leaveRoom(roomId_); });
- menu_->addAction(leaveRoom_);
+
+ connect(menu_, &QMenu::aboutToShow, this, [this]() {
+ menu_->clear();
+ menu_->addAction(leaveRoom_);
+
+ menu_->addSection(QIcon(":/icons/icons/ui/tag.png"), tr("Tag room as:"));
+
+ auto roomInfo = cache::singleRoomInfo(roomId_.toStdString());
+
+ auto tags = ChatPage::instance()->communitiesList()->currentTags();
+
+ // add default tag, remove server notice tag
+ if (std::find(tags.begin(), tags.end(), "m.favourite") == tags.end())
+ tags.push_back("m.favourite");
+ if (std::find(tags.begin(), tags.end(), "m.lowpriority") == tags.end())
+ tags.push_back("m.lowpriority");
+ if (auto it = std::find(tags.begin(), tags.end(), "m.server_notice");
+ it != tags.end())
+ tags.erase(it);
+
+ for (const auto &tag : tags) {
+ QString tagName;
+ if (tag == "m.favourite")
+ tagName = tr("Favourite", "Standard matrix tag for favourites");
+ else if (tag == "m.lowpriority")
+ tagName =
+ tr("Low Priority", "Standard matrix tag for low priority rooms");
+ else if (tag == "m.server_notice")
+ tagName =
+ tr("Server Notice", "Standard matrix tag for server notices");
+ else if ((tag.size() > 2 && tag.substr(0, 2) == "u.") ||
+ tag.find(".") !=
+ std::string::npos) // tag manager creates tags without u., which
+ // is wrong, but we still want to display them
+ tagName = QString::fromStdString(tag.substr(2));
+
+ if (tagName.isEmpty())
+ continue;
+
+ auto tagAction = menu_->addAction(tagName);
+ tagAction->setCheckable(true);
+ tagAction->setWhatsThis(tr("Adds or removes the specified tag.",
+ "WhatsThis hint for tag menu actions"));
+
+ for (const auto &riTag : roomInfo.tags)
+ if (riTag == tag) {
+ tagAction->setChecked(true);
+ break;
+ }
+
+ connect(tagAction, &QAction::triggered, this, [this, tag](bool checked) {
+ if (checked)
+ http::client()->put_tag(
+ roomId_.toStdString(),
+ tag,
+ {},
+ [tag](mtx::http::RequestErr err) {
+ if (err) {
+ nhlog::ui()->error(
+ "Failed to add tag: {}, {}",
+ tag,
+ err->matrix_error.error);
+ }
+ });
+ else
+ http::client()->delete_tag(
+ roomId_.toStdString(),
+ tag,
+ [tag](mtx::http::RequestErr err) {
+ if (err) {
+ nhlog::ui()->error(
+ "Failed to delete tag: {}, {}",
+ tag,
+ err->matrix_error.error);
+ }
+ });
+ });
+ }
+
+ auto newTagAction = menu_->addAction(tr("New tag...", "Add a new tag to the room"));
+ connect(newTagAction, &QAction::triggered, this, [this]() {
+ QString tagName =
+ QInputDialog::getText(this,
+ tr("New Tag", "Tag name prompt title"),
+ tr("Tag:", "Tag name prompt"));
+ if (tagName.isEmpty())
+ return;
+
+ std::string tag = "u." + tagName.toStdString();
+
+ http::client()->put_tag(
+ roomId_.toStdString(), tag, {}, [tag](mtx::http::RequestErr err) {
+ if (err) {
+ nhlog::ui()->error("Failed to add tag: {}, {}",
+ tag,
+ err->matrix_error.error);
+ }
+ });
+ });
+ });
}
RoomInfoListItem::RoomInfoListItem(QString room_id,
diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp
index af5c278e..3e3915bb 100644
--- a/src/TextInputWidget.cpp
+++ b/src/TextInputWidget.cpp
@@ -279,6 +279,7 @@ FilteredTextEdit::canInsertFromMimeData(const QMimeData *source) const
void
FilteredTextEdit::insertFromMimeData(const QMimeData *source)
{
+ qInfo() << "Got mime formats: \n" << source->formats();
const auto formats = source->formats().filter("/");
const auto image = formats.filter("image/", Qt::CaseInsensitive);
const auto audio = formats.filter("audio/", Qt::CaseInsensitive);
@@ -576,6 +577,8 @@ TextInputWidget::command(QString command, QString args)
sendBanRoomRequest(args.section(' ', 0, 0), args.section(' ', 1, -1));
} else if (command == "unban") {
sendUnbanRoomRequest(args.section(' ', 0, 0), args.section(' ', 1, -1));
+ } else if (command == "roomnick") {
+ changeRoomNick(args);
} else if (command == "shrug") {
sendTextMessage("¯\\_(ツ)_/¯");
} else if (command == "fliptable") {
diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h
index addb61ec..a0105eb0 100644
--- a/src/TextInputWidget.h
+++ b/src/TextInputWidget.h
@@ -167,6 +167,7 @@ signals:
void sendKickRoomRequest(const QString &userid, const QString &reason);
void sendBanRoomRequest(const QString &userid, const QString &reason);
void sendUnbanRoomRequest(const QString &userid, const QString &reason);
+ void changeRoomNick(const QString &displayname);
void startedTyping();
void stoppedTyping();
diff --git a/src/dialogs/PreviewUploadOverlay.cpp b/src/dialogs/PreviewUploadOverlay.cpp
index 42558d67..20959b0a 100644
--- a/src/dialogs/PreviewUploadOverlay.cpp
+++ b/src/dialogs/PreviewUploadOverlay.cpp
@@ -136,6 +136,11 @@ PreviewUploadOverlay::setLabels(const QString &type, const QString &mime, uint64
void
PreviewUploadOverlay::setPreview(const QImage &src, const QString &mime)
{
+ nhlog::ui()->info("Pasting image with size: {}x{}, format: {}",
+ src.height(),
+ src.width(),
+ mime.toStdString());
+
auto const &split = mime.split('/');
auto const &type = split[1];
|