// SPDX-FileCopyrightText: 2021 Nheko Contributors // // SPDX-License-Identifier: GPL-3.0-or-later #include #include #include #include #include #include #include #include #include #include #include "dialogs/ReadReceipts.h" #include "AvatarProvider.h" #include "Cache.h" #include "ChatPage.h" #include "Config.h" #include "Utils.h" #include "ui/Avatar.h" using namespace dialogs; ReceiptItem::ReceiptItem(QWidget *parent, const QString &user_id, uint64_t timestamp, const QString &room_id) : QWidget(parent) { topLayout_ = new QHBoxLayout(this); topLayout_->setMargin(0); textLayout_ = new QVBoxLayout; textLayout_->setMargin(0); textLayout_->setSpacing(conf::modals::TEXT_SPACING); QFont nameFont; nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1); auto displayName = cache::displayName(room_id, user_id); avatar_ = new Avatar(this, 44); avatar_->setLetter(utils::firstChar(displayName)); // If it's a matrix id we use the second letter. if (displayName.size() > 1 && displayName.at(0) == '@') avatar_->setLetter(QChar(displayName.at(1))); userName_ = new QLabel(displayName, this); userName_->setFont(nameFont); timestamp_ = new QLabel(dateFormat(QDateTime::fromMSecsSinceEpoch(timestamp)), this); textLayout_->addWidget(userName_); textLayout_->addWidget(timestamp_); topLayout_->addWidget(avatar_); topLayout_->addLayout(textLayout_, 1); avatar_->setImage(ChatPage::instance()->currentRoom(), user_id); } void ReceiptItem::paintEvent(QPaintEvent *) { QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } QString ReceiptItem::dateFormat(const QDateTime &then) const { auto now = QDateTime::currentDateTime(); auto days = then.daysTo(now); if (days == 0) return tr("Today %1") .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); else if (days < 2) return tr("Yesterday %1") .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); else if (days < 7) return QString("%1 %2") .arg(then.toString("dddd")) .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); return QLocale::system().toString(then.time(), QLocale::ShortFormat); } ReadReceipts::ReadReceipts(QWidget *parent) : QFrame(parent) { setAutoFillBackground(true); setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); setWindowModality(Qt::WindowModal); setAttribute(Qt::WA_DeleteOnClose, true); auto layout = new QVBoxLayout(this); layout->setSpacing(conf::modals::WIDGET_SPACING); layout->setMargin(conf::modals::WIDGET_MARGIN); userList_ = new QListWidget; userList_->setFrameStyle(QFrame::NoFrame); userList_->setSelectionMode(QAbstractItemView::NoSelection); userList_->setSpacing(conf::modals::TEXT_SPACING); QFont largeFont; largeFont.setPointSizeF(largeFont.pointSizeF() * 1.5); setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); setMinimumHeight(userList_->sizeHint().height() * 2); setMinimumWidth(std::max(userList_->sizeHint().width() + 4 * conf::modals::WIDGET_MARGIN, QFontMetrics(largeFont).averageCharWidth() * 30 - 2 * conf::modals::WIDGET_MARGIN)); QFont font; font.setPointSizeF(font.pointSizeF() * conf::modals::LABEL_MEDIUM_SIZE_RATIO); topLabel_ = new QLabel(tr("Read receipts"), this); topLabel_->setAlignment(Qt::AlignCenter); topLabel_->setFont(font); auto okBtn = new QPushButton(tr("Close"), this); auto buttonLayout = new QHBoxLayout(); buttonLayout->setSpacing(15); buttonLayout->addStretch(1); buttonLayout->addWidget(okBtn); layout->addWidget(topLabel_); layout->addWidget(userList_); layout->addLayout(buttonLayout); auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this); connect(closeShortcut, &QShortcut::activated, this, &ReadReceipts::close); connect(okBtn, &QPushButton::clicked, this, &ReadReceipts::close); } void ReadReceipts::addUsers(const std::multimap> &receipts) { // We want to remove any previous items that have been set. userList_->clear(); for (const auto &receipt : receipts) { auto user = new ReceiptItem(this, QString::fromStdString(receipt.second), receipt.first, ChatPage::instance()->currentRoom()); auto item = new QListWidgetItem(userList_); item->setSizeHint(user->minimumSizeHint()); item->setFlags(Qt::NoItemFlags); item->setTextAlignment(Qt::AlignCenter); userList_->setItemWidget(item, user); } } void ReadReceipts::paintEvent(QPaintEvent *) { QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } void ReadReceipts::hideEvent(QHideEvent *event) { userList_->clear(); QFrame::hideEvent(event); }