From 1c9cc33902d8242ec25b4416a1662ee6c9902583 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 28 Jul 2019 12:50:10 +0200 Subject: Try to localise timestamps I'm not sure, if that is the right way, but Qt doesn't really have a way to format custom localised dates, so I tried to find the closest approximations to what we currently have. Relates to #69 --- src/dialogs/MemberList.cpp | 4 ++-- src/dialogs/ReadReceipts.cpp | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'src/dialogs') diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp index f4167143..3b957c15 100644 --- a/src/dialogs/MemberList.cpp +++ b/src/dialogs/MemberList.cpp @@ -97,7 +97,7 @@ MemberList::MemberList(const QString &room_id, QWidget *parent) topLabel_->setAlignment(Qt::AlignCenter); topLabel_->setFont(font); - auto okBtn = new QPushButton("OK", this); + auto okBtn = new QPushButton(tr("OK"), this); auto buttonLayout = new QHBoxLayout(); buttonLayout->setSpacing(15); @@ -126,7 +126,7 @@ MemberList::MemberList(const QString &room_id, QWidget *parent) qCritical() << e.what(); } - auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this); + auto closeShortcut = new QShortcut(QKeySequence("ESC"), this); connect(closeShortcut, &QShortcut::activated, this, &MemberList::close); connect(okBtn, &QPushButton::clicked, this, &MemberList::close); } diff --git a/src/dialogs/ReadReceipts.cpp b/src/dialogs/ReadReceipts.cpp index dc4145db..03ce3068 100644 --- a/src/dialogs/ReadReceipts.cpp +++ b/src/dialogs/ReadReceipts.cpp @@ -78,13 +78,15 @@ ReceiptItem::dateFormat(const QDateTime &then) const auto days = then.daysTo(now); if (days == 0) - return QString("Today %1").arg(then.toString("HH:mm")); + return tr("Today %1").arg(then.time().toString(Qt::DefaultLocaleShortDate)); else if (days < 2) - return QString("Yesterday %1").arg(then.toString("HH:mm")); - else if (days < 365) - return then.toString("dd/MM HH:mm"); + return tr("Yesterday %1").arg(then.time().toString(Qt::DefaultLocaleShortDate)); + else if (days < 7) + return QString("%1 %2") + .arg(then.toString("dddd")) + .arg(then.time().toString(Qt::DefaultLocaleShortDate)); - return then.toString("dd/MM/yy"); + return then.toString(Qt::DefaultLocaleShortDate); } ReadReceipts::ReadReceipts(QWidget *parent) -- cgit 1.5.1 From dbb8eecf292626a59b52d3c524d41f102716f235 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 28 Jul 2019 16:16:02 +0200 Subject: media->file in error message, when image upload fails --- resources/langs/nheko_de.ts | 23 ++++------------------- resources/langs/nheko_el.ts | 23 ++++------------------- resources/langs/nheko_en.ts | 23 ++++------------------- resources/langs/nheko_fi.ts | 23 ++++------------------- resources/langs/nheko_fr.ts | 23 ++++------------------- resources/langs/nheko_nl.ts | 23 ++++------------------- resources/langs/nheko_pl.ts | 27 ++++++--------------------- resources/langs/nheko_ru.ts | 27 ++++++--------------------- resources/langs/nheko_zh_CN.ts | 27 ++++++--------------------- src/dialogs/MemberList.cpp | 2 +- src/dialogs/ReadReceipts.cpp | 2 +- src/dialogs/RoomSettings.cpp | 6 +++--- src/dialogs/UserProfile.cpp | 2 +- 13 files changed, 48 insertions(+), 183 deletions(-) (limited to 'src/dialogs') diff --git a/resources/langs/nheko_de.ts b/resources/langs/nheko_de.ts index a3acae8e..1f856b80 100644 --- a/resources/langs/nheko_de.ts +++ b/resources/langs/nheko_de.ts @@ -835,16 +835,11 @@ Medien-Größe: %2 Close - - - ESC - - dialogs::ReceiptItem - + Today %1 @@ -952,12 +947,7 @@ Medien-Größe: %2 - - ESC - - - - + Failed to enable encryption: %1 @@ -973,12 +963,12 @@ Medien-Größe: %2 - The selected media is not an image + The selected file is not an image - Error while reading media: %1 + Error while reading file: %1 @@ -1015,11 +1005,6 @@ Medien-Größe: %2 Devices - - - ESC - - emoji::Panel diff --git a/resources/langs/nheko_el.ts b/resources/langs/nheko_el.ts index 462f523e..e50aadad 100644 --- a/resources/langs/nheko_el.ts +++ b/resources/langs/nheko_el.ts @@ -833,16 +833,11 @@ Media size: %2 Close - - - ESC - - dialogs::ReceiptItem - + Today %1 @@ -950,12 +945,7 @@ Media size: %2 - - ESC - - - - + Failed to enable encryption: %1 @@ -971,12 +961,12 @@ Media size: %2 - The selected media is not an image + The selected file is not an image - Error while reading media: %1 + Error while reading file: %1 @@ -1013,11 +1003,6 @@ Media size: %2 Devices - - - ESC - - emoji::Panel diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts index afd4c815..e031c4ec 100644 --- a/resources/langs/nheko_en.ts +++ b/resources/langs/nheko_en.ts @@ -833,16 +833,11 @@ Media size: %2 Close - - - ESC - - dialogs::ReceiptItem - + Today %1 @@ -950,12 +945,7 @@ Media size: %2 - - ESC - - - - + Failed to enable encryption: %1 @@ -971,12 +961,12 @@ Media size: %2 - The selected media is not an image + The selected file is not an image - Error while reading media: %1 + Error while reading file: %1 @@ -1013,11 +1003,6 @@ Media size: %2 Devices - - - ESC - - emoji::Panel diff --git a/resources/langs/nheko_fi.ts b/resources/langs/nheko_fi.ts index 789a4ebd..2baba55d 100644 --- a/resources/langs/nheko_fi.ts +++ b/resources/langs/nheko_fi.ts @@ -833,16 +833,11 @@ Media size: %2 Close - - - ESC - - dialogs::ReceiptItem - + Today %1 @@ -950,12 +945,7 @@ Media size: %2 - - ESC - - - - + Failed to enable encryption: %1 @@ -971,12 +961,12 @@ Media size: %2 - The selected media is not an image + The selected file is not an image - Error while reading media: %1 + Error while reading file: %1 @@ -1013,11 +1003,6 @@ Media size: %2 Devices - - - ESC - - emoji::Panel diff --git a/resources/langs/nheko_fr.ts b/resources/langs/nheko_fr.ts index b8c0d6d9..355c4325 100644 --- a/resources/langs/nheko_fr.ts +++ b/resources/langs/nheko_fr.ts @@ -836,16 +836,11 @@ Taille du média : %2 Close - - - ESC - - dialogs::ReceiptItem - + Today %1 @@ -953,12 +948,7 @@ Taille du média : %2 - - ESC - - - - + Failed to enable encryption: %1 @@ -974,12 +964,12 @@ Taille du média : %2 - The selected media is not an image + The selected file is not an image - Error while reading media: %1 + Error while reading file: %1 @@ -1016,11 +1006,6 @@ Taille du média : %2 Devices - - - ESC - - emoji::Panel diff --git a/resources/langs/nheko_nl.ts b/resources/langs/nheko_nl.ts index b1be0135..db56dc0f 100644 --- a/resources/langs/nheko_nl.ts +++ b/resources/langs/nheko_nl.ts @@ -835,16 +835,11 @@ Mediagrootte: %2 Close - - - ESC - - dialogs::ReceiptItem - + Today %1 @@ -952,12 +947,7 @@ Mediagrootte: %2 - - ESC - - - - + Failed to enable encryption: %1 @@ -973,12 +963,12 @@ Mediagrootte: %2 - The selected media is not an image + The selected file is not an image - Error while reading media: %1 + Error while reading file: %1 @@ -1015,11 +1005,6 @@ Mediagrootte: %2 Devices - - - ESC - - emoji::Panel diff --git a/resources/langs/nheko_pl.ts b/resources/langs/nheko_pl.ts index 2f7c903c..34a4ed26 100644 --- a/resources/langs/nheko_pl.ts +++ b/resources/langs/nheko_pl.ts @@ -835,16 +835,11 @@ Rozmiar multimediów: %2 Close - - - ESC - - dialogs::ReceiptItem - + Today %1 @@ -955,12 +950,7 @@ Rozmiar multimediów: %2 - - ESC - - - - + Failed to enable encryption: %1 Nie udało się włączyć szyfrowania: %1 @@ -976,13 +966,13 @@ Rozmiar multimediów: %2 - The selected media is not an image - Wybrany plik multimedialny nie jest obrazem + The selected file is not an image + - Error while reading media: %1 - Błąd odczytywania pliku: %1 + Error while reading file: %1 + @@ -1018,11 +1008,6 @@ Rozmiar multimediów: %2 Devices Urządzenia - - - ESC - - emoji::Panel diff --git a/resources/langs/nheko_ru.ts b/resources/langs/nheko_ru.ts index 097067db..afe36ef9 100644 --- a/resources/langs/nheko_ru.ts +++ b/resources/langs/nheko_ru.ts @@ -836,16 +836,11 @@ Media size: %2 Close Закрыть - - - ESC - - dialogs::ReceiptItem - + Today %1 @@ -954,12 +949,7 @@ Media size: %2 - - ESC - - - - + Failed to enable encryption: %1 Не удалось включить шифрование: %1 @@ -975,13 +965,13 @@ Media size: %2 - The selected media is not an image - Выбранное медия не является изображением + The selected file is not an image + - Error while reading media: %1 - Ошибка при чтении медия: %1 + Error while reading file: %1 + @@ -1017,11 +1007,6 @@ Media size: %2 Devices Устройства - - - ESC - - emoji::Panel diff --git a/resources/langs/nheko_zh_CN.ts b/resources/langs/nheko_zh_CN.ts index 2481f989..607b2ba9 100644 --- a/resources/langs/nheko_zh_CN.ts +++ b/resources/langs/nheko_zh_CN.ts @@ -835,16 +835,11 @@ Media size: %2 Close - - - ESC - - dialogs::ReceiptItem - + Today %1 @@ -953,12 +948,7 @@ Media size: %2 - - ESC - - - - + Failed to enable encryption: %1 启用加密失败:%1 @@ -974,13 +964,13 @@ Media size: %2 - The selected media is not an image - 选择的媒体不是一个图像 + The selected file is not an image + - Error while reading media: %1 - 读取媒体时失败:%1 + Error while reading file: %1 + @@ -1016,11 +1006,6 @@ Media size: %2 Devices 设备 - - - ESC - - emoji::Panel diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp index 3b957c15..88a95403 100644 --- a/src/dialogs/MemberList.cpp +++ b/src/dialogs/MemberList.cpp @@ -126,7 +126,7 @@ MemberList::MemberList(const QString &room_id, QWidget *parent) qCritical() << e.what(); } - auto closeShortcut = new QShortcut(QKeySequence("ESC"), this); + auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this); connect(closeShortcut, &QShortcut::activated, this, &MemberList::close); connect(okBtn, &QPushButton::clicked, this, &MemberList::close); } diff --git a/src/dialogs/ReadReceipts.cpp b/src/dialogs/ReadReceipts.cpp index 03ce3068..5a0d98c7 100644 --- a/src/dialogs/ReadReceipts.cpp +++ b/src/dialogs/ReadReceipts.cpp @@ -133,7 +133,7 @@ ReadReceipts::ReadReceipts(QWidget *parent) layout->addWidget(userList_); layout->addLayout(buttonLayout); - auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this); + auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this); connect(closeShortcut, &QShortcut::activated, this, &ReadReceipts::close); connect(okBtn, &QPushButton::clicked, this, &ReadReceipts::close); } diff --git a/src/dialogs/RoomSettings.cpp b/src/dialogs/RoomSettings.cpp index b2344f23..1fe5904b 100644 --- a/src/dialogs/RoomSettings.cpp +++ b/src/dialogs/RoomSettings.cpp @@ -438,7 +438,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent) resetErrorLabel(); }); - auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this); + auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this); connect(closeShortcut, &QShortcut::activated, this, &RoomSettings::close); connect(okBtn, &QPushButton::clicked, this, &RoomSettings::close); } @@ -668,12 +668,12 @@ RoomSettings::updateAvatar() QFile file{fileName, this}; if (format != "image") { - displayErrorMessage(tr("The selected media is not an image")); + displayErrorMessage(tr("The selected file is not an image")); return; } if (!file.open(QIODevice::ReadOnly)) { - displayErrorMessage(tr("Error while reading media: %1").arg(file.errorString())); + displayErrorMessage(tr("Error while reading file: %1").arg(file.errorString())); return; } diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp index b8040f9f..6aea96a8 100644 --- a/src/dialogs/UserProfile.cpp +++ b/src/dialogs/UserProfile.cpp @@ -183,7 +183,7 @@ UserProfile::UserProfile(QWidget *parent) qRegisterMetaType>(); - auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this); + auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this); connect(closeShortcut, &QShortcut::activated, this, &UserProfile::close); connect(okBtn, &QPushButton::clicked, this, &UserProfile::close); } -- cgit 1.5.1 From fd2d4d6db3c1ed93f1860260a0519c2284b97ffa Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Sun, 28 Jul 2019 23:14:10 -0400 Subject: Update mentions dialog Mentions are now separated into 'this room' and 'all rooms' tab., which allows the user to filter on the current room if they desire. Should add additional logic in the future to show which room the mention was in the for the 'all rooms' view. --- resources/langs/nheko_de.ts | 31 ++++++++++++----- resources/langs/nheko_el.ts | 31 ++++++++++++----- resources/langs/nheko_en.ts | 31 ++++++++++++----- resources/langs/nheko_fi.ts | 31 ++++++++++++----- resources/langs/nheko_fr.ts | 31 ++++++++++++----- resources/langs/nheko_nl.ts | 31 ++++++++++++----- resources/langs/nheko_pl.ts | 31 ++++++++++++----- resources/langs/nheko_ru.ts | 31 ++++++++++++----- resources/langs/nheko_zh_CN.ts | 31 ++++++++++++----- src/ChatPage.cpp | 5 ++- src/dialogs/UserMentions.cpp | 75 +++++++++++++++++++++++++++++++++--------- src/dialogs/UserMentions.h | 15 ++++++--- 12 files changed, 270 insertions(+), 104 deletions(-) (limited to 'src/dialogs') diff --git a/resources/langs/nheko_de.ts b/resources/langs/nheko_de.ts index 15497d60..b596fb67 100644 --- a/resources/langs/nheko_de.ts +++ b/resources/langs/nheko_de.ts @@ -12,7 +12,7 @@ ChatPage - + Failed to upload image. Please try again. Hochladen des Bildes fehlgeschlagen. Bitte versuche es erneut. @@ -977,6 +977,19 @@ Medien-Größe: %2 Hochladen der Bilddatei fehlgeschlagen: %s + + dialogs::UserMentions + + + This Room + + + + + All Rooms + + + dialogs::UserProfile @@ -1056,32 +1069,32 @@ Medien-Größe: %2 - + %1 an image - + %1 a file - + %1 a video clip - + %1 a sticker - + %1 a notification - + %1 an encrypted message @@ -1089,7 +1102,7 @@ Medien-Größe: %2 message-description: - + sent For when someone else is the sender @@ -1108,7 +1121,7 @@ Medien-Größe: %2 utils - + You Du diff --git a/resources/langs/nheko_el.ts b/resources/langs/nheko_el.ts index 84b76ba4..700c3d57 100644 --- a/resources/langs/nheko_el.ts +++ b/resources/langs/nheko_el.ts @@ -12,7 +12,7 @@ ChatPage - + Failed to upload image. Please try again. @@ -975,6 +975,19 @@ Media size: %2 + + dialogs::UserMentions + + + This Room + + + + + All Rooms + + + dialogs::UserProfile @@ -1054,32 +1067,32 @@ Media size: %2 - + %1 an image - + %1 a file - + %1 a video clip - + %1 a sticker - + %1 a notification - + %1 an encrypted message @@ -1087,7 +1100,7 @@ Media size: %2 message-description: - + sent For when someone else is the sender @@ -1106,7 +1119,7 @@ Media size: %2 utils - + You diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts index f44f8a73..a8329a94 100644 --- a/resources/langs/nheko_en.ts +++ b/resources/langs/nheko_en.ts @@ -12,7 +12,7 @@ ChatPage - + Failed to upload image. Please try again. Failed to upload image. Please try again. @@ -979,6 +979,19 @@ Media size: %2 Failed to upload image: %s + + dialogs::UserMentions + + + This Room + + + + + All Rooms + + + dialogs::UserProfile @@ -1058,32 +1071,32 @@ Media size: %2 %1 an audio clip - + %1 an image %1 an image - + %1 a file %1 a file - + %1 a video clip %1 a video clip - + %1 a sticker %1 a sticker - + %1 a notification %1 a notification - + %1 an encrypted message %1 an encrypted message @@ -1091,7 +1104,7 @@ Media size: %2 message-description: - + sent For when someone else is the sender sent @@ -1110,7 +1123,7 @@ Media size: %2 utils - + You You diff --git a/resources/langs/nheko_fi.ts b/resources/langs/nheko_fi.ts index 6494664a..89eb33b7 100644 --- a/resources/langs/nheko_fi.ts +++ b/resources/langs/nheko_fi.ts @@ -12,7 +12,7 @@ ChatPage - + Failed to upload image. Please try again. Kuvan lähettäminen epäonnistui. Ole hyvä ja yritä uudelleen. @@ -979,6 +979,19 @@ Median koko: %2 Kuvan lähetys epäonnistui: %s + + dialogs::UserMentions + + + This Room + + + + + All Rooms + + + dialogs::UserProfile @@ -1058,32 +1071,32 @@ Median koko: %2 - + %1 an image - + %1 a file - + %1 a video clip - + %1 a sticker - + %1 a notification - + %1 an encrypted message @@ -1091,7 +1104,7 @@ Median koko: %2 message-description: - + sent For when someone else is the sender @@ -1110,7 +1123,7 @@ Median koko: %2 utils - + You Sinä diff --git a/resources/langs/nheko_fr.ts b/resources/langs/nheko_fr.ts index 600d191c..42f82b0f 100644 --- a/resources/langs/nheko_fr.ts +++ b/resources/langs/nheko_fr.ts @@ -12,7 +12,7 @@ ChatPage - + Failed to upload image. Please try again. @@ -978,6 +978,19 @@ Taille du média : %2 + + dialogs::UserMentions + + + This Room + + + + + All Rooms + + + dialogs::UserProfile @@ -1057,32 +1070,32 @@ Taille du média : %2 - + %1 an image - + %1 a file - + %1 a video clip - + %1 a sticker - + %1 a notification - + %1 an encrypted message @@ -1090,7 +1103,7 @@ Taille du média : %2 message-description: - + sent For when someone else is the sender @@ -1109,7 +1122,7 @@ Taille du média : %2 utils - + You diff --git a/resources/langs/nheko_nl.ts b/resources/langs/nheko_nl.ts index aa1c6928..53840f82 100644 --- a/resources/langs/nheko_nl.ts +++ b/resources/langs/nheko_nl.ts @@ -12,7 +12,7 @@ ChatPage - + Failed to upload image. Please try again. @@ -977,6 +977,19 @@ Mediagrootte: %2 + + dialogs::UserMentions + + + This Room + + + + + All Rooms + + + dialogs::UserProfile @@ -1056,32 +1069,32 @@ Mediagrootte: %2 - + %1 an image - + %1 a file - + %1 a video clip - + %1 a sticker - + %1 a notification - + %1 an encrypted message @@ -1089,7 +1102,7 @@ Mediagrootte: %2 message-description: - + sent For when someone else is the sender @@ -1108,7 +1121,7 @@ Mediagrootte: %2 utils - + You diff --git a/resources/langs/nheko_pl.ts b/resources/langs/nheko_pl.ts index 4c90292f..f4f98dbb 100644 --- a/resources/langs/nheko_pl.ts +++ b/resources/langs/nheko_pl.ts @@ -12,7 +12,7 @@ ChatPage - + Failed to upload image. Please try again. Nie udało się wysłać obrazu. Spróbuj ponownie. @@ -981,6 +981,19 @@ Rozmiar multimediów: %2 Nie udało się wysłać obrazu: %s + + dialogs::UserMentions + + + This Room + + + + + All Rooms + + + dialogs::UserProfile @@ -1060,32 +1073,32 @@ Rozmiar multimediów: %2 - + %1 an image - + %1 a file - + %1 a video clip - + %1 a sticker - + %1 a notification - + %1 an encrypted message @@ -1093,7 +1106,7 @@ Rozmiar multimediów: %2 message-description: - + sent For when someone else is the sender @@ -1112,7 +1125,7 @@ Rozmiar multimediów: %2 utils - + You diff --git a/resources/langs/nheko_ru.ts b/resources/langs/nheko_ru.ts index 958e93fa..04285c72 100644 --- a/resources/langs/nheko_ru.ts +++ b/resources/langs/nheko_ru.ts @@ -12,7 +12,7 @@ ChatPage - + Failed to upload image. Please try again. Не удалось загрузить изображение. Пожалуйста, попробуйте еще раз. @@ -980,6 +980,19 @@ Media size: %2 Не удалось загрузить изображение: %s + + dialogs::UserMentions + + + This Room + + + + + All Rooms + + + dialogs::UserProfile @@ -1059,32 +1072,32 @@ Media size: %2 - + %1 an image - + %1 a file - + %1 a video clip - + %1 a sticker - + %1 a notification - + %1 an encrypted message @@ -1092,7 +1105,7 @@ Media size: %2 message-description: - + sent For when someone else is the sender @@ -1111,7 +1124,7 @@ Media size: %2 utils - + You diff --git a/resources/langs/nheko_zh_CN.ts b/resources/langs/nheko_zh_CN.ts index 8c7b2d34..1e539e64 100644 --- a/resources/langs/nheko_zh_CN.ts +++ b/resources/langs/nheko_zh_CN.ts @@ -12,7 +12,7 @@ ChatPage - + Failed to upload image. Please try again. 上传图像失败。请重试。 @@ -977,6 +977,19 @@ Media size: %2 上传图像失败:%s + + dialogs::UserMentions + + + This Room + + + + + All Rooms + + + dialogs::UserProfile @@ -1064,32 +1077,32 @@ Media size: %2 - + %1 an image - + %1 a file - + %1 a video clip - + %1 a sticker - + %1 a notification - + %1 an encrypted message @@ -1097,7 +1110,7 @@ Media size: %2 message-description: - + sent For when someone else is the sender @@ -1116,7 +1129,7 @@ Media size: %2 utils - + You diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 18188429..ca18d810 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -91,12 +91,11 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(sidebarActions_, &SideBarActions::createRoom, this, &ChatPage::createRoom); user_info_widget_ = new UserInfoWidget(sideBar_); - // user_mentions_widget_ = new UserMentionsWidget(sideBar_); + // user_mentions_widget_ = new UserMentionsWidget(top_bar_); room_list_ = new RoomList(sideBar_); connect(room_list_, &RoomList::joinRoom, this, &ChatPage::joinRoom); sideBarLayout_->addWidget(user_info_widget_); - // sideBarLayout_->addWidget(user_mentions_widget_); sideBarLayout_->addWidget(room_list_); sideBarLayout_->addWidget(sidebarActions_); @@ -1000,7 +999,7 @@ ChatPage::showNotificationsDialog(const mtx::responses::Notifications &res, cons const auto user_id = utils::event_sender(item.event); const auto body = utils::event_body(item.event); - notifDialog->pushItem(event_id, user_id, body, room_id); + notifDialog->pushItem(event_id, user_id, body, room_id, current_room_); } catch (const lmdb::error &e) { nhlog::db()->warn("error while sending desktop notification: {}", e.what()); diff --git a/src/dialogs/UserMentions.cpp b/src/dialogs/UserMentions.cpp index 8f56ec93..4cfcdaca 100644 --- a/src/dialogs/UserMentions.cpp +++ b/src/dialogs/UserMentions.cpp @@ -1,3 +1,4 @@ +#include #include #include "UserMentions.h" @@ -8,31 +9,50 @@ using namespace dialogs; UserMentions::UserMentions(QWidget *parent) : QWidget{parent} { + tab_layout_ = new QTabWidget(this); + top_layout_ = new QVBoxLayout(this); top_layout_->setSpacing(0); top_layout_->setMargin(0); - scroll_area_ = new QScrollArea(this); - scroll_area_->setWidgetResizable(true); - scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + local_scroll_area_ = new QScrollArea(this); + local_scroll_area_->setWidgetResizable(true); + local_scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + local_scroll_widget_ = new QWidget(this); + local_scroll_widget_->setObjectName("local_scroll_widget"); + + all_scroll_area_ = new QScrollArea(this); + all_scroll_area_->setWidgetResizable(true); + all_scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - scroll_widget_ = new QWidget(this); - scroll_widget_->setObjectName("scroll_widget"); + all_scroll_widget_ = new QWidget(this); + all_scroll_widget_->setObjectName("all_scroll_widget"); // Height of the typing display. QFont f; f.setPointSizeF(f.pointSizeF() * 0.9); const int bottomMargin = QFontMetrics(f).height() + 6; - scroll_layout_ = new QVBoxLayout(scroll_widget_); - scroll_layout_->setContentsMargins(4, 0, 15, bottomMargin); - scroll_layout_->setSpacing(0); - scroll_layout_->setObjectName("timelinescrollarea"); + local_scroll_layout_ = new QVBoxLayout(local_scroll_widget_); + local_scroll_layout_->setContentsMargins(4, 0, 15, bottomMargin); + local_scroll_layout_->setSpacing(0); + local_scroll_layout_->setObjectName("localcrollarea"); - scroll_area_->setWidget(scroll_widget_); - scroll_area_->setAlignment(Qt::AlignBottom); + all_scroll_layout_ = new QVBoxLayout(all_scroll_widget_); + all_scroll_layout_->setContentsMargins(4, 0, 15, bottomMargin); + all_scroll_layout_->setSpacing(0); + all_scroll_layout_->setObjectName("allcrollarea"); - top_layout_->addWidget(scroll_area_); + local_scroll_area_->setWidget(local_scroll_widget_); + local_scroll_area_->setAlignment(Qt::AlignBottom); + + all_scroll_area_->setWidget(all_scroll_widget_); + all_scroll_area_->setAlignment(Qt::AlignBottom); + + tab_layout_->addTab(local_scroll_area_, tr("This Room")); + tab_layout_->addTab(all_scroll_area_, tr("All Rooms")); + top_layout_->addWidget(tab_layout_); setLayout(top_layout_); } @@ -41,18 +61,41 @@ void UserMentions::pushItem(const QString &event_id, const QString &user_id, const QString &body, - const QString &room_id) + const QString &room_id, + const QString ¤t_room_id) { + setUpdatesEnabled(false); + + // Add to the 'all' section TimelineItem *view_item = new TimelineItem( - mtx::events::MessageType::Text, user_id, body, true, room_id, scroll_widget_); + mtx::events::MessageType::Text, user_id, body, true, room_id, all_scroll_widget_); view_item->setEventId(event_id); - setUpdatesEnabled(false); view_item->hide(); - scroll_layout_->addWidget(view_item); + all_scroll_layout_->addWidget(view_item); QTimer::singleShot(0, this, [view_item, this]() { view_item->show(); view_item->adjustSize(); setUpdatesEnabled(true); }); + + // if it matches the current room... add it to the current room as well. + if (QString::compare(room_id, current_room_id, Qt::CaseInsensitive) == 0) { + // Add to the 'local' section + TimelineItem *local_view_item = new TimelineItem(mtx::events::MessageType::Text, + user_id, + body, + true, + room_id, + local_scroll_widget_); + local_view_item->setEventId(event_id); + local_view_item->hide(); + + local_scroll_layout_->addWidget(local_view_item); + + QTimer::singleShot(0, this, [local_view_item, this]() { + local_view_item->show(); + local_view_item->adjustSize(); + }); + } } \ No newline at end of file diff --git a/src/dialogs/UserMentions.h b/src/dialogs/UserMentions.h index e995b207..9b43dcfd 100644 --- a/src/dialogs/UserMentions.h +++ b/src/dialogs/UserMentions.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -15,14 +16,20 @@ public: void pushItem(const QString &event_id, const QString &user_id, const QString &body, - const QString &room_id); + const QString &room_id, + const QString ¤t_room_id); private: + QTabWidget *tab_layout_; QVBoxLayout *top_layout_; - QVBoxLayout *scroll_layout_; + QVBoxLayout *local_scroll_layout_; + QVBoxLayout *all_scroll_layout_; - QScrollArea *scroll_area_; - QWidget *scroll_widget_; + QScrollArea *local_scroll_area_; + QWidget *local_scroll_widget_; + + QScrollArea *all_scroll_area_; + QWidget *all_scroll_widget_; }; } \ No newline at end of file -- cgit 1.5.1 From 24a649529143dbc1493260a861077217627af657 Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Mon, 29 Jul 2019 15:37:21 -0400 Subject: Fix lambda capture issue --- src/dialogs/UserMentions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/dialogs') diff --git a/src/dialogs/UserMentions.cpp b/src/dialogs/UserMentions.cpp index 4cfcdaca..f0874809 100644 --- a/src/dialogs/UserMentions.cpp +++ b/src/dialogs/UserMentions.cpp @@ -93,7 +93,7 @@ UserMentions::pushItem(const QString &event_id, local_scroll_layout_->addWidget(local_view_item); - QTimer::singleShot(0, this, [local_view_item, this]() { + QTimer::singleShot(0, this, [local_view_item]() { local_view_item->show(); local_view_item->adjustSize(); }); -- cgit 1.5.1 From 3f563e1e6e5e73b0eb50f53cc4568064a0f2f780 Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Fri, 9 Aug 2019 23:34:44 -0400 Subject: Cache User Mentions Cache user mentions when they are retrieved from the server. This logic currently isn't being utilized by the UI. Additionally, the app should use a 'since' value to only get mentions newer than those stored in the DB, to avoid excessive web requests. This will be implemented in a future commit. --- CMakeLists.txt | 6 +- src/Cache.cpp | 66 +++++++-- src/Cache.h | 20 ++- src/ChatPage.cpp | 29 ++-- src/ChatPage.h | 6 +- src/UserMentionsWidget.cpp | 309 ------------------------------------------- src/UserMentionsWidget.h | 164 ----------------------- src/dialogs/UserMentions.cpp | 101 -------------- src/dialogs/UserMentions.h | 35 ----- src/popups/UserMentions.cpp | 108 +++++++++++++++ src/popups/UserMentions.h | 40 ++++++ 11 files changed, 246 insertions(+), 638 deletions(-) delete mode 100644 src/UserMentionsWidget.cpp delete mode 100644 src/UserMentionsWidget.h delete mode 100644 src/dialogs/UserMentions.cpp delete mode 100644 src/dialogs/UserMentions.h create mode 100644 src/popups/UserMentions.cpp create mode 100644 src/popups/UserMentions.h (limited to 'src/dialogs') diff --git a/CMakeLists.txt b/CMakeLists.txt index 09eea071..4d5aff7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,7 +179,6 @@ set(SRC_FILES src/dialogs/LeaveRoom.cpp src/dialogs/Logout.cpp src/dialogs/UserProfile.cpp - src/dialogs/UserMentions.cpp src/dialogs/ReadReceipts.cpp src/dialogs/ReCaptcha.cpp src/dialogs/RoomSettings.cpp @@ -241,13 +240,13 @@ set(SRC_FILES src/popups/SuggestionsPopup.cpp src/popups/PopupItem.cpp src/popups/ReplyPopup.cpp + src/popups/UserMentions.cpp src/TextInputWidget.cpp src/TopRoomBar.cpp src/TrayIcon.cpp src/TypingDisplay.cpp src/Utils.cpp src/UserInfoWidget.cpp - src/UserMentionsWidget.cpp src/UserSettingsPage.cpp src/WelcomePage.cpp src/main.cpp @@ -321,7 +320,6 @@ qt5_wrap_cpp(MOC_HEADERS src/dialogs/MemberList.h src/dialogs/LeaveRoom.h src/dialogs/Logout.h - src/dialogs/UserMentions.h src/dialogs/UserProfile.h src/dialogs/RawMessage.h src/dialogs/ReadReceipts.h @@ -383,12 +381,12 @@ qt5_wrap_cpp(MOC_HEADERS src/popups/SuggestionsPopup.h src/popups/ReplyPopup.h src/popups/PopupItem.h + src/popups/UserMentions.h src/TextInputWidget.h src/TopRoomBar.h src/TrayIcon.h src/TypingDisplay.h src/UserInfoWidget.h - src/UserMentionsWidget.h src/UserSettingsPage.h src/WelcomePage.h ) diff --git a/src/Cache.cpp b/src/Cache.cpp index 9bf3b5b0..5ccf9291 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1232,6 +1232,28 @@ Cache::roomMessages() return msgs; } +std::map +Cache::getTimelineMentions() +{ + // TODO: Should be read-only, but getMentionsDb will attempt to create a DB + // if it doesn't exist, throwing an error. + auto txn = lmdb::txn::begin(env_, nullptr); + + std::map notifs; + + auto room_ids = getRoomIds(txn); + + for (const auto &room_id : room_ids) { + auto roomNotifs = getTimelineMentionsForRoom(txn, room_id); + notifs.emplace(QString::fromStdString(room_id), roomNotifs); + } + + txn.commit(); + + return notifs; +} + + mtx::responses::Timeline Cache::getTimelineMessages(lmdb::txn &txn, const std::string &room_id) { @@ -1934,11 +1956,16 @@ Cache::saveTimelineMessages(lmdb::txn &txn, lmdb::val(obj.dump())); } } + mtx::responses::Notifications -Cache::getTimelineMentions(lmdb::txn &txn, const std::string &room_id) +Cache::getTimelineMentionsForRoom(lmdb::txn &txn, const std::string &room_id) { auto db = getMentionsDb(txn, room_id); + if (db.size(txn) == 0) { + return mtx::responses::Notifications{}; + } + mtx::responses::Notifications notif; std::string event_id, msg; @@ -1961,29 +1988,52 @@ Cache::getTimelineMentions(lmdb::txn &txn, const std::string &room_id) return notif; } + +//! Add all notifications containing a user mention to the db. +void +Cache::saveTimelineMentions(const mtx::responses::Notifications &res) +{ + QMap> notifsByRoom; + + // Sort into room-specific 'buckets' + for (const auto ¬if : res.notifications) { + notifsByRoom[notif.room_id].push_back(notif); + } + + auto txn = lmdb::txn::begin(env_); + // Insert the entire set of mentions for each room at a time. + for (const auto &room : notifsByRoom.keys()) { + nhlog::db()->debug("Storing notifications for " + room); + saveTimelineMentions(txn, room, notifsByRoom[room]); + } + + txn.commit(); +} + void Cache::saveTimelineMentions(lmdb::txn &txn, const std::string &room_id, - const mtx::responses::Notifications &res) + const QList &res) { auto db = getMentionsDb(txn, room_id); using namespace mtx::events; using namespace mtx::events::state; - for (const auto &n : res.notifications) { - const auto event_id = utils::event_id(n.event); + int i = 0; + for (const auto ¬if : res) { + nhlog::db()->debug("Storing notification " + std::to_string(i++) + " for room " + room_id); + const auto event_id = utils::event_id(notif.event); // double check that we have the correct room_id... - if (room_id.compare(n.room_id) != 0) - continue; + if (room_id.compare(notif.room_id) != 0) { + return; + } json obj = json::object(); lmdb::dbi_put(txn, db, lmdb::val(event_id), lmdb::val(obj.dump())); } - - txn.commit(); } void diff --git a/src/Cache.h b/src/Cache.h index 5971df66..07ccf790 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -323,6 +323,8 @@ public: std::map roomMessages(); + std::map getTimelineMentions(); + //! Retrieve all the user ids from a room. std::vector roomMembers(const std::string &room_id); @@ -402,13 +404,8 @@ public: //! Check if we have sent a desktop notification for the given event id. bool isNotificationSent(const std::string &event_id); - //! Add a notification containing a user mention to the db. - void saveTimelineMentions(lmdb::txn &txn, - const std::string &room_id, - const mtx::responses::Notifications &res); - //! Get timeline items that a user was mentions in - mtx::responses::Notifications getTimelineMentions(lmdb::txn &txn, - const std::string &room_id); + //! Add all notifications containing a user mention to the db. + void saveTimelineMentions(const mtx::responses::Notifications &res); //! Remove old unused data. void deleteOldMessages(); @@ -478,6 +475,15 @@ private: lmdb::dbi &membersdb, const mtx::responses::InvitedRoom &room); + //! Add a notification containing a user mention to the db. + void saveTimelineMentions(lmdb::txn &txn, + const std::string &room_id, + const QList &res); + + //! Get timeline items that a user was mentions in for a given room + mtx::responses::Notifications getTimelineMentionsForRoom(lmdb::txn &txn, + const std::string &room_id); + QString getInviteRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); QString getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb); QString getInviteRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index ca18d810..2a02e740 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -35,7 +35,6 @@ #include "TopRoomBar.h" #include "TypingDisplay.h" #include "UserInfoWidget.h" -#include "UserMentionsWidget.h" #include "UserSettingsPage.h" #include "Utils.h" #include "ui/OverlayModal.h" @@ -44,7 +43,7 @@ #include "notifications/Manager.h" #include "dialogs/ReadReceipts.h" -#include "dialogs/UserMentions.h" +#include "popups/UserMentions.h" #include "timeline/TimelineViewManager.h" // TODO: Needs to be updated with an actual secret. @@ -91,7 +90,7 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(sidebarActions_, &SideBarActions::createRoom, this, &ChatPage::createRoom); user_info_widget_ = new UserInfoWidget(sideBar_); - // user_mentions_widget_ = new UserMentionsWidget(top_bar_); + user_mentions_popup_ = new popups::UserMentions(); room_list_ = new RoomList(sideBar_); connect(room_list_, &RoomList::joinRoom, this, &ChatPage::joinRoom); @@ -518,8 +517,17 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(this, &ChatPage::leftRoom, this, &ChatPage::removeRoom); connect(this, &ChatPage::notificationsRetrieved, this, &ChatPage::sendDesktopNotifications); - connect( - this, &ChatPage::highlightedNotifsRetrieved, this, &ChatPage::showNotificationsDialog); + connect(this, + &ChatPage::highlightedNotifsRetrieved, + this, + [this](const mtx::responses::Notifications ¬if, const QPoint &widgetPos) { + try { + cache::client()->saveTimelineMentions(notif); + } catch (const lmdb::error &e) { + nhlog::db()->error("failed to save mentions: {}", e.what()); + } + showNotificationsDialog(notif, widgetPos); + }); connect(communitiesList_, &CommunitiesList::communityChanged, @@ -558,6 +566,10 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) &ChatPage::initializeEmptyViews, view_manager_, &TimelineViewManager::initWithMessages); + connect(this, + &ChatPage::initializeMentions, + user_mentions_popup_, + &popups::UserMentions::initializeMentions); connect(this, &ChatPage::syncUI, this, [this](const mtx::responses::Rooms &rooms) { try { room_list_->cleanupInvites(cache::client()->invites()); @@ -830,6 +842,7 @@ ChatPage::loadStateFromCache() emit initializeEmptyViews(cache::client()->roomMessages()); emit initializeRoomList(cache::client()->roomInfo()); + emit initializeMentions(cache::client()->getTimelineMentions()); emit syncTags(cache::client()->roomInfo().toStdMap()); cache::client()->calculateRoomReadStatus(); @@ -988,9 +1001,7 @@ ChatPage::sendDesktopNotifications(const mtx::responses::Notifications &res) void ChatPage::showNotificationsDialog(const mtx::responses::Notifications &res, const QPoint &widgetPos) { - // TODO: This should NOT BE A DIALOG. Make the TimelineView support - // creating a timeline view from notifications (similarly to how it can show history views) - auto notifDialog = new dialogs::UserMentions(); + auto notifDialog = user_mentions_popup_; for (const auto &item : res.notifications) { const auto event_id = QString::fromStdString(utils::event_id(item.event)); @@ -1242,6 +1253,8 @@ ChatPage::sendTypingNotifications() void ChatPage::initialSyncHandler(const mtx::responses::Sync &res, mtx::http::RequestErr err) { + // TODO: Initial Sync should include mentions as well... + if (err) { const auto error = QString::fromStdString(err->matrix_error.error); const auto msg = tr("Please try to login again: %1").arg(error); diff --git a/src/ChatPage.h b/src/ChatPage.h index 3c97ba25..87876a09 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -33,6 +34,7 @@ #include "MatrixClient.h" #include "Utils.h" #include "notifications/Manager.h" +#include "popups/UserMentions.h" class OverlayModal; class QuickSwitcher; @@ -44,7 +46,6 @@ class TimelineViewManager; class TopRoomBar; class TypingDisplay; class UserInfoWidget; -class UserMentionsWidget; class UserSettings; class NotificationsManager; @@ -139,6 +140,7 @@ signals: void initializeRoomList(QMap); void initializeViews(const mtx::responses::Rooms &rooms); void initializeEmptyViews(const std::map &msgs); + void initializeMentions(const std::map ¬ifs); void syncUI(const mtx::responses::Rooms &rooms); void syncRoomlist(const std::map &updates); void syncTags(const std::map &updates); @@ -242,7 +244,7 @@ private: UserInfoWidget *user_info_widget_; - UserMentionsWidget *user_mentions_widget_; + popups::UserMentions *user_mentions_popup_; // Keeps track of the users currently typing on each room. std::map> typingUsers_; diff --git a/src/UserMentionsWidget.cpp b/src/UserMentionsWidget.cpp deleted file mode 100644 index a28db930..00000000 --- a/src/UserMentionsWidget.cpp +++ /dev/null @@ -1,309 +0,0 @@ -#include -#include -#include -#include -#include - -#include "MainWindow.h" -#include "UserMentionsWidget.h" -#include "Utils.h" -#include "ui/Ripple.h" -#include "ui/RippleOverlay.h" - -constexpr int MaxUnreadCountDisplayed = 99; - -struct WMetrics -{ - int maxHeight; - int iconSize; - int padding; - int unit; - - int unreadLineWidth; - int unreadLineOffset; - - int inviteBtnX; - int inviteBtnY; -}; - -WMetrics -getWMetrics(const QFont &font) -{ - WMetrics m; - - const int height = QFontMetrics(font).lineSpacing(); - - m.unit = height; - m.maxHeight = std::ceil((double)height * 3.8); - m.iconSize = std::ceil((double)height * 2.8); - m.padding = std::ceil((double)height / 2.0); - m.unreadLineWidth = m.padding - m.padding / 3; - m.unreadLineOffset = m.padding - m.padding / 4; - - m.inviteBtnX = m.iconSize + 2 * m.padding; - m.inviteBtnX = m.iconSize / 2.0 + m.padding + m.padding / 3.0; - - return m; -} - -UserMentionsWidget::UserMentionsWidget(QWidget *parent) - : QWidget(parent) - , isPressed_(false) - , unreadMsgCount_(0) -{ - init(parent); - - QFont f; - f.setPointSizeF(f.pointSizeF()); - - const int fontHeight = QFontMetrics(f).height(); - const int widgetMargin = fontHeight / 3; - const int contentHeight = fontHeight * 3; - - setFixedHeight(contentHeight + widgetMargin); - - topLayout_ = new QHBoxLayout(this); - topLayout_->setSpacing(0); - topLayout_->setMargin(widgetMargin); -} - -void -UserMentionsWidget::init(QWidget *parent) -{ - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - setMouseTracking(true); - setAttribute(Qt::WA_Hover); - - setFixedHeight(getWMetrics(QFont{}).maxHeight); - - QPainterPath path; - path.addRect(0, 0, parent->width(), height()); - - ripple_overlay_ = new RippleOverlay(this); - ripple_overlay_->setClipPath(path); - ripple_overlay_->setClipping(true); - - unreadCountFont_.setPointSizeF(unreadCountFont_.pointSizeF() * 0.8); - unreadCountFont_.setBold(true); - - bubbleDiameter_ = QFontMetrics(unreadCountFont_).averageCharWidth() * 3; -} - -// void -// UserMentionsWidget::resizeEvent(QResizeEvent *event) -// { -// Q_UNUSED(event); - -// const auto sz = utils::calculateSidebarSizes(QFont{}); - -// if (width() <= sz.small) { -// topLayout_->setContentsMargins(0, 0, logoutButtonSize_, 0); - -// } else { -// topLayout_->setMargin(5); -// } - -// QWidget::resizeEvent(event); -// } - -void -UserMentionsWidget::setPressedState(bool state) -{ - if (isPressed_ != state) { - isPressed_ = state; - update(); - } -} - -void -UserMentionsWidget::resizeEvent(QResizeEvent *) -{ - // Update ripple's clipping path. - QPainterPath path; - path.addRect(0, 0, width(), height()); - - const auto sidebarSizes = utils::calculateSidebarSizes(QFont{}); - - if (width() > sidebarSizes.small) - setToolTip(""); - else - setToolTip(""); - - ripple_overlay_->setClipPath(path); - ripple_overlay_->setClipping(true); -} - -void -UserMentionsWidget::mousePressEvent(QMouseEvent *event) -{ - if (event->buttons() == Qt::RightButton) { - QWidget::mousePressEvent(event); - return; - } - - emit clicked(); - - setPressedState(true); - - // Ripple on mouse position by default. - QPoint pos = event->pos(); - qreal radiusEndValue = static_cast(width()) / 3; - - Ripple *ripple = new Ripple(pos); - - ripple->setRadiusEndValue(radiusEndValue); - ripple->setOpacityStartValue(0.15); - ripple->setColor(QColor("white")); - ripple->radiusAnimation()->setDuration(200); - ripple->opacityAnimation()->setDuration(400); - - ripple_overlay_->addRipple(ripple); -} - -void -UserMentionsWidget::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter p(this); - p.setRenderHint(QPainter::TextAntialiasing); - p.setRenderHint(QPainter::SmoothPixmapTransform); - p.setRenderHint(QPainter::Antialiasing); - - auto wm = getWMetrics(QFont{}); - - QPen titlePen(titleColor_); - QPen subtitlePen(subtitleColor_); - - QFontMetrics metrics(QFont{}); - - if (isPressed_) { - p.fillRect(rect(), highlightedBackgroundColor_); - titlePen.setColor(highlightedTitleColor_); - subtitlePen.setColor(highlightedSubtitleColor_); - } else if (underMouse()) { - p.fillRect(rect(), hoverBackgroundColor_); - titlePen.setColor(hoverTitleColor_); - subtitlePen.setColor(hoverSubtitleColor_); - } else { - p.fillRect(rect(), backgroundColor_); - titlePen.setColor(titleColor_); - subtitlePen.setColor(subtitleColor_); - } - - // Description line with the default font. - int bottom_y = wm.maxHeight - wm.padding - metrics.ascent() / 2; - - const auto sidebarSizes = utils::calculateSidebarSizes(QFont{}); - - if (width() > sidebarSizes.small) { - QFont headingFont; - headingFont.setWeight(QFont::Medium); - p.setFont(headingFont); - p.setPen(titlePen); - - QFont tsFont; - tsFont.setPointSizeF(tsFont.pointSizeF() * 0.9); -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - const int msgStampWidth = QFontMetrics(tsFont).width("timestamp") + 4; -#else - const int msgStampWidth = QFontMetrics(tsFont).horizontalAdvance("timestamp") + 4; -#endif - // We use the full width of the widget if there is no unread msg bubble. - // const int bottomLineWidthLimit = (unreadMsgCount_ > 0) ? msgStampWidth : 0; - - // Name line. - QFontMetrics fontNameMetrics(headingFont); - int top_y = 2 * wm.padding + fontNameMetrics.ascent() / 2; - - const auto name = metrics.elidedText( - "Mentions", - Qt::ElideRight, - (width() - wm.iconSize - 2 * wm.padding - msgStampWidth) * 0.8); - p.drawText(QPoint(2 * wm.padding + wm.iconSize, top_y), name); - - p.setFont(QFont{}); - p.setPen(subtitlePen); - - // The limit is the space between the end of the avatar and the start of the - // timestamp. - int usernameLimit = - std::max(0, width() - 3 * wm.padding - msgStampWidth - wm.iconSize - 20); - auto userName = - metrics.elidedText("Show Mentioned Messages", Qt::ElideRight, usernameLimit); - - p.setFont(QFont{}); - p.drawText(QPoint(2 * wm.padding + wm.iconSize, bottom_y), userName); - - // We show the last message timestamp. - p.save(); - if (isPressed_) { - p.setPen(QPen(highlightedTimestampColor_)); - } else if (underMouse()) { - p.setPen(QPen(hoverTimestampColor_)); - } else { - p.setPen(QPen(timestampColor_)); - } - - // p.setFont(tsFont); - // p.drawText(QPoint(width() - wm.padding - msgStampWidth, top_y), "timestamp"); - p.restore(); - } - - p.setPen(Qt::NoPen); - - if (unreadMsgCount_ > 0) { - QBrush brush; - brush.setStyle(Qt::SolidPattern); - - brush.setColor(mentionedColor()); - - if (isPressed_) - brush.setColor(bubbleFgColor()); - - p.setBrush(brush); - p.setPen(Qt::NoPen); - p.setFont(unreadCountFont_); - - // Extra space on the x-axis to accomodate the extra character space - // inside the bubble. - const int x_width = unreadMsgCount_ > MaxUnreadCountDisplayed - ? QFontMetrics(p.font()).averageCharWidth() - : 0; - - QRectF r(width() - bubbleDiameter_ - wm.padding - x_width, - bottom_y - bubbleDiameter_ / 2 - 5, - bubbleDiameter_ + x_width, - bubbleDiameter_); - - if (width() == sidebarSizes.small) - r = QRectF(width() - bubbleDiameter_ - 5, - height() - bubbleDiameter_ - 5, - bubbleDiameter_ + x_width, - bubbleDiameter_); - - p.setPen(Qt::NoPen); - p.drawEllipse(r); - - p.setPen(QPen(bubbleFgColor())); - - if (isPressed_) - p.setPen(QPen(bubbleBgColor())); - - auto countTxt = unreadMsgCount_ > MaxUnreadCountDisplayed - ? QString("99+") - : QString::number(unreadMsgCount_); - - p.setBrush(Qt::NoBrush); - p.drawText(r.translated(0, -0.5), Qt::AlignCenter, countTxt); - } - - if (!isPressed_ && hasUnreadMessages_) { - QPen pen; - pen.setWidth(wm.unreadLineWidth); - pen.setColor(highlightedBackgroundColor_); - - p.setPen(pen); - p.drawLine(0, wm.unreadLineOffset, 0, height() - wm.unreadLineOffset); - } -} \ No newline at end of file diff --git a/src/UserMentionsWidget.h b/src/UserMentionsWidget.h deleted file mode 100644 index 179f0026..00000000 --- a/src/UserMentionsWidget.h +++ /dev/null @@ -1,164 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -class FlatButton; -class RippleOverlay; - -class UserMentionsWidget : public QWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) - - Q_PROPERTY(QColor highlightedBackgroundColor READ highlightedBackgroundColor WRITE - setHighlightedBackgroundColor) - Q_PROPERTY( - QColor hoverBackgroundColor READ hoverBackgroundColor WRITE setHoverBackgroundColor) - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) - - Q_PROPERTY(QColor avatarBgColor READ avatarBgColor WRITE setAvatarBgColor) - Q_PROPERTY(QColor avatarFgColor READ avatarFgColor WRITE setAvatarFgColor) - - Q_PROPERTY(QColor bubbleBgColor READ bubbleBgColor WRITE setBubbleBgColor) - Q_PROPERTY(QColor bubbleFgColor READ bubbleFgColor WRITE setBubbleFgColor) - - Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor) - Q_PROPERTY(QColor subtitleColor READ subtitleColor WRITE setSubtitleColor) - - Q_PROPERTY(QColor timestampColor READ timestampColor WRITE setTimestampColor) - Q_PROPERTY(QColor highlightedTimestampColor READ highlightedTimestampColor WRITE - setHighlightedTimestampColor) - Q_PROPERTY(QColor hoverTimestampColor READ hoverTimestampColor WRITE setHoverTimestampColor) - - Q_PROPERTY( - QColor highlightedTitleColor READ highlightedTitleColor WRITE setHighlightedTitleColor) - Q_PROPERTY(QColor highlightedSubtitleColor READ highlightedSubtitleColor WRITE - setHighlightedSubtitleColor) - - Q_PROPERTY(QColor hoverTitleColor READ hoverTitleColor WRITE setHoverTitleColor) - Q_PROPERTY(QColor hoverSubtitleColor READ hoverSubtitleColor WRITE setHoverSubtitleColor) - - Q_PROPERTY(QColor mentionedColor READ mentionedColor WRITE setMentionedColor) - Q_PROPERTY(QColor btnColor READ btnColor WRITE setBtnColor) - Q_PROPERTY(QColor btnTextColor READ btnTextColor WRITE setBtnTextColor) - -public: - UserMentionsWidget(QWidget *parent = 0); - - void updateUnreadMessageCount(int count); - void clearUnreadMessageCount() { updateUnreadMessageCount(0); }; - bool isPressed() const { return isPressed_; } - int unreadMessageCount() const { return unreadMsgCount_; } - QColor borderColor() const { return borderColor_; } - void setBorderColor(QColor &color) { borderColor_ = color; } - QColor highlightedBackgroundColor() const { return highlightedBackgroundColor_; } - QColor hoverBackgroundColor() const { return hoverBackgroundColor_; } - QColor hoverTitleColor() const { return hoverTitleColor_; } - QColor hoverSubtitleColor() const { return hoverSubtitleColor_; } - QColor hoverTimestampColor() const { return hoverTimestampColor_; } - QColor backgroundColor() const { return backgroundColor_; } - QColor avatarBgColor() const { return avatarBgColor_; } - QColor avatarFgColor() const { return avatarFgColor_; } - - QColor highlightedTitleColor() const { return highlightedTitleColor_; } - QColor highlightedSubtitleColor() const { return highlightedSubtitleColor_; } - QColor highlightedTimestampColor() const { return highlightedTimestampColor_; } - - QColor titleColor() const { return titleColor_; } - QColor subtitleColor() const { return subtitleColor_; } - QColor timestampColor() const { return timestampColor_; } - QColor btnColor() const { return btnColor_; } - QColor btnTextColor() const { return btnTextColor_; } - - QColor bubbleFgColor() const { return bubbleFgColor_; } - QColor bubbleBgColor() const { return bubbleBgColor_; } - QColor mentionedColor() const { return mentionedFontColor_; } - - void setHighlightedBackgroundColor(QColor &color) { highlightedBackgroundColor_ = color; } - void setHoverBackgroundColor(QColor &color) { hoverBackgroundColor_ = color; } - void setHoverSubtitleColor(QColor &color) { hoverSubtitleColor_ = color; } - void setHoverTitleColor(QColor &color) { hoverTitleColor_ = color; } - void setHoverTimestampColor(QColor &color) { hoverTimestampColor_ = color; } - void setBackgroundColor(QColor &color) { backgroundColor_ = color; } - void setTimestampColor(QColor &color) { timestampColor_ = color; } - void setAvatarFgColor(QColor &color) { avatarFgColor_ = color; } - void setAvatarBgColor(QColor &color) { avatarBgColor_ = color; } - - void setHighlightedTitleColor(QColor &color) { highlightedTitleColor_ = color; } - void setHighlightedSubtitleColor(QColor &color) { highlightedSubtitleColor_ = color; } - void setHighlightedTimestampColor(QColor &color) { highlightedTimestampColor_ = color; } - - void setTitleColor(QColor &color) { titleColor_ = color; } - void setSubtitleColor(QColor &color) { subtitleColor_ = color; } - - void setBtnColor(QColor &color) { btnColor_ = color; } - void setBtnTextColor(QColor &color) { btnTextColor_ = color; } - - void setBubbleFgColor(QColor &color) { bubbleFgColor_ = color; } - void setBubbleBgColor(QColor &color) { bubbleBgColor_ = color; } - void setMentionedColor(QColor &color) { mentionedFontColor_ = color; } - -signals: - void clicked(); - -public slots: - void setPressedState(bool state); - -protected: - void mousePressEvent(QMouseEvent *event) override; - void paintEvent(QPaintEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - -private: - void init(QWidget *parent); - - RippleOverlay *ripple_overlay_; - - bool isPressed_ = false; - - bool hasUnreadMessages_ = true; - - int unreadMsgCount_ = 0; - - QHBoxLayout *topLayout_; - - QColor borderColor_; - QColor highlightedBackgroundColor_; - QColor hoverBackgroundColor_; - QColor backgroundColor_; - - QColor highlightedTitleColor_; - QColor highlightedSubtitleColor_; - - QColor titleColor_; - QColor subtitleColor_; - - QColor hoverTitleColor_; - QColor hoverSubtitleColor_; - - QColor btnColor_; - QColor btnTextColor_; - - QRectF acceptBtnRegion_; - QRectF declineBtnRegion_; - - // Fonts - QColor mentionedFontColor_; - QFont unreadCountFont_; - int bubbleDiameter_; - - QColor timestampColor_; - QColor highlightedTimestampColor_; - QColor hoverTimestampColor_; - - QColor avatarBgColor_; - QColor avatarFgColor_; - - QColor bubbleBgColor_; - QColor bubbleFgColor_; -}; \ No newline at end of file diff --git a/src/dialogs/UserMentions.cpp b/src/dialogs/UserMentions.cpp deleted file mode 100644 index f0874809..00000000 --- a/src/dialogs/UserMentions.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include - -#include "UserMentions.h" -#include "timeline/TimelineItem.h" - -using namespace dialogs; - -UserMentions::UserMentions(QWidget *parent) - : QWidget{parent} -{ - tab_layout_ = new QTabWidget(this); - - top_layout_ = new QVBoxLayout(this); - top_layout_->setSpacing(0); - top_layout_->setMargin(0); - - local_scroll_area_ = new QScrollArea(this); - local_scroll_area_->setWidgetResizable(true); - local_scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - local_scroll_widget_ = new QWidget(this); - local_scroll_widget_->setObjectName("local_scroll_widget"); - - all_scroll_area_ = new QScrollArea(this); - all_scroll_area_->setWidgetResizable(true); - all_scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - all_scroll_widget_ = new QWidget(this); - all_scroll_widget_->setObjectName("all_scroll_widget"); - - // Height of the typing display. - QFont f; - f.setPointSizeF(f.pointSizeF() * 0.9); - const int bottomMargin = QFontMetrics(f).height() + 6; - - local_scroll_layout_ = new QVBoxLayout(local_scroll_widget_); - local_scroll_layout_->setContentsMargins(4, 0, 15, bottomMargin); - local_scroll_layout_->setSpacing(0); - local_scroll_layout_->setObjectName("localcrollarea"); - - all_scroll_layout_ = new QVBoxLayout(all_scroll_widget_); - all_scroll_layout_->setContentsMargins(4, 0, 15, bottomMargin); - all_scroll_layout_->setSpacing(0); - all_scroll_layout_->setObjectName("allcrollarea"); - - local_scroll_area_->setWidget(local_scroll_widget_); - local_scroll_area_->setAlignment(Qt::AlignBottom); - - all_scroll_area_->setWidget(all_scroll_widget_); - all_scroll_area_->setAlignment(Qt::AlignBottom); - - tab_layout_->addTab(local_scroll_area_, tr("This Room")); - tab_layout_->addTab(all_scroll_area_, tr("All Rooms")); - top_layout_->addWidget(tab_layout_); - - setLayout(top_layout_); -} - -void -UserMentions::pushItem(const QString &event_id, - const QString &user_id, - const QString &body, - const QString &room_id, - const QString ¤t_room_id) -{ - setUpdatesEnabled(false); - - // Add to the 'all' section - TimelineItem *view_item = new TimelineItem( - mtx::events::MessageType::Text, user_id, body, true, room_id, all_scroll_widget_); - view_item->setEventId(event_id); - view_item->hide(); - - all_scroll_layout_->addWidget(view_item); - QTimer::singleShot(0, this, [view_item, this]() { - view_item->show(); - view_item->adjustSize(); - setUpdatesEnabled(true); - }); - - // if it matches the current room... add it to the current room as well. - if (QString::compare(room_id, current_room_id, Qt::CaseInsensitive) == 0) { - // Add to the 'local' section - TimelineItem *local_view_item = new TimelineItem(mtx::events::MessageType::Text, - user_id, - body, - true, - room_id, - local_scroll_widget_); - local_view_item->setEventId(event_id); - local_view_item->hide(); - - local_scroll_layout_->addWidget(local_view_item); - - QTimer::singleShot(0, this, [local_view_item]() { - local_view_item->show(); - local_view_item->adjustSize(); - }); - } -} \ No newline at end of file diff --git a/src/dialogs/UserMentions.h b/src/dialogs/UserMentions.h deleted file mode 100644 index 9b43dcfd..00000000 --- a/src/dialogs/UserMentions.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace dialogs { - -class UserMentions : public QWidget -{ - Q_OBJECT -public: - UserMentions(QWidget *parent = nullptr); - void pushItem(const QString &event_id, - const QString &user_id, - const QString &body, - const QString &room_id, - const QString ¤t_room_id); - -private: - QTabWidget *tab_layout_; - QVBoxLayout *top_layout_; - QVBoxLayout *local_scroll_layout_; - QVBoxLayout *all_scroll_layout_; - - QScrollArea *local_scroll_area_; - QWidget *local_scroll_widget_; - - QScrollArea *all_scroll_area_; - QWidget *all_scroll_widget_; -}; - -} \ No newline at end of file diff --git a/src/popups/UserMentions.cpp b/src/popups/UserMentions.cpp new file mode 100644 index 00000000..77e5260e --- /dev/null +++ b/src/popups/UserMentions.cpp @@ -0,0 +1,108 @@ +#include +#include + +#include "UserMentions.h" +#include "timeline/TimelineItem.h" + +using namespace popups; + +UserMentions::UserMentions(QWidget *parent) + : QWidget{parent} +{ + tab_layout_ = new QTabWidget(this); + + top_layout_ = new QVBoxLayout(this); + top_layout_->setSpacing(0); + top_layout_->setMargin(0); + + local_scroll_area_ = new QScrollArea(this); + local_scroll_area_->setWidgetResizable(true); + local_scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + local_scroll_widget_ = new QWidget(this); + local_scroll_widget_->setObjectName("local_scroll_widget"); + + all_scroll_area_ = new QScrollArea(this); + all_scroll_area_->setWidgetResizable(true); + all_scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + all_scroll_widget_ = new QWidget(this); + all_scroll_widget_->setObjectName("all_scroll_widget"); + + // Height of the typing display. + QFont f; + f.setPointSizeF(f.pointSizeF() * 0.9); + const int bottomMargin = QFontMetrics(f).height() + 6; + + local_scroll_layout_ = new QVBoxLayout(local_scroll_widget_); + local_scroll_layout_->setContentsMargins(4, 0, 15, bottomMargin); + local_scroll_layout_->setSpacing(0); + local_scroll_layout_->setObjectName("localcrollarea"); + + all_scroll_layout_ = new QVBoxLayout(all_scroll_widget_); + all_scroll_layout_->setContentsMargins(4, 0, 15, bottomMargin); + all_scroll_layout_->setSpacing(0); + all_scroll_layout_->setObjectName("allcrollarea"); + + local_scroll_area_->setWidget(local_scroll_widget_); + local_scroll_area_->setAlignment(Qt::AlignBottom); + + all_scroll_area_->setWidget(all_scroll_widget_); + all_scroll_area_->setAlignment(Qt::AlignBottom); + + tab_layout_->addTab(local_scroll_area_, tr("This Room")); + tab_layout_->addTab(all_scroll_area_, tr("All Rooms")); + top_layout_->addWidget(tab_layout_); + + setLayout(top_layout_); +} + +void +UserMentions::initializeMentions(const std::map ¬ifs) +{ + Q_UNUSED(notifs); + // Very TODO: +} + +void +UserMentions::pushItem(const QString &event_id, + const QString &user_id, + const QString &body, + const QString &room_id, + const QString ¤t_room_id) +{ + setUpdatesEnabled(false); + + // Add to the 'all' section + TimelineItem *view_item = new TimelineItem( + mtx::events::MessageType::Text, user_id, body, true, room_id, all_scroll_widget_); + view_item->setEventId(event_id); + view_item->hide(); + + all_scroll_layout_->addWidget(view_item); + QTimer::singleShot(0, this, [view_item, this]() { + view_item->show(); + view_item->adjustSize(); + setUpdatesEnabled(true); + }); + + // if it matches the current room... add it to the current room as well. + if (QString::compare(room_id, current_room_id, Qt::CaseInsensitive) == 0) { + // Add to the 'local' section + TimelineItem *local_view_item = new TimelineItem(mtx::events::MessageType::Text, + user_id, + body, + true, + room_id, + local_scroll_widget_); + local_view_item->setEventId(event_id); + local_view_item->hide(); + + local_scroll_layout_->addWidget(local_view_item); + + QTimer::singleShot(0, this, [local_view_item]() { + local_view_item->show(); + local_view_item->adjustSize(); + }); + } +} \ No newline at end of file diff --git a/src/popups/UserMentions.h b/src/popups/UserMentions.h new file mode 100644 index 00000000..5dc475bf --- /dev/null +++ b/src/popups/UserMentions.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +namespace popups { + +class UserMentions : public QWidget +{ + Q_OBJECT +public: + UserMentions(QWidget *parent = nullptr); + void pushItem(const QString &event_id, + const QString &user_id, + const QString &body, + const QString &room_id, + const QString ¤t_room_id); + + void initializeMentions(const std::map ¬ifs); + +private: + QTabWidget *tab_layout_; + QVBoxLayout *top_layout_; + QVBoxLayout *local_scroll_layout_; + QVBoxLayout *all_scroll_layout_; + + QScrollArea *local_scroll_area_; + QWidget *local_scroll_widget_; + + QScrollArea *all_scroll_area_; + QWidget *all_scroll_widget_; +}; + +} \ No newline at end of file -- cgit 1.5.1 From 52056a79fa94117ce0fc8f388458ceb48cc3be54 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 26 Aug 2019 01:24:56 +0200 Subject: Try to reduce memory usage by reusing avatar pixmaps --- src/AvatarProvider.cpp | 55 +++++++++++++++++++++++++++++++------ src/AvatarProvider.h | 12 ++++++-- src/Cache.cpp | 5 +--- src/Cache.h | 1 - src/ChatPage.cpp | 38 +++---------------------- src/ChatPage.h | 4 +-- src/Logging.cpp | 2 ++ src/Logging.h | 2 ++ src/RoomInfoListItem.cpp | 9 ++++-- src/RoomInfoListItem.h | 2 +- src/RoomList.cpp | 39 ++------------------------ src/RoomList.h | 6 ++-- src/TopRoomBar.cpp | 5 ++-- src/TopRoomBar.h | 2 +- src/UserInfoWidget.cpp | 19 ++++++------- src/UserInfoWidget.h | 2 +- src/dialogs/MemberList.cpp | 12 ++------ src/dialogs/ReadReceipts.cpp | 8 ++---- src/dialogs/RoomSettings.cpp | 17 ++++++------ src/dialogs/RoomSettings.h | 4 +-- src/dialogs/UserProfile.cpp | 6 ++-- src/popups/PopupItem.cpp | 26 ++++-------------- src/timeline/.TimelineItem.cpp.swp | Bin 0 -> 114688 bytes src/timeline/TimelineItem.cpp | 22 ++++++--------- src/timeline/TimelineItem.h | 8 ++---- src/ui/Avatar.cpp | 39 ++++++++++++-------------- src/ui/Avatar.h | 10 ++++--- 27 files changed, 148 insertions(+), 207 deletions(-) create mode 100644 src/timeline/.TimelineItem.cpp.swp (limited to 'src/dialogs') diff --git a/src/AvatarProvider.cpp b/src/AvatarProvider.cpp index 57b61c75..277a4030 100644 --- a/src/AvatarProvider.cpp +++ b/src/AvatarProvider.cpp @@ -16,30 +16,44 @@ */ #include +#include #include +#include #include "AvatarProvider.h" #include "Cache.h" #include "Logging.h" #include "MatrixClient.h" -namespace AvatarProvider { +static QPixmapCache avatar_cache; +namespace AvatarProvider { void -resolve(const QString &room_id, const QString &user_id, QObject *receiver, AvatarCallback callback) +resolve(const QString &avatarUrl, int size, QObject *receiver, AvatarCallback callback) { - const auto key = QString("%1 %2").arg(room_id).arg(user_id); - const auto avatarUrl = Cache::avatarUrl(room_id, user_id); + avatar_cache.setCacheLimit(1024 * 1024); - if (!Cache::AvatarUrls.contains(key) || !cache::client()) + const auto cacheKey = avatarUrl + "_size_" + size; + + if (!cache::client()) return; if (avatarUrl.isEmpty()) return; + QPixmap pixmap; + if (avatar_cache.find(cacheKey, pixmap)) { + nhlog::net()->info("cached pixmap {}", avatarUrl.toStdString()); + callback(pixmap); + return; + } + auto data = cache::client()->image(avatarUrl); if (!data.isNull()) { - callback(QImage::fromData(data)); + pixmap.loadFromData(data); + avatar_cache.insert(cacheKey, pixmap); + nhlog::net()->info("loaded pixmap from disk cache {}", avatarUrl.toStdString()); + callback(pixmap); return; } @@ -47,7 +61,12 @@ resolve(const QString &room_id, const QString &user_id, QObject *receiver, Avata QObject::connect(proxy.get(), &AvatarProxy::avatarDownloaded, receiver, - [callback](const QByteArray &data) { callback(QImage::fromData(data)); }); + [callback, cacheKey](const QByteArray &data) { + QPixmap pm; + pm.loadFromData(data); + avatar_cache.insert(cacheKey, pm); + callback(pm); + }); mtx::http::ThumbOpts opts; opts.width = 256; @@ -67,8 +86,26 @@ resolve(const QString &room_id, const QString &user_id, QObject *receiver, Avata cache::client()->saveImage(opts.mxc_url, res); - auto data = QByteArray(res.data(), res.size()); - emit proxy->avatarDownloaded(data); + nhlog::net()->info("downloaded pixmap {}", opts.mxc_url); + + emit proxy->avatarDownloaded(QByteArray(res.data(), res.size())); }); } + +void +resolve(const QString &room_id, + const QString &user_id, + int size, + QObject *receiver, + AvatarCallback callback) +{ + const auto key = QString("%1 %2").arg(room_id).arg(user_id); + const auto avatarUrl = Cache::avatarUrl(room_id, user_id); + const auto cacheKey = avatarUrl + "_size_" + size; + + if (!Cache::AvatarUrls.contains(key) || !cache::client()) + return; + + resolve(avatarUrl, size, receiver, callback); +} } diff --git a/src/AvatarProvider.h b/src/AvatarProvider.h index 4b4e15e9..47ed028e 100644 --- a/src/AvatarProvider.h +++ b/src/AvatarProvider.h @@ -17,7 +17,7 @@ #pragma once -#include +#include #include class AvatarProxy : public QObject @@ -28,9 +28,15 @@ signals: void avatarDownloaded(const QByteArray &data); }; -using AvatarCallback = std::function; +using AvatarCallback = std::function; namespace AvatarProvider { void -resolve(const QString &room_id, const QString &user_id, QObject *receiver, AvatarCallback cb); +resolve(const QString &avatarUrl, int size, QObject *receiver, AvatarCallback cb); +void +resolve(const QString &room_id, + const QString &user_id, + int size, + QObject *receiver, + AvatarCallback cb); } diff --git a/src/Cache.cpp b/src/Cache.cpp index ef0f951e..083dbe89 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1830,10 +1830,7 @@ Cache::searchRooms(const std::string &query, std::uint8_t max_items) std::vector results; for (auto it = items.begin(); it != end; it++) { - results.push_back( - RoomSearchResult{it->second.first, - it->second.second, - QImage::fromData(image(txn, it->second.second.avatar_url))}); + results.push_back(RoomSearchResult{it->second.first, it->second.second}); } txn.commit(); diff --git a/src/Cache.h b/src/Cache.h index 302bb65b..0da49793 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -153,7 +153,6 @@ struct RoomSearchResult { std::string room_id; RoomInfo info; - QImage img; }; Q_DECLARE_METATYPE(RoomSearchResult) diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 2ed64b6b..21ded4b3 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -774,12 +774,12 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) } void -ChatPage::updateTopBarAvatar(const QString &roomid, const QPixmap &img) +ChatPage::updateTopBarAvatar(const QString &roomid, const QString &img) { if (current_room_ != roomid) return; - top_bar_->updateRoomAvatar(img.toImage()); + top_bar_->updateRoomAvatar(img); } void @@ -807,7 +807,7 @@ ChatPage::changeTopRoomInfo(const QString &room_id) if (img.isNull()) top_bar_->updateRoomAvatarFromName(name); else - top_bar_->updateRoomAvatar(img); + top_bar_->updateRoomAvatar(avatar_url); } catch (const lmdb::error &e) { nhlog::ui()->error("failed to change top bar room info: {}", e.what()); @@ -1337,37 +1337,7 @@ ChatPage::getProfileInfo() emit setUserDisplayName(QString::fromStdString(res.display_name)); - if (cache::client()) { - auto data = cache::client()->image(res.avatar_url); - if (!data.isNull()) { - emit setUserAvatar(QImage::fromData(data)); - return; - } - } - - if (res.avatar_url.empty()) - return; - - http::client()->download( - res.avatar_url, - [this, res](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn( - "failed to download user avatar: {} - {}", - mtx::errors::to_string(err->matrix_error.errcode), - err->matrix_error.error); - return; - } - - if (cache::client()) - cache::client()->saveImage(res.avatar_url, data); - - emit setUserAvatar( - QImage::fromData(QByteArray(data.data(), data.size()))); - }); + emit setUserAvatar(QString::fromStdString(res.avatar_url)); }); http::client()->joined_groups( diff --git a/src/ChatPage.h b/src/ChatPage.h index 189af387..e41ae1ae 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -129,7 +129,7 @@ signals: void ownProfileOk(); void setUserDisplayName(const QString &name); - void setUserAvatar(const QImage &avatar); + void setUserAvatar(const QString &avatar); void loggedOut(); void trySyncCb(); @@ -159,7 +159,7 @@ signals: private slots: void showUnreadMessageNotification(int count); - void updateTopBarAvatar(const QString &roomid, const QPixmap &img); + void updateTopBarAvatar(const QString &roomid, const QString &img); void changeTopRoomInfo(const QString &room_id); void logout(); void removeRoom(const QString &room_id); diff --git a/src/Logging.cpp b/src/Logging.cpp index 686274d8..32287582 100644 --- a/src/Logging.cpp +++ b/src/Logging.cpp @@ -16,6 +16,8 @@ constexpr auto MAX_LOG_FILES = 3; } namespace nhlog { +bool enable_debug_log_from_commandline = false; + void init(const std::string &file_path) { diff --git a/src/Logging.h b/src/Logging.h index 2feae60d..e54f3c3f 100644 --- a/src/Logging.h +++ b/src/Logging.h @@ -18,4 +18,6 @@ db(); std::shared_ptr crypto(); + +extern bool enable_debug_log_from_commandline; } diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp index 9bcce134..dbcd6806 100644 --- a/src/RoomInfoListItem.cpp +++ b/src/RoomInfoListItem.cpp @@ -21,6 +21,7 @@ #include #include +#include "AvatarProvider.h" #include "Cache.h" #include "Config.h" #include "RoomInfoListItem.h" @@ -434,10 +435,12 @@ RoomInfoListItem::mousePressEvent(QMouseEvent *event) } void -RoomInfoListItem::setAvatar(const QImage &img) +RoomInfoListItem::setAvatar(const QString &avatar_url) { - roomAvatar_ = utils::scaleImageToPixmap(img, IconSize); - update(); + AvatarProvider::resolve(avatar_url, IconSize, this, [this](const QPixmap &img) { + roomAvatar_ = img; + update(); + }); } void diff --git a/src/RoomInfoListItem.h b/src/RoomInfoListItem.h index 40c938c1..54e02a76 100644 --- a/src/RoomInfoListItem.h +++ b/src/RoomInfoListItem.h @@ -73,7 +73,7 @@ public: bool isPressed() const { return isPressed_; } int unreadMessageCount() const { return unreadMsgCount_; } - void setAvatar(const QImage &avatar_image); + void setAvatar(const QString &avatar_url); void setDescriptionMessage(const DescInfo &info); DescInfo lastMessageInfo() const { return lastMsgInfo_; } diff --git a/src/RoomList.cpp b/src/RoomList.cpp index 1abf3533..c5e05621 100644 --- a/src/RoomList.cpp +++ b/src/RoomList.cpp @@ -89,40 +89,7 @@ RoomList::updateAvatar(const QString &room_id, const QString &url) if (url.isEmpty()) return; - QByteArray savedImgData; - - if (cache::client()) - savedImgData = cache::client()->image(url); - - if (savedImgData.isEmpty()) { - mtx::http::ThumbOpts opts; - opts.mxc_url = url.toStdString(); - http::client()->get_thumbnail( - opts, [room_id, opts, this](const std::string &res, mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn( - "failed to download room avatar: {} {} {}", - opts.mxc_url, - mtx::errors::to_string(err->matrix_error.errcode), - err->matrix_error.error); - return; - } - - if (cache::client()) - cache::client()->saveImage(opts.mxc_url, res); - - auto data = QByteArray(res.data(), res.size()); - QPixmap pixmap; - pixmap.loadFromData(data); - - emit updateRoomAvatarCb(room_id, pixmap); - }); - } else { - QPixmap img; - img.loadFromData(savedImgData); - - updateRoomAvatar(room_id, img); - } + emit updateRoomAvatarCb(room_id, url); } void @@ -252,7 +219,7 @@ RoomList::highlightSelectedRoom(const QString &room_id) } void -RoomList::updateRoomAvatar(const QString &roomid, const QPixmap &img) +RoomList::updateRoomAvatar(const QString &roomid, const QString &img) { if (!roomExists(roomid)) { nhlog::ui()->warn("avatar update on non-existent room_id: {}", @@ -260,7 +227,7 @@ RoomList::updateRoomAvatar(const QString &roomid, const QPixmap &img) return; } - rooms_[roomid]->setAvatar(img.toImage()); + rooms_[roomid]->setAvatar(img); // Used to inform other widgets for the new image data. emit roomAvatarChanged(roomid, img); diff --git a/src/RoomList.h b/src/RoomList.h index 155a969c..95fc0d9b 100644 --- a/src/RoomList.h +++ b/src/RoomList.h @@ -61,12 +61,12 @@ signals: void totalUnreadMessageCountUpdated(int count); void acceptInvite(const QString &room_id); void declineInvite(const QString &room_id); - void roomAvatarChanged(const QString &room_id, const QPixmap &img); + void roomAvatarChanged(const QString &room_id, const QString &img); void joinRoom(const QString &room_id); - void updateRoomAvatarCb(const QString &room_id, const QPixmap &img); + void updateRoomAvatarCb(const QString &room_id, const QString &img); public slots: - void updateRoomAvatar(const QString &roomid, const QPixmap &img); + void updateRoomAvatar(const QString &roomid, const QString &img); void highlightSelectedRoom(const QString &room_id); void updateUnreadMessageCount(const QString &roomid, int count, int highlightedCount); void updateRoomDescription(const QString &roomid, const DescInfo &info); diff --git a/src/TopRoomBar.cpp b/src/TopRoomBar.cpp index a8049e3a..712fe9aa 100644 --- a/src/TopRoomBar.cpp +++ b/src/TopRoomBar.cpp @@ -46,9 +46,8 @@ TopRoomBar::TopRoomBar(QWidget *parent) topLayout_->setContentsMargins( 2 * widgetMargin, widgetMargin, 2 * widgetMargin, widgetMargin); - avatar_ = new Avatar(this); + avatar_ = new Avatar(this, fontHeight * 2); avatar_->setLetter(""); - avatar_->setSize(fontHeight * 2); textLayout_ = new QVBoxLayout(); textLayout_->setSpacing(0); @@ -183,7 +182,7 @@ TopRoomBar::reset() } void -TopRoomBar::updateRoomAvatar(const QImage &avatar_image) +TopRoomBar::updateRoomAvatar(const QString &avatar_image) { avatar_->setImage(avatar_image); update(); diff --git a/src/TopRoomBar.h b/src/TopRoomBar.h index 5f2c936e..3243064e 100644 --- a/src/TopRoomBar.h +++ b/src/TopRoomBar.h @@ -44,7 +44,7 @@ class TopRoomBar : public QWidget public: TopRoomBar(QWidget *parent = 0); - void updateRoomAvatar(const QImage &avatar_image); + void updateRoomAvatar(const QString &avatar_image); void updateRoomAvatar(const QIcon &icon); void updateRoomName(const QString &name); void updateRoomTopic(QString topic); diff --git a/src/UserInfoWidget.cpp b/src/UserInfoWidget.cpp index 5345fb2a..19d7478e 100644 --- a/src/UserInfoWidget.cpp +++ b/src/UserInfoWidget.cpp @@ -52,10 +52,9 @@ UserInfoWidget::UserInfoWidget(QWidget *parent) textLayout_->setSpacing(widgetMargin / 2); textLayout_->setContentsMargins(widgetMargin * 2, widgetMargin, widgetMargin, widgetMargin); - userAvatar_ = new Avatar(this); + userAvatar_ = new Avatar(this, fontHeight * 2.5); userAvatar_->setObjectName("userAvatar"); userAvatar_->setLetter(QChar('?')); - userAvatar_->setSize(fontHeight * 2.5); QFont nameFont; nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1); @@ -134,14 +133,6 @@ UserInfoWidget::reset() userAvatar_->setLetter(QChar('?')); } -void -UserInfoWidget::setAvatar(const QImage &img) -{ - avatar_image_ = img; - userAvatar_->setImage(img); - update(); -} - void UserInfoWidget::setDisplayName(const QString &name) { @@ -160,6 +151,14 @@ UserInfoWidget::setUserId(const QString &userid) { user_id_ = userid; userIdLabel_->setText(userid); + update(); +} + +void +UserInfoWidget::setAvatar(const QString &url) +{ + userAvatar_->setImage(url); + update(); } void diff --git a/src/UserInfoWidget.h b/src/UserInfoWidget.h index 65de7be9..263dd0c2 100644 --- a/src/UserInfoWidget.h +++ b/src/UserInfoWidget.h @@ -33,9 +33,9 @@ class UserInfoWidget : public QWidget public: UserInfoWidget(QWidget *parent = 0); - void setAvatar(const QImage &img); void setDisplayName(const QString &name); void setUserId(const QString &userid); + void setAvatar(const QString &url); void reset(); diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp index 88a95403..9e973efa 100644 --- a/src/dialogs/MemberList.cpp +++ b/src/dialogs/MemberList.cpp @@ -9,7 +9,6 @@ #include "dialogs/MemberList.h" -#include "AvatarProvider.h" #include "Cache.h" #include "ChatPage.h" #include "Config.h" @@ -28,17 +27,10 @@ MemberItem::MemberItem(const RoomMember &member, QWidget *parent) textLayout_->setMargin(0); textLayout_->setSpacing(0); - avatar_ = new Avatar(this); - avatar_->setSize(44); + avatar_ = new Avatar(this, 44); avatar_->setLetter(utils::firstChar(member.display_name)); - if (!member.avatar.isNull()) - avatar_->setImage(member.avatar); - else - AvatarProvider::resolve(ChatPage::instance()->currentRoom(), - member.user_id, - this, - [this](const QImage &img) { avatar_->setImage(img); }); + avatar_->setImage(ChatPage::instance()->currentRoom(), member.user_id); QFont nameFont; nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1); diff --git a/src/dialogs/ReadReceipts.cpp b/src/dialogs/ReadReceipts.cpp index 5a0d98c7..58ad59c3 100644 --- a/src/dialogs/ReadReceipts.cpp +++ b/src/dialogs/ReadReceipts.cpp @@ -37,8 +37,7 @@ ReceiptItem::ReceiptItem(QWidget *parent, auto displayName = Cache::displayName(room_id, user_id); - avatar_ = new Avatar(this); - avatar_->setSize(44); + avatar_ = new Avatar(this, 44); avatar_->setLetter(utils::firstChar(displayName)); // If it's a matrix id we use the second letter. @@ -56,10 +55,7 @@ ReceiptItem::ReceiptItem(QWidget *parent, topLayout_->addWidget(avatar_); topLayout_->addLayout(textLayout_, 1); - AvatarProvider::resolve(ChatPage::instance()->currentRoom(), - user_id, - this, - [this](const QImage &img) { avatar_->setImage(img); }); + avatar_->setImage(ChatPage::instance()->currentRoom(), user_id); } void diff --git a/src/dialogs/RoomSettings.cpp b/src/dialogs/RoomSettings.cpp index 1fe5904b..00b034cc 100644 --- a/src/dialogs/RoomSettings.cpp +++ b/src/dialogs/RoomSettings.cpp @@ -350,12 +350,12 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent) keyRequestsToggle_->hide(); } - avatar_ = new Avatar(this); - avatar_->setSize(128); + avatar_ = new Avatar(this, 128); if (avatarImg_.isNull()) avatar_->setLetter(utils::firstChar(QString::fromStdString(info_.name))); else - avatar_->setImage(avatarImg_); + avatar_->setImage(room_id_, + QString::fromStdString(http::client()->user_id().to_string())); if (canChangeAvatar(room_id_.toStdString(), utils::localUser().toStdString())) { auto filter = new ClickableFilter(this); @@ -487,7 +487,7 @@ RoomSettings::retrieveRoomInfo() try { usesEncryption_ = cache::client()->isRoomEncrypted(room_id_.toStdString()); info_ = cache::client()->singleRoomInfo(room_id_.toStdString()); - setAvatar(QImage::fromData(cache::client()->image(info_.avatar_url))); + setAvatar(); } catch (const lmdb::error &e) { nhlog::db()->warn("failed to retrieve room info from cache: {}", room_id_.toStdString()); @@ -633,14 +633,13 @@ RoomSettings::displayErrorMessage(const QString &msg) } void -RoomSettings::setAvatar(const QImage &img) +RoomSettings::setAvatar() { stopLoadingSpinner(); - avatarImg_ = img; - if (avatar_) - avatar_->setImage(img); + avatar_->setImage(room_id_, + QString::fromStdString(http::client()->user_id().to_string())); } void @@ -733,7 +732,7 @@ RoomSettings::updateAvatar() return; } - emit proxy->avatarChanged(QImage::fromData(content)); + emit proxy->avatarChanged(); }); }); } diff --git a/src/dialogs/RoomSettings.h b/src/dialogs/RoomSettings.h index 6667b68b..e1807ba1 100644 --- a/src/dialogs/RoomSettings.h +++ b/src/dialogs/RoomSettings.h @@ -52,7 +52,7 @@ class ThreadProxy : public QObject signals: void error(const QString &msg); - void avatarChanged(const QImage &img); + void avatarChanged(); void nameEventSent(const QString &); void topicEventSent(); }; @@ -140,7 +140,7 @@ private: void resetErrorLabel(); void displayErrorMessage(const QString &msg); - void setAvatar(const QImage &img); + void setAvatar(); void setupEditButton(); //! Retrieve the current room information from cache. void retrieveRoomInfo(); diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp index 6aea96a8..5ad3afa2 100644 --- a/src/dialogs/UserProfile.cpp +++ b/src/dialogs/UserProfile.cpp @@ -114,9 +114,8 @@ UserProfile::UserProfile(QWidget *parent) btnLayout->setSpacing(8); btnLayout->setMargin(0); - avatar_ = new Avatar(this); + avatar_ = new Avatar(this, 128); avatar_->setLetter("X"); - avatar_->setSize(128); QFont font; font.setPointSizeF(font.pointSizeF() * 2); @@ -210,8 +209,7 @@ UserProfile::init(const QString &userId, const QString &roomId) displayNameLabel_->setText(displayName); avatar_->setLetter(utils::firstChar(displayName)); - AvatarProvider::resolve( - roomId, userId, this, [this](const QImage &img) { avatar_->setImage(img); }); + avatar_->setImage(roomId, userId); auto localUser = utils::localUser(); diff --git a/src/popups/PopupItem.cpp b/src/popups/PopupItem.cpp index f905983a..c4d4327f 100644 --- a/src/popups/PopupItem.cpp +++ b/src/popups/PopupItem.cpp @@ -11,7 +11,7 @@ constexpr int PopupItemMargin = 3; PopupItem::PopupItem(QWidget *parent) : QWidget(parent) - , avatar_{new Avatar(this)} + , avatar_{new Avatar(this, conf::popup::avatar)} , hovering_{false} { setMouseTracking(true); @@ -40,7 +40,6 @@ UserItem::UserItem(QWidget *parent) : PopupItem(parent) { userName_ = new QLabel("Placeholder", this); - avatar_->setSize(conf::popup::avatar); avatar_->setLetter("P"); topLayout_->addWidget(avatar_); topLayout_->addWidget(userName_, 1); @@ -52,7 +51,6 @@ UserItem::UserItem(QWidget *parent, const QString &user_id) { auto displayName = Cache::displayName(ChatPage::instance()->currentRoom(), userId_); - avatar_->setSize(conf::popup::avatar); avatar_->setLetter(utils::firstChar(displayName)); // If it's a matrix id we use the second letter. @@ -87,16 +85,7 @@ UserItem::updateItem(const QString &user_id) void UserItem::resolveAvatar(const QString &user_id) { - AvatarProvider::resolve( - ChatPage::instance()->currentRoom(), userId_, this, [this, user_id](const QImage &img) { - // The user on the widget when the avatar is resolved, - // might be different from the user that made the call. - if (user_id == userId_) - avatar_->setImage(img); - else - // We try to resolve the avatar again. - resolveAvatar(userId_); - }); + avatar_->setImage(ChatPage::instance()->currentRoom(), user_id); } void @@ -116,7 +105,6 @@ RoomItem::RoomItem(QWidget *parent, const RoomSearchResult &res) auto name = QFontMetrics(QFont()).elidedText( QString::fromStdString(res.info.name), Qt::ElideRight, parentWidget()->width() - 10); - avatar_->setSize(conf::popup::avatar + 6); avatar_->setLetter(utils::firstChar(name)); roomName_ = new QLabel(name, this); @@ -125,8 +113,7 @@ RoomItem::RoomItem(QWidget *parent, const RoomSearchResult &res) topLayout_->addWidget(avatar_); topLayout_->addWidget(roomName_, 1); - if (!res.img.isNull()) - avatar_->setImage(res.img); + avatar_->setImage(QString::fromStdString(res.info.avatar_url)); } void @@ -141,10 +128,7 @@ RoomItem::updateItem(const RoomSearchResult &result) roomName_->setText(name); - if (!result.img.isNull()) - avatar_->setImage(result.img); - else - avatar_->setLetter(utils::firstChar(name)); + avatar_->setImage(QString::fromStdString(result.info.avatar_url)); } void @@ -154,4 +138,4 @@ RoomItem::mousePressEvent(QMouseEvent *event) emit clicked(selectedText()); QWidget::mousePressEvent(event); -} \ No newline at end of file +} diff --git a/src/timeline/.TimelineItem.cpp.swp b/src/timeline/.TimelineItem.cpp.swp new file mode 100644 index 00000000..75e03aeb Binary files /dev/null and b/src/timeline/.TimelineItem.cpp.swp differ diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp index dd3b48c3..7916bd80 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp @@ -326,8 +326,7 @@ TimelineItem::TimelineItem(mtx::events::MessageType ty, generateBody(userid, displayName, formatted_body); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, userid, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(userid); } else { generateBody(formatted_body); setupSimpleLayout(); @@ -509,8 +508,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent generateBody(sender, displayName, formatted_body); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, sender, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(sender); } else { generateBody(formatted_body); setupSimpleLayout(); @@ -607,8 +604,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent generateBody(sender, displayName, formatted_body); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, sender, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(sender); } else { generateBody(formatted_body); setupSimpleLayout(); @@ -793,9 +789,8 @@ TimelineItem::setupAvatarLayout(const QString &userName) QFont f; f.setPointSizeF(f.pointSizeF()); - userAvatar_ = new Avatar(this); + userAvatar_ = new Avatar(this, QFontMetrics(f).height() * 2); userAvatar_->setLetter(QChar(userName[0]).toUpper()); - userAvatar_->setSize(QFontMetrics(f).height() * 2); // TODO: The provided user name should be a UserId class if (userName[0] == '@' && userName.size() > 1) @@ -822,12 +817,12 @@ TimelineItem::setupSimpleLayout() } void -TimelineItem::setUserAvatar(const QImage &avatar) +TimelineItem::setUserAvatar(const QString &userid) { if (userAvatar_ == nullptr) return; - userAvatar_->setImage(avatar); + userAvatar_->setImage(room_id_, userid); } void @@ -911,8 +906,7 @@ TimelineItem::addAvatar() setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, userid, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(userid); } void diff --git a/src/timeline/TimelineItem.h b/src/timeline/TimelineItem.h index fe354000..356976e5 100644 --- a/src/timeline/TimelineItem.h +++ b/src/timeline/TimelineItem.h @@ -215,7 +215,7 @@ public: void setBackgroundColor(const QColor &color) { backgroundColor_ = color; } QColor backgroundColor() const { return backgroundColor_; } - void setUserAvatar(const QImage &pixmap); + void setUserAvatar(const QString &userid); DescInfo descriptionMessage() const { return descriptionMsg_; } QString eventId() const { return event_id_; } void setEventId(const QString &event_id) { event_id_ = event_id; } @@ -336,8 +336,7 @@ TimelineItem::setupLocalWidgetLayout(Widget *widget, const QString &userid, bool generateBody(userid, displayName, ""); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, userid, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(userid); } else { setupSimpleLayout(); } @@ -381,8 +380,7 @@ TimelineItem::setupWidgetLayout(Widget *widget, const Event &event, bool withSen generateBody(sender, displayName, ""); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, sender, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(sender); } else { setupSimpleLayout(); } diff --git a/src/ui/Avatar.cpp b/src/ui/Avatar.cpp index 4b4cd272..98bf21c6 100644 --- a/src/ui/Avatar.cpp +++ b/src/ui/Avatar.cpp @@ -1,12 +1,13 @@ #include +#include "AvatarProvider.h" #include "Utils.h" #include "ui/Avatar.h" -Avatar::Avatar(QWidget *parent) +Avatar::Avatar(QWidget *parent, int size) : QWidget(parent) + , size_(size) { - size_ = ui::AvatarSize; type_ = ui::AvatarType::Letter; letter_ = "A"; @@ -61,35 +62,31 @@ Avatar::setBackgroundColor(const QColor &color) } void -Avatar::setSize(int size) +Avatar::setLetter(const QString &letter) { - size_ = size; - - if (!image_.isNull()) - pixmap_ = utils::scaleImageToPixmap(image_, size_); - - QFont _font(font()); - _font.setPointSizeF(size_ * (ui::FontSize) / 40); - - setFont(_font); + letter_ = letter; + type_ = ui::AvatarType::Letter; update(); } void -Avatar::setLetter(const QString &letter) +Avatar::setImage(const QString &avatar_url) { - letter_ = letter; - type_ = ui::AvatarType::Letter; - update(); + AvatarProvider::resolve(avatar_url, size_, this, [this](QPixmap pm) { + type_ = ui::AvatarType::Image; + pixmap_ = pm; + update(); + }); } void -Avatar::setImage(const QImage &image) +Avatar::setImage(const QString &room, const QString &user) { - image_ = image; - type_ = ui::AvatarType::Image; - pixmap_ = utils::scaleImageToPixmap(image_, size_); - update(); + AvatarProvider::resolve(room, user, size_, this, [this](QPixmap pm) { + type_ = ui::AvatarType::Image; + pixmap_ = pm; + update(); + }); } void diff --git a/src/ui/Avatar.h b/src/ui/Avatar.h index 41967af5..b9225dd1 100644 --- a/src/ui/Avatar.h +++ b/src/ui/Avatar.h @@ -15,13 +15,14 @@ class Avatar : public QWidget Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) public: - explicit Avatar(QWidget *parent = 0); + explicit Avatar(QWidget *parent = 0, int size = ui::AvatarSize); void setBackgroundColor(const QColor &color); void setIcon(const QIcon &icon); - void setImage(const QImage &image); + void setImage(const QString &avatar_url); + void setImage(const QString &room, const QString &user); void setLetter(const QString &letter); - void setSize(int size); + // void setSize(int size); void setTextColor(const QColor &color); QColor backgroundColor() const; @@ -41,7 +42,8 @@ private: QColor background_color_; QColor text_color_; QIcon icon_; - QImage image_; QPixmap pixmap_; + const std::string room; + const std::string user; int size_; }; -- cgit 1.5.1