Reserve size of some containers we are filling

This commit is contained in:
Nicolas Werner 2021-12-29 06:01:38 +01:00
parent 812e3b5f03
commit 19dc6cadea
No known key found for this signature in database
GPG key ID: C8D75E610773F2D9
31 changed files with 317 additions and 209 deletions

View file

@ -227,8 +227,8 @@ Cache::setup()
QString::fromUtf8(localUserId_.toUtf8().toHex()), QString::fromUtf8(localUserId_.toUtf8().toHex()),
QString::fromUtf8(settings->profile().toUtf8().toHex())); QString::fromUtf8(settings->profile().toUtf8().toHex()));
cacheDirectory_ = cacheDirectory_ = QStringLiteral("%1/%2%3").arg(
QStringLiteral("%1/%2%3").arg(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), QStandardPaths::writableLocation(QStandardPaths::AppDataLocation),
QString::fromUtf8(localUserId_.toUtf8().toHex()), QString::fromUtf8(localUserId_.toUtf8().toHex()),
QString::fromUtf8(settings->profile().toUtf8().toHex())); QString::fromUtf8(settings->profile().toUtf8().toHex()));

View file

@ -1325,7 +1325,8 @@ ChatPage::handleMatrixUri(QString uri)
if (item.startsWith(QLatin1String("action="))) { if (item.startsWith(QLatin1String("action="))) {
action = item.remove(QStringLiteral("action=")); action = item.remove(QStringLiteral("action="));
} else if (item.startsWith(QLatin1String("via="))) { } else if (item.startsWith(QLatin1String("via="))) {
vias.push_back(QUrl::fromPercentEncoding(item.remove(QStringLiteral("via=")).toUtf8()).toStdString()); vias.push_back(QUrl::fromPercentEncoding(item.remove(QStringLiteral("via=")).toUtf8())
.toStdString());
} }
} }

View file

@ -56,7 +56,8 @@ CombinedImagePackModel::data(const QModelIndex &index, int role) const
if (hasIndex(index.row(), index.column(), index.parent())) { if (hasIndex(index.row(), index.column(), index.parent())) {
switch (role) { switch (role) {
case CompletionModel::CompletionRole: case CompletionModel::CompletionRole:
return QStringLiteral("<img data-mx-emoticon height=32 src=\"%1\" alt=\"%2\" title=\"%2\">") return QStringLiteral(
"<img data-mx-emoticon height=32 src=\"%1\" alt=\"%2\" title=\"%2\">")
.arg(QString::fromStdString(images[index.row()].image.url).toHtmlEscaped(), .arg(QString::fromStdString(images[index.row()].image.url).toHtmlEscaped(),
QString::fromStdString(images[index.row()].image.body)); QString::fromStdString(images[index.row()].image.body));
case Roles::Url: case Roles::Url:

View file

@ -396,7 +396,9 @@ mtx::accessors::formattedBodyWithFallback(const mtx::events::collections::Timeli
if (!formatted.empty()) if (!formatted.empty())
return QString::fromStdString(formatted); return QString::fromStdString(formatted);
else else
return QString::fromStdString(body(event)).toHtmlEscaped().replace(QLatin1String("\n"), QLatin1String("<br>")); return QString::fromStdString(body(event))
.toHtmlEscaped()
.replace(QLatin1String("\n"), QLatin1String("<br>"));
} }
std::optional<mtx::crypto::EncryptedFile> std::optional<mtx::crypto::EncryptedFile>

View file

@ -15,6 +15,7 @@ ImagePackListModel::ImagePackListModel(const std::string &roomId, QObject *paren
{ {
auto packs_ = cache::client()->getImagePacks(room_id, std::nullopt); auto packs_ = cache::client()->getImagePacks(room_id, std::nullopt);
packs.reserve(packs_.size());
for (const auto &pack : packs_) { for (const auto &pack : packs_) {
packs.push_back(QSharedPointer<SingleImagePackModel>(new SingleImagePackModel(pack))); packs.push_back(QSharedPointer<SingleImagePackModel>(new SingleImagePackModel(pack)));
} }

View file

@ -76,14 +76,15 @@ QStringList
InviteesModel::mxids() InviteesModel::mxids()
{ {
QStringList mxidList; QStringList mxidList;
for (int i = 0; i < invitees_.length(); ++i) mxidList.reserve(invitees_.size());
mxidList.push_back(invitees_[i]->mxid_); for (auto &invitee : qAsConst(invitees_))
mxidList.push_back(invitee->mxid_);
return mxidList; return mxidList;
} }
Invitee::Invitee(const QString &mxid, QObject *parent) Invitee::Invitee(QString mxid, QObject *parent)
: QObject{parent} : QObject{parent}
, mxid_{mxid} , mxid_{std::move(mxid)}
{ {
http::client()->get_profile( http::client()->get_profile(
mxid_.toStdString(), [this](const mtx::responses::Profile &res, mtx::http::RequestErr err) { mxid_.toStdString(), [this](const mtx::responses::Profile &res, mtx::http::RequestErr err) {

View file

@ -13,7 +13,7 @@ class Invitee : public QObject
Q_OBJECT Q_OBJECT
public: public:
Invitee(const QString &mxid, QObject *parent = nullptr); Invitee(QString mxid, QObject *parent = nullptr);
signals: signals:
void userInfoLoaded(); void userInfoLoaded();
@ -45,12 +45,13 @@ public:
Q_INVOKABLE void addUser(QString mxid); Q_INVOKABLE void addUser(QString mxid);
Q_INVOKABLE void removeUser(QString mxid); Q_INVOKABLE void removeUser(QString mxid);
QHash<int, QByteArray> roleNames() const override; [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex & = QModelIndex()) const override [[nodiscard]] int rowCount(const QModelIndex & = QModelIndex()) const override
{ {
return (int)invitees_.size(); return (int)invitees_.size();
} }
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; [[nodiscard]] QVariant
data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QStringList mxids(); QStringList mxids();
signals: signals:

View file

@ -261,7 +261,8 @@ void
MainWindow::closeEvent(QCloseEvent *event) MainWindow::closeEvent(QCloseEvent *event)
{ {
if (WebRTCSession::instance().state() != webrtc::State::DISCONNECTED) { if (WebRTCSession::instance().state() != webrtc::State::DISCONNECTED) {
if (QMessageBox::question(this, QStringLiteral("nheko"), QStringLiteral("A call is in progress. Quit?")) != if (QMessageBox::question(
this, QStringLiteral("nheko"), QStringLiteral("A call is in progress. Quit?")) !=
QMessageBox::Yes) { QMessageBox::Yes) {
event->ignore(); event->ignore();
return; return;

View file

@ -255,7 +255,8 @@ MxcImageProvider::download(const QString &id,
image = clipRadius(std::move(image), radius); image = clipRadius(std::move(image), radius);
} }
image.setText(QStringLiteral("original filename"), QString::fromStdString(originalFilename)); image.setText(QStringLiteral("original filename"),
QString::fromStdString(originalFilename));
image.setText(QStringLiteral("mxc url"), "mxc://" + id); image.setText(QStringLiteral("mxc url"), "mxc://" + id);
then(id, requestedSize, image, fileInfo.absoluteFilePath()); then(id, requestedSize, image, fileInfo.absoluteFilePath());
return; return;
@ -266,7 +267,8 @@ MxcImageProvider::download(const QString &id,
image = clipRadius(std::move(image), radius); image = clipRadius(std::move(image), radius);
} }
image.setText(QStringLiteral("original filename"), QString::fromStdString(originalFilename)); image.setText(QStringLiteral("original filename"),
QString::fromStdString(originalFilename));
image.setText(QStringLiteral("mxc url"), "mxc://" + id); image.setText(QStringLiteral("mxc url"), "mxc://" + id);
then(id, requestedSize, image, fileInfo.absoluteFilePath()); then(id, requestedSize, image, fileInfo.absoluteFilePath());
}); });

View file

@ -112,7 +112,8 @@ ReadReceiptsModel::dateFormat(const QDateTime &then) const
else if (days < 7) else if (days < 7)
//: %1 is the name of the current day, %2 is the time the read receipt was read. The //: %1 is the name of the current day, %2 is the time the read receipt was read. The
//: result may look like this: Monday, 7:15 //: result may look like this: Monday, 7:15
return QStringLiteral("%1, %2").arg(then.toString(QStringLiteral("dddd")), return QStringLiteral("%1, %2").arg(
then.toString(QStringLiteral("dddd")),
QLocale::system().toString(then.time(), QLocale::ShortFormat)); QLocale::system().toString(then.time(), QLocale::ShortFormat));
return QLocale::system().toString(then.time(), QLocale::ShortFormat); return QLocale::system().toString(then.time(), QLocale::ShortFormat);

View file

@ -364,7 +364,10 @@ RegisterPage::doRegistration()
disconnect(UIA::instance(), &UIA::error, this, nullptr); disconnect(UIA::instance(), &UIA::error, this, nullptr);
}); });
http::client()->registration( http::client()->registration(
username, password, ::UIA::instance()->genericHandler(QStringLiteral("Registration")), registrationCb()); username,
password,
::UIA::instance()->genericHandler(QStringLiteral("Registration")),
registrationCb());
} }
} }

View file

@ -29,6 +29,7 @@ SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent)
if (!pack.pack) if (!pack.pack)
pack.pack = mtx::events::msc2545::ImagePack::PackDescription{}; pack.pack = mtx::events::msc2545::ImagePack::PackDescription{};
shortcodes.reserve(pack.images.size());
for (const auto &e : pack.images) for (const auto &e : pack.images)
shortcodes.push_back(e.first); shortcodes.push_back(e.first);

View file

@ -64,10 +64,13 @@ UserSettings::load(std::optional<QString> profile)
startInTray_ = settings.value(QStringLiteral("user/window/start_in_tray"), false).toBool(); startInTray_ = settings.value(QStringLiteral("user/window/start_in_tray"), false).toBool();
roomListWidth_ = settings.value(QStringLiteral("user/sidebar/room_list_width"), -1).toInt(); roomListWidth_ = settings.value(QStringLiteral("user/sidebar/room_list_width"), -1).toInt();
communityListWidth_ = settings.value(QStringLiteral("user/sidebar/community_list_width"), -1).toInt(); communityListWidth_ =
settings.value(QStringLiteral("user/sidebar/community_list_width"), -1).toInt();
hasDesktopNotifications_ = settings.value(QStringLiteral("user/desktop_notifications"), true).toBool(); hasDesktopNotifications_ =
hasAlertOnNotification_ = settings.value(QStringLiteral("user/alert_on_notification"), false).toBool(); settings.value(QStringLiteral("user/desktop_notifications"), true).toBool();
hasAlertOnNotification_ =
settings.value(QStringLiteral("user/alert_on_notification"), false).toBool();
groupView_ = settings.value(QStringLiteral("user/group_view"), true).toBool(); groupView_ = settings.value(QStringLiteral("user/group_view"), true).toBool();
buttonsInTimeline_ = settings.value(QStringLiteral("user/timeline/buttons"), true).toBool(); buttonsInTimeline_ = settings.value(QStringLiteral("user/timeline/buttons"), true).toBool();
timelineMaxWidth_ = settings.value(QStringLiteral("user/timeline/max_width"), 0).toInt(); timelineMaxWidth_ = settings.value(QStringLiteral("user/timeline/max_width"), 0).toInt();
@ -76,8 +79,10 @@ UserSettings::load(std::optional<QString> profile)
enlargeEmojiOnlyMessages_ = enlargeEmojiOnlyMessages_ =
settings.value(QStringLiteral("user/timeline/enlarge_emoji_only_msg"), false).toBool(); settings.value(QStringLiteral("user/timeline/enlarge_emoji_only_msg"), false).toBool();
markdown_ = settings.value(QStringLiteral("user/markdown_enabled"), true).toBool(); markdown_ = settings.value(QStringLiteral("user/markdown_enabled"), true).toBool();
animateImagesOnHover_ = settings.value(QStringLiteral("user/animate_images_on_hover"), false).toBool(); animateImagesOnHover_ =
typingNotifications_ = settings.value(QStringLiteral("user/typing_notifications"), true).toBool(); settings.value(QStringLiteral("user/animate_images_on_hover"), false).toBool();
typingNotifications_ =
settings.value(QStringLiteral("user/typing_notifications"), true).toBool();
sortByImportance_ = settings.value(QStringLiteral("user/sort_by_unread"), true).toBool(); sortByImportance_ = settings.value(QStringLiteral("user/sort_by_unread"), true).toBool();
readReceipts_ = settings.value(QStringLiteral("user/read_receipts"), true).toBool(); readReceipts_ = settings.value(QStringLiteral("user/read_receipts"), true).toBool();
theme_ = settings.value(QStringLiteral("user/theme"), defaultTheme_).toString(); theme_ = settings.value(QStringLiteral("user/theme"), defaultTheme_).toString();
@ -86,11 +91,14 @@ UserSettings::load(std::optional<QString> profile)
useIdenticon_ = settings.value(QStringLiteral("user/use_identicon"), true).toBool(); useIdenticon_ = settings.value(QStringLiteral("user/use_identicon"), true).toBool();
decryptSidebar_ = settings.value(QStringLiteral("user/decrypt_sidebar"), true).toBool(); decryptSidebar_ = settings.value(QStringLiteral("user/decrypt_sidebar"), true).toBool();
privacyScreen_ = settings.value(QStringLiteral("user/privacy_screen"), false).toBool(); privacyScreen_ = settings.value(QStringLiteral("user/privacy_screen"), false).toBool();
privacyScreenTimeout_ = settings.value(QStringLiteral("user/privacy_screen_timeout"), 0).toInt(); privacyScreenTimeout_ =
settings.value(QStringLiteral("user/privacy_screen_timeout"), 0).toInt();
mobileMode_ = settings.value(QStringLiteral("user/mobile_mode"), false).toBool(); mobileMode_ = settings.value(QStringLiteral("user/mobile_mode"), false).toBool();
emojiFont_ = settings.value(QStringLiteral("user/emoji_font_family"), "default").toString(); emojiFont_ = settings.value(QStringLiteral("user/emoji_font_family"), "default").toString();
baseFontSize_ = settings.value(QStringLiteral("user/font_size"), QFont().pointSizeF()).toDouble(); baseFontSize_ =
auto tempPresence = settings.value(QStringLiteral("user/presence"), "").toString().toStdString(); settings.value(QStringLiteral("user/font_size"), QFont().pointSizeF()).toDouble();
auto tempPresence =
settings.value(QStringLiteral("user/presence"), "").toString().toStdString();
auto presenceValue = QMetaEnum::fromType<Presence>().keyToValue(tempPresence.c_str()); auto presenceValue = QMetaEnum::fromType<Presence>().keyToValue(tempPresence.c_str());
if (presenceValue < 0) if (presenceValue < 0)
presenceValue = 0; presenceValue = 0;
@ -98,12 +106,17 @@ UserSettings::load(std::optional<QString> profile)
ringtone_ = settings.value(QStringLiteral("user/ringtone"), "Default").toString(); ringtone_ = settings.value(QStringLiteral("user/ringtone"), "Default").toString();
microphone_ = settings.value(QStringLiteral("user/microphone"), QString()).toString(); microphone_ = settings.value(QStringLiteral("user/microphone"), QString()).toString();
camera_ = settings.value(QStringLiteral("user/camera"), QString()).toString(); camera_ = settings.value(QStringLiteral("user/camera"), QString()).toString();
cameraResolution_ = settings.value(QStringLiteral("user/camera_resolution"), QString()).toString(); cameraResolution_ =
cameraFrameRate_ = settings.value(QStringLiteral("user/camera_frame_rate"), QString()).toString(); settings.value(QStringLiteral("user/camera_resolution"), QString()).toString();
screenShareFrameRate_ = settings.value(QStringLiteral("user/screen_share_frame_rate"), 5).toInt(); cameraFrameRate_ =
settings.value(QStringLiteral("user/camera_frame_rate"), QString()).toString();
screenShareFrameRate_ =
settings.value(QStringLiteral("user/screen_share_frame_rate"), 5).toInt();
screenSharePiP_ = settings.value(QStringLiteral("user/screen_share_pip"), true).toBool(); screenSharePiP_ = settings.value(QStringLiteral("user/screen_share_pip"), true).toBool();
screenShareRemoteVideo_ = settings.value(QStringLiteral("user/screen_share_remote_video"), false).toBool(); screenShareRemoteVideo_ =
screenShareHideCursor_ = settings.value(QStringLiteral("user/screen_share_hide_cursor"), false).toBool(); settings.value(QStringLiteral("user/screen_share_remote_video"), false).toBool();
screenShareHideCursor_ =
settings.value(QStringLiteral("user/screen_share_hide_cursor"), false).toBool();
useStunServer_ = settings.value(QStringLiteral("user/use_stun_server"), false).toBool(); useStunServer_ = settings.value(QStringLiteral("user/use_stun_server"), false).toBool();
if (profile) // set to "" if it's the default to maintain compatibility if (profile) // set to "" if it's the default to maintain compatibility
@ -111,7 +124,9 @@ UserSettings::load(std::optional<QString> profile)
else else
profile_ = settings.value(QStringLiteral("user/currentProfile"), "").toString(); profile_ = settings.value(QStringLiteral("user/currentProfile"), "").toString();
QString prefix = (profile_ != QLatin1String("") && profile_ != QLatin1String("default")) ? "profile/" + profile_ + "/" : QLatin1String(""); QString prefix = (profile_ != QLatin1String("") && profile_ != QLatin1String("default"))
? "profile/" + profile_ + "/"
: QLatin1String("");
accessToken_ = settings.value(prefix + "auth/access_token", "").toString(); accessToken_ = settings.value(prefix + "auth/access_token", "").toString();
homeserver_ = settings.value(prefix + "auth/home_server", "").toString(); homeserver_ = settings.value(prefix + "auth/home_server", "").toString();
userId_ = settings.value(prefix + "auth/user_id", "").toString(); userId_ = settings.value(prefix + "auth/user_id", "").toString();
@ -714,7 +729,9 @@ UserSettings::save()
settings.endGroup(); // user settings.endGroup(); // user
QString prefix = (profile_ != QLatin1String("") && profile_ != QLatin1String("default")) ? "profile/" + profile_ + "/" : QLatin1String(""); QString prefix = (profile_ != QLatin1String("") && profile_ != QLatin1String("default"))
? "profile/" + profile_ + "/"
: QLatin1String("");
settings.setValue(prefix + "auth/access_token", accessToken_); settings.setValue(prefix + "auth/access_token", accessToken_);
settings.setValue(prefix + "auth/home_server", homeserver_); settings.setValue(prefix + "auth/home_server", homeserver_);
settings.setValue(prefix + "auth/user_id", userId_); settings.setValue(prefix + "auth/user_id", userId_);
@ -730,11 +747,13 @@ UserSettings::save()
settings.setValue(prefix + "user/recent_reactions", recentReactions_); settings.setValue(prefix + "user/recent_reactions", recentReactions_);
QVariantList v; QVariantList v;
v.reserve(collapsedSpaces_.size());
for (const auto &e : qAsConst(collapsedSpaces_)) for (const auto &e : qAsConst(collapsedSpaces_))
v.push_back(e); v.push_back(e);
settings.setValue(prefix + "user/collapsed_spaces", v); settings.setValue(prefix + "user/collapsed_spaces", v);
settings.setValue(QStringLiteral("disable_certificate_validation"), disableCertificateValidation_); settings.setValue(QStringLiteral("disable_certificate_validation"),
disableCertificateValidation_);
settings.sync(); settings.sync();
} }
@ -959,7 +978,8 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
crossSigningKeysLayout->addWidget(crossSigningRequestBtn, 0, Qt::AlignRight); crossSigningKeysLayout->addWidget(crossSigningRequestBtn, 0, Qt::AlignRight);
crossSigningKeysLayout->addWidget(crossSigningDownloadBtn, 0, Qt::AlignRight); crossSigningKeysLayout->addWidget(crossSigningDownloadBtn, 0, Qt::AlignRight);
auto boxWrap = [this, &font](QString labelText, QWidget *field, QString tooltipText = QLatin1String("")) { auto boxWrap =
[this, &font](QString labelText, QWidget *field, QString tooltipText = QLatin1String("")) {
auto label = new QLabel{labelText, this}; auto label = new QLabel{labelText, this};
label->setFont(font); label->setFont(font);
label->setMargin(OptionMargin); label->setMargin(OptionMargin);
@ -1087,7 +1107,8 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
ringtoneCombo_->addItem(QStringLiteral("Default")); ringtoneCombo_->addItem(QStringLiteral("Default"));
ringtoneCombo_->addItem(QStringLiteral("Other...")); ringtoneCombo_->addItem(QStringLiteral("Other..."));
const QString &ringtone = settings_->ringtone(); const QString &ringtone = settings_->ringtone();
if (!ringtone.isEmpty() && ringtone != QLatin1String("Mute") && ringtone != QLatin1String("Default")) if (!ringtone.isEmpty() && ringtone != QLatin1String("Mute") &&
ringtone != QLatin1String("Default"))
ringtoneCombo_->addItem(ringtone); ringtoneCombo_->addItem(ringtone);
microphoneCombo_->setSizeAdjustPolicy(QComboBox::AdjustToContents); microphoneCombo_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
cameraCombo_->setSizeAdjustPolicy(QComboBox::AdjustToContents); cameraCombo_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
@ -1186,13 +1207,13 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
this, this,
[this](const QString &family) { settings_->setEmojiFontFamily(family.trimmed()); }); [this](const QString &family) { settings_->setEmojiFontFamily(family.trimmed()); });
connect(ringtoneCombo_, connect(
ringtoneCombo_,
static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentTextChanged), static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentTextChanged),
this, this,
[this](const QString &ringtone) { [this](const QString &ringtone) {
if (ringtone == QLatin1String("Other...")) { if (ringtone == QLatin1String("Other...")) {
QString homeFolder = QString homeFolder = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
auto filepath = QFileDialog::getOpenFileName( auto filepath = QFileDialog::getOpenFileName(
this, tr("Select a file"), homeFolder, tr("All Files (*)")); this, tr("Select a file"), homeFolder, tr("All Files (*)"));
if (!filepath.isEmpty()) { if (!filepath.isEmpty()) {

View file

@ -291,8 +291,9 @@ signals:
private: private:
// Default to system theme if QT_QPA_PLATFORMTHEME var is set. // Default to system theme if QT_QPA_PLATFORMTHEME var is set.
QString defaultTheme_ = QString defaultTheme_ = QProcessEnvironment::systemEnvironment()
QProcessEnvironment::systemEnvironment().value(QStringLiteral("QT_QPA_PLATFORMTHEME"), QLatin1String("")).isEmpty() .value(QStringLiteral("QT_QPA_PLATFORMTHEME"), QLatin1String(""))
.isEmpty()
? "light" ? "light"
: "system"; : "system";
QString theme_; QString theme_;

View file

@ -237,8 +237,8 @@ utils::getMessageDescription(const TimelineEvent &event,
DescInfo info; DescInfo info;
info.userid = sender; info.userid = sender;
info.body = info.body = QStringLiteral(" %1").arg(
QStringLiteral(" %1").arg(messageDescription<Encrypted>(username, QLatin1String(""), sender == localUser)); messageDescription<Encrypted>(username, QLatin1String(""), sender == localUser));
info.timestamp = msg->origin_server_ts; info.timestamp = msg->origin_server_ts;
info.descriptiveTime = utils::descriptiveTime(ts); info.descriptiveTime = utils::descriptiveTime(ts);
info.event_id = QString::fromStdString(msg->event_id); info.event_id = QString::fromStdString(msg->event_id);
@ -402,7 +402,8 @@ utils::linkifyMessage(const QString &body)
// Convert to valid XML. // Convert to valid XML.
auto doc = body; auto doc = body;
doc.replace(conf::strings::url_regex, conf::strings::url_html); doc.replace(conf::strings::url_regex, conf::strings::url_html);
doc.replace(QRegularExpression(QStringLiteral("\\b(?<![\"'])(?>(matrix:[\\S]{5,}))(?![\"'])\\b")), doc.replace(
QRegularExpression(QStringLiteral("\\b(?<![\"'])(?>(matrix:[\\S]{5,}))(?![\"'])\\b")),
conf::strings::url_html); conf::strings::url_html);
return doc; return doc;
@ -555,7 +556,8 @@ utils::markdownToHtml(const QString &text, bool rainbowify)
auto result = linkifyMessage(escapeBlacklistedHtml(QString::fromStdString(html))).trimmed(); auto result = linkifyMessage(escapeBlacklistedHtml(QString::fromStdString(html))).trimmed();
if (result.count(QStringLiteral("<p>")) == 1 && result.startsWith(QLatin1String("<p>")) && result.endsWith(QLatin1String("</p>"))) { if (result.count(QStringLiteral("<p>")) == 1 && result.startsWith(QLatin1String("<p>")) &&
result.endsWith(QLatin1String("</p>"))) {
result = result.mid(3, result.size() - 3 - 4); result = result.mid(3, result.size() - 3 - 4);
} }

View file

@ -1220,6 +1220,7 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
auto deviceTargets = devices; auto deviceTargets = devices;
if (devices.empty()) { if (devices.empty()) {
deviceTargets.clear(); deviceTargets.clear();
deviceTargets.reserve(deviceKeys->device_keys.size());
for (const auto &[device, keys] : deviceKeys->device_keys) { for (const auto &[device, keys] : deviceKeys->device_keys) {
(void)keys; (void)keys;
deviceTargets.push_back(device); deviceTargets.push_back(device);

View file

@ -185,8 +185,7 @@ main(int argc, char *argv[])
// name is set. It only exists to keep Qt from complaining about the --profile/-p // name is set. It only exists to keep Qt from complaining about the --profile/-p
// option and thereby crashing the app. // option and thereby crashing the app.
QCommandLineOption configName( QCommandLineOption configName(
QStringList() << QStringLiteral("p") QStringList() << QStringLiteral("p") << QStringLiteral("profile"),
<< QStringLiteral("profile"),
QCoreApplication::tr("Create a unique profile, which allows you to log into several " QCoreApplication::tr("Create a unique profile, which allows you to log into several "
"accounts at the same time and start multiple instances of nheko."), "accounts at the same time and start multiple instances of nheko."),
QCoreApplication::tr("profile"), QCoreApplication::tr("profile"),
@ -252,11 +251,15 @@ main(int argc, char *argv[])
QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom)); QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom));
QTranslator qtTranslator; QTranslator qtTranslator;
qtTranslator.load(QLocale(), QStringLiteral("qt"), QStringLiteral("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); qtTranslator.load(QLocale(),
QStringLiteral("qt"),
QStringLiteral("_"),
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app.installTranslator(&qtTranslator); app.installTranslator(&qtTranslator);
QTranslator appTranslator; QTranslator appTranslator;
appTranslator.load(QLocale(), QStringLiteral("nheko"), QStringLiteral("_"), QStringLiteral(":/translations")); appTranslator.load(
QLocale(), QStringLiteral("nheko"), QStringLiteral("_"), QStringLiteral(":/translations"));
app.installTranslator(&appTranslator); app.installTranslator(&appTranslator);
MainWindow w; MainWindow w;
@ -304,7 +307,8 @@ main(int argc, char *argv[])
QObject::disconnect(uriConnection); QObject::disconnect(uriConnection);
}); });
} }
QDesktopServices::setUrlHandler(QStringLiteral("matrix"), ChatPage::instance(), "handleMatrixUri"); QDesktopServices::setUrlHandler(
QStringLiteral("matrix"), ChatPage::instance(), "handleMatrixUri");
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
// Temporary solution for the emoji picker until // Temporary solution for the emoji picker until

View file

@ -108,7 +108,8 @@ NotificationsManager::postNotification(const mtx::responses::Notification &notif
if (hasImages_ && if (hasImages_ &&
mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Image) { mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Image) {
MxcImageProvider::download( MxcImageProvider::download(
QString::fromStdString(mtx::accessors::url(notification.event)).remove(QStringLiteral("mxc://")), QString::fromStdString(mtx::accessors::url(notification.event))
.remove(QStringLiteral("mxc://")),
QSize(200, 80), QSize(200, 80),
[postNotif, notification, template_](QString, QSize, QImage, QString imgPath) { [postNotif, notification, template_](QString, QSize, QImage, QString imgPath) {
if (imgPath.isEmpty()) if (imgPath.isEmpty())

View file

@ -293,6 +293,7 @@ CommunitiesModel::FlatTree::storeCollapsed()
int depth = -1; int depth = -1;
QStringList current; QStringList current;
elements.reserve(static_cast<int>(tree.size()));
for (const auto &e : tree) { for (const auto &e : tree) {
if (e.depth > depth) { if (e.depth > depth) {

View file

@ -527,6 +527,7 @@ EventStore::reactions(const std::string &event_id)
} }
QVariantList temp; QVariantList temp;
temp.reserve(static_cast<int>(reactions.size()));
for (auto &reaction : reactions) { for (auto &reaction : reactions) {
const auto &agg = aggregation[reaction.key_.toStdString()]; const auto &agg = aggregation[reaction.key_.toStdString()];
reaction.count_ = agg.count; reaction.count_ = agg.count;

View file

@ -56,7 +56,8 @@ InputBar::insertMimeData(const QMimeData *md)
if (!md) if (!md)
return; return;
nhlog::ui()->debug("Got mime formats: {}", md->formats().join(QStringLiteral(", ")).toStdString()); nhlog::ui()->debug("Got mime formats: {}",
md->formats().join(QStringLiteral(", ")).toStdString());
const auto formats = md->formats().filter(QStringLiteral("/")); const auto formats = md->formats().filter(QStringLiteral("/"));
const auto image = formats.filter(QStringLiteral("image/"), Qt::CaseInsensitive); const auto image = formats.filter(QStringLiteral("image/"), Qt::CaseInsensitive);
const auto audio = formats.filter(QStringLiteral("audio/"), Qt::CaseInsensitive); const auto audio = formats.filter(QStringLiteral("audio/"), Qt::CaseInsensitive);
@ -140,7 +141,8 @@ InputBar::updateAtRoom(const QString &t)
auto start = finder.position(); auto start = finder.position();
finder.toNextBoundary(); finder.toNextBoundary();
auto end = finder.position(); auto end = finder.position();
if (start > 0 && end - start >= 4 && t.mid(start, end - start) == QLatin1String("room") && if (start > 0 && end - start >= 4 &&
t.mid(start, end - start) == QLatin1String("room") &&
t.at(start - 1) == QChar('@')) { t.at(start - 1) == QChar('@')) {
roomMention = true; roomMention = true;
break; break;
@ -660,13 +662,15 @@ InputBar::showPreview(const QMimeData &source, const QString &path, const QStrin
previewDialog_->setAttribute(Qt::WA_DeleteOnClose); previewDialog_->setAttribute(Qt::WA_DeleteOnClose);
// Force SVG to _not_ be handled as an image, but as raw data // Force SVG to _not_ be handled as an image, but as raw data
if (source.hasImage() && (formats.empty() || formats.front() != QLatin1String("image/svg+xml"))) { if (source.hasImage() &&
(formats.empty() || formats.front() != QLatin1String("image/svg+xml"))) {
if (!formats.empty() && formats.front().startsWith(QLatin1String("image/"))) { if (!formats.empty() && formats.front().startsWith(QLatin1String("image/"))) {
// known format, keep as-is // known format, keep as-is
previewDialog_->setPreview(qvariant_cast<QImage>(source.imageData()), formats.front()); previewDialog_->setPreview(qvariant_cast<QImage>(source.imageData()), formats.front());
} else { } else {
// unknown image format, default to image/png // unknown image format, default to image/png
previewDialog_->setPreview(qvariant_cast<QImage>(source.imageData()), QStringLiteral("image/png")); previewDialog_->setPreview(qvariant_cast<QImage>(source.imageData()),
QStringLiteral("image/png"));
} }
} else if (!path.isEmpty()) } else if (!path.isEmpty())
previewDialog_->setPreview(path); previewDialog_->setPreview(path);

View file

@ -90,6 +90,7 @@ RoomlistModel::data(const QModelIndex &index, int role) const
if (role == Roles::ParentSpaces) { if (role == Roles::ParentSpaces) {
auto parents = cache::client()->getParentRoomIds(roomid.toStdString()); auto parents = cache::client()->getParentRoomIds(roomid.toStdString());
QStringList list; QStringList list;
list.reserve(static_cast<int>(parents.size()));
for (const auto &t : parents) for (const auto &t : parents)
list.push_back(QString::fromStdString(t)); list.push_back(QString::fromStdString(t));
return list; return list;
@ -98,7 +99,8 @@ RoomlistModel::data(const QModelIndex &index, int role) const
} else if (role == Roles::IsDirect) { } else if (role == Roles::IsDirect) {
return directChatToUser.count(roomid) > 0; return directChatToUser.count(roomid) > 0;
} else if (role == Roles::DirectChatOtherUserId) { } else if (role == Roles::DirectChatOtherUserId) {
return directChatToUser.count(roomid) ? directChatToUser.at(roomid).front() : QLatin1String(""); return directChatToUser.count(roomid) ? directChatToUser.at(roomid).front()
: QLatin1String("");
} }
if (models.contains(roomid)) { if (models.contains(roomid)) {
@ -113,7 +115,7 @@ RoomlistModel::data(const QModelIndex &index, int role) const
case Roles::Time: case Roles::Time:
return room->lastMessage().descriptiveTime; return room->lastMessage().descriptiveTime;
case Roles::Timestamp: case Roles::Timestamp:
return QVariant(static_cast<quint64>(room->lastMessage().timestamp)); return QVariant{static_cast<quint64>(room->lastMessage().timestamp)};
case Roles::HasUnreadMessages: case Roles::HasUnreadMessages:
return this->roomReadStatus.count(roomid) && this->roomReadStatus.at(roomid); return this->roomReadStatus.count(roomid) && this->roomReadStatus.at(roomid);
case Roles::HasLoudNotification: case Roles::HasLoudNotification:
@ -129,6 +131,7 @@ RoomlistModel::data(const QModelIndex &index, int role) const
case Roles::Tags: { case Roles::Tags: {
auto info = cache::singleRoomInfo(roomid.toStdString()); auto info = cache::singleRoomInfo(roomid.toStdString());
QStringList list; QStringList list;
list.reserve(static_cast<int>(info.tags.size()));
for (const auto &t : info.tags) for (const auto &t : info.tags)
list.push_back(QString::fromStdString(t)); list.push_back(QString::fromStdString(t));
return list; return list;
@ -148,7 +151,7 @@ RoomlistModel::data(const QModelIndex &index, int role) const
case Roles::Time: case Roles::Time:
return QString(); return QString();
case Roles::Timestamp: case Roles::Timestamp:
return QVariant(static_cast<quint64>(0)); return QVariant{static_cast<quint64>(0)};
case Roles::HasUnreadMessages: case Roles::HasUnreadMessages:
case Roles::HasLoudNotification: case Roles::HasLoudNotification:
return false; return false;
@ -177,7 +180,7 @@ RoomlistModel::data(const QModelIndex &index, int role) const
case Roles::Time: case Roles::Time:
return QString(); return QString();
case Roles::Timestamp: case Roles::Timestamp:
return QVariant(static_cast<quint64>(0)); return QVariant{static_cast<quint64>(0)};
case Roles::HasUnreadMessages: case Roles::HasUnreadMessages:
case Roles::HasLoudNotification: case Roles::HasLoudNotification:
return false; return false;

View file

@ -159,7 +159,8 @@ public slots:
} }
void joinPreview(QString roomid) void joinPreview(QString roomid)
{ {
roomlistmodel->joinPreview(roomid, filterType == FilterBy::Space ? filterStr : QLatin1String("")); roomlistmodel->joinPreview(roomid,
filterType == FilterBy::Space ? filterStr : QLatin1String(""));
} }
void acceptInvite(QString roomid) { roomlistmodel->acceptInvite(roomid); } void acceptInvite(QString roomid) { roomlistmodel->acceptInvite(roomid); }
void declineInvite(QString roomid) { roomlistmodel->declineInvite(roomid); } void declineInvite(QString roomid) { roomlistmodel->declineInvite(roomid); }

View file

@ -503,7 +503,7 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
switch (role) { switch (role) {
case IsSender: case IsSender:
return QVariant(acc::sender(event) == http::client()->user_id().to_string()); return {acc::sender(event) == http::client()->user_id().to_string()};
case UserId: case UserId:
return QVariant(QString::fromStdString(acc::sender(event))); return QVariant(QString::fromStdString(acc::sender(event)));
case UserName: case UserName:
@ -512,12 +512,12 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
case Day: { case Day: {
QDateTime prevDate = origin_server_ts(event); QDateTime prevDate = origin_server_ts(event);
prevDate.setTime(QTime()); prevDate.setTime(QTime());
return QVariant(prevDate.toMSecsSinceEpoch()); return {prevDate.toMSecsSinceEpoch()};
} }
case Timestamp: case Timestamp:
return QVariant(origin_server_ts(event)); return QVariant(origin_server_ts(event));
case Type: case Type:
return QVariant(toRoomEventType(event)); return {toRoomEventType(event)};
case TypeString: case TypeString:
return QVariant(toRoomEventTypeString(event)); return QVariant(toRoomEventTypeString(event));
case IsOnlyEmoji: { case IsOnlyEmoji: {
@ -530,17 +530,18 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
if (utils::codepointIsEmoji(code)) { if (utils::codepointIsEmoji(code)) {
emojiCount++; emojiCount++;
} else { } else {
return QVariant(0); return {0};
} }
} }
return QVariant(emojiCount); return {emojiCount};
} }
case Body: case Body:
return QVariant(utils::replaceEmoji(QString::fromStdString(body(event)).toHtmlEscaped())); return QVariant(utils::replaceEmoji(QString::fromStdString(body(event)).toHtmlEscaped()));
case FormattedBody: { case FormattedBody: {
const static QRegularExpression replyFallback( const static QRegularExpression replyFallback(
QStringLiteral("<mx-reply>.*</mx-reply>"), QRegularExpression::DotMatchesEverythingOption); QStringLiteral("<mx-reply>.*</mx-reply>"),
QRegularExpression::DotMatchesEverythingOption);
auto ascent = QFontMetrics(UserSettings::instance()->font()).ascent(); auto ascent = QFontMetrics(UserSettings::instance()->font()).ascent();
@ -574,7 +575,8 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
// Construct image parameters later used by MxcImageProvider. // Construct image parameters later used by MxcImageProvider.
QString imgParams; QString imgParams;
if (curImg.contains(QLatin1String("height"))) { if (curImg.contains(QLatin1String("height"))) {
const static QRegularExpression matchImgHeight(QStringLiteral("height=([\"\']?)(\\d+)([\"\']?)")); const static QRegularExpression matchImgHeight(
QStringLiteral("height=([\"\']?)(\\d+)([\"\']?)"));
// Make emoticons twice as high as the font. // Make emoticons twice as high as the font.
if (curImg.contains(QLatin1String("data-mx-emoticon"))) { if (curImg.contains(QLatin1String("data-mx-emoticon"))) {
imgReplacement = imgReplacement =
@ -587,11 +589,11 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
// Replace src in current <img>. // Replace src in current <img>.
const static QRegularExpression matchImgUri(QStringLiteral("src=\"mxc://([^\"]*)\"")); const static QRegularExpression matchImgUri(QStringLiteral("src=\"mxc://([^\"]*)\""));
imgReplacement.replace(matchImgUri, imgReplacement.replace(matchImgUri,
QString("src=\"image://mxcImage/\\1%1\"").arg(imgParams)); QStringLiteral(R"(src="image://mxcImage/\1%1")").arg(imgParams));
// Same regex but for single quotes around the src // Same regex but for single quotes around the src
const static QRegularExpression matchImgUri2(QStringLiteral("src=\'mxc://([^\']*)\'")); const static QRegularExpression matchImgUri2(QStringLiteral("src=\'mxc://([^\']*)\'"));
imgReplacement.replace(matchImgUri2, imgReplacement.replace(matchImgUri2,
QString("src=\'image://mxcImage/\\1%1\'").arg(imgParams)); QStringLiteral("src=\'image://mxcImage/\\1%1\'").arg(imgParams));
// Replace <img> in formattedBody_ with our new <img>. // Replace <img> in formattedBody_ with our new <img>.
formattedBody_.replace(curImg, imgReplacement); formattedBody_.replace(curImg, imgReplacement);
@ -623,7 +625,7 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
double prop = media_height(event) / (double)w; double prop = media_height(event) / (double)w;
return QVariant(prop > 0 ? prop : 1.); return {prop > 0 ? prop : 1.};
} }
case EventId: { case EventId: {
if (auto replaces = relations(event).replaces()) if (auto replaces = relations(event).replaces())
@ -651,10 +653,10 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
return qml_mtx_events::Received; return qml_mtx_events::Received;
} }
case IsEdited: case IsEdited:
return QVariant(relations(event).replaces().has_value()); return {relations(event).replaces().has_value()};
case IsEditable: case IsEditable:
return QVariant(!is_state_event(event) && return {!is_state_event(event) &&
mtx::accessors::sender(event) == http::client()->user_id().to_string()); mtx::accessors::sender(event) == http::client()->user_id().to_string()};
case IsEncrypted: { case IsEncrypted: {
auto id = event_id(event); auto id = event_id(event);
auto encrypted_event = events.get(id, "", false); auto encrypted_event = events.get(id, "", false);
@ -693,8 +695,10 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
return QVariant( return QVariant(
utils::replaceEmoji(QString::fromStdString(room_name(event)).toHtmlEscaped())); utils::replaceEmoji(QString::fromStdString(room_name(event)).toHtmlEscaped()));
case RoomTopic: case RoomTopic:
return QVariant(utils::replaceEmoji(utils::linkifyMessage( return QVariant(utils::replaceEmoji(
QString::fromStdString(room_topic(event)).toHtmlEscaped().replace(QLatin1String("\n"), QLatin1String("<br>"))))); utils::linkifyMessage(QString::fromStdString(room_topic(event))
.toHtmlEscaped()
.replace(QLatin1String("\n"), QLatin1String("<br>")))));
case CallType: case CallType:
return QVariant(QString::fromStdString(call_type(event))); return QVariant(QString::fromStdString(call_type(event)));
case Dump: { case Dump: {
@ -736,7 +740,7 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
case RelatedEventCacheBuster: case RelatedEventCacheBuster:
return relatedEventCacheBuster; return relatedEventCacheBuster;
default: default:
return QVariant(); return {};
} }
} }
@ -746,7 +750,7 @@ TimelineModel::data(const QModelIndex &index, int role) const
using namespace mtx::accessors; using namespace mtx::accessors;
namespace acc = mtx::accessors; namespace acc = mtx::accessors;
if (index.row() < 0 && index.row() >= rowCount()) if (index.row() < 0 && index.row() >= rowCount())
return QVariant(); return {};
// HACK(Nico): fetchMore likes to break with dynamically sized delegates and reuseItems // HACK(Nico): fetchMore likes to break with dynamically sized delegates and reuseItems
if (index.row() + 1 == rowCount() && !m_paginationInProgress) if (index.row() + 1 == rowCount() && !m_paginationInProgress)
@ -760,10 +764,10 @@ TimelineModel::data(const QModelIndex &index, int role) const
if (role == PreviousMessageDay || role == PreviousMessageUserId) { if (role == PreviousMessageDay || role == PreviousMessageUserId) {
int prevIdx = rowCount() - index.row() - 2; int prevIdx = rowCount() - index.row() - 2;
if (prevIdx < 0) if (prevIdx < 0)
return QVariant(); return {};
auto tempEv = events.get(prevIdx); auto tempEv = events.get(prevIdx);
if (!tempEv) if (!tempEv)
return QVariant(); return {};
if (role == PreviousMessageUserId) if (role == PreviousMessageUserId)
return data(*tempEv, UserId); return data(*tempEv, UserId);
else else
@ -778,7 +782,7 @@ TimelineModel::dataById(const QString &id, int role, const QString &relatedTo)
{ {
if (auto event = events.get(id.toStdString(), relatedTo.toStdString())) if (auto event = events.get(id.toStdString(), relatedTo.toStdString()))
return data(*event, role); return data(*event, role);
return QVariant(); return {};
} }
bool bool
@ -1623,7 +1627,7 @@ TimelineModel::cacheMedia(const QString &eventId,
void void
TimelineModel::cacheMedia(const QString &eventId) TimelineModel::cacheMedia(const QString &eventId)
{ {
cacheMedia(eventId, NULL); cacheMedia(eventId, nullptr);
} }
void void
@ -1739,7 +1743,7 @@ TimelineModel::formatTypingUsers(const std::vector<QString> &users, const QColor
(int)users.size()); (int)users.size());
if (users.empty()) { if (users.empty()) {
return QString(); return {};
} }
QStringList uidWithoutLast; QStringList uidWithoutLast;
@ -1774,6 +1778,7 @@ TimelineModel::formatTypingUsers(const std::vector<QString> &users, const QColor
return coloredUsername; return coloredUsername;
}; };
uidWithoutLast.reserve(static_cast<int>(users.size()));
for (size_t i = 0; i + 1 < users.size(); i++) { for (size_t i = 0; i + 1 < users.size(); i++) {
uidWithoutLast.append(formatUser(users[i])); uidWithoutLast.append(formatUser(users[i]));
} }
@ -1786,11 +1791,11 @@ TimelineModel::formatJoinRuleEvent(const QString &id)
{ {
mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), ""); mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), "");
if (!e) if (!e)
return QString(); return {};
auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::JoinRules>>(e); auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::JoinRules>>(e);
if (!event) if (!event)
return QString(); return {};
QString user = QString::fromStdString(event->sender); QString user = QString::fromStdString(event->sender);
QString name = utils::replaceEmoji(displayName(user)); QString name = utils::replaceEmoji(displayName(user));
@ -1814,7 +1819,7 @@ TimelineModel::formatJoinRuleEvent(const QString &id)
} }
default: default:
// Currently, knock and private are reserved keywords and not implemented in Matrix. // Currently, knock and private are reserved keywords and not implemented in Matrix.
return QString(); return {};
} }
} }
@ -1823,11 +1828,11 @@ TimelineModel::formatGuestAccessEvent(const QString &id)
{ {
mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), ""); mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), "");
if (!e) if (!e)
return QString(); return {};
auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::GuestAccess>>(e); auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::GuestAccess>>(e);
if (!event) if (!event)
return QString(); return {};
QString user = QString::fromStdString(event->sender); QString user = QString::fromStdString(event->sender);
QString name = utils::replaceEmoji(displayName(user)); QString name = utils::replaceEmoji(displayName(user));
@ -1838,7 +1843,7 @@ TimelineModel::formatGuestAccessEvent(const QString &id)
case mtx::events::state::AccessState::Forbidden: case mtx::events::state::AccessState::Forbidden:
return tr("%1 has closed the room to guest access.").arg(name); return tr("%1 has closed the room to guest access.").arg(name);
default: default:
return QString(); return {};
} }
} }
@ -1847,12 +1852,12 @@ TimelineModel::formatHistoryVisibilityEvent(const QString &id)
{ {
mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), ""); mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), "");
if (!e) if (!e)
return QString(); return {};
auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::HistoryVisibility>>(e); auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::HistoryVisibility>>(e);
if (!event) if (!event)
return QString(); return {};
QString user = QString::fromStdString(event->sender); QString user = QString::fromStdString(event->sender);
QString name = utils::replaceEmoji(displayName(user)); QString name = utils::replaceEmoji(displayName(user));
@ -1870,7 +1875,7 @@ TimelineModel::formatHistoryVisibilityEvent(const QString &id)
return tr("%1 set the room history visible to members since they joined the room.") return tr("%1 set the room history visible to members since they joined the room.")
.arg(name); .arg(name);
default: default:
return QString(); return {};
} }
} }
@ -1879,7 +1884,7 @@ TimelineModel::formatPowerLevelEvent(const QString &id)
{ {
mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), ""); mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), "");
if (!e) if (!e)
return QString(); return {};
auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::PowerLevels>>(e); auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::PowerLevels>>(e);
if (!event) if (!event)
@ -1980,11 +1985,11 @@ TimelineModel::formatMemberEvent(const QString &id)
{ {
mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), ""); mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), "");
if (!e) if (!e)
return QString(); return {};
auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::Member>>(e); auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::Member>>(e);
if (!event) if (!event)
return QString(); return {};
mtx::events::StateEvent<mtx::events::state::Member> *prevEvent = nullptr; mtx::events::StateEvent<mtx::events::state::Member> *prevEvent = nullptr;
if (!event->unsigned_data.replaces_state.empty()) { if (!event->unsigned_data.replaces_state.empty()) {
@ -2038,7 +2043,7 @@ TimelineModel::formatMemberEvent(const QString &id)
break; break;
case Membership::Leave: case Membership::Leave:
if (!prevEvent) // Should only ever happen temporarily if (!prevEvent) // Should only ever happen temporarily
return QString(); return {};
if (prevEvent->content.membership == Membership::Invite) { if (prevEvent->content.membership == Membership::Invite) {
if (event->state_key == event->sender) if (event->state_key == event->sender)
@ -2163,7 +2168,7 @@ TimelineModel::roomName() const
auto info = cache::getRoomInfo({room_id_.toStdString()}); auto info = cache::getRoomInfo({room_id_.toStdString()});
if (!info.count(room_id_)) if (!info.count(room_id_))
return QString(); return {};
else else
return utils::replaceEmoji(QString::fromStdString(info[room_id_].name).toHtmlEscaped()); return utils::replaceEmoji(QString::fromStdString(info[room_id_].name).toHtmlEscaped());
} }
@ -2174,7 +2179,7 @@ TimelineModel::plainRoomName() const
auto info = cache::getRoomInfo({room_id_.toStdString()}); auto info = cache::getRoomInfo({room_id_.toStdString()});
if (!info.count(room_id_)) if (!info.count(room_id_))
return QString(); return {};
else else
return QString::fromStdString(info[room_id_].name); return QString::fromStdString(info[room_id_].name);
} }
@ -2185,7 +2190,7 @@ TimelineModel::roomAvatarUrl() const
auto info = cache::getRoomInfo({room_id_.toStdString()}); auto info = cache::getRoomInfo({room_id_.toStdString()});
if (!info.count(room_id_)) if (!info.count(room_id_))
return QString(); return {};
else else
return QString::fromStdString(info[room_id_].avatar_url); return QString::fromStdString(info[room_id_].avatar_url);
} }
@ -2196,7 +2201,7 @@ TimelineModel::roomTopic() const
auto info = cache::getRoomInfo({room_id_.toStdString()}); auto info = cache::getRoomInfo({room_id_.toStdString()});
if (!info.count(room_id_)) if (!info.count(room_id_))
return QString(); return {};
else else
return utils::replaceEmoji( return utils::replaceEmoji(
utils::linkifyMessage(QString::fromStdString(info[room_id_].topic).toHtmlEscaped())); utils::linkifyMessage(QString::fromStdString(info[room_id_].topic).toHtmlEscaped()));
@ -2244,5 +2249,5 @@ TimelineModel::directChatOtherUserId() const
id = member.user_id; id = member.user_id;
return id; return id;
} else } else
return QString(); return {};
} }

View file

@ -286,6 +286,7 @@ public:
{ {
auto list = events.reactions(event_id); auto list = events.reactions(event_id);
std::vector<::Reaction> vec; std::vector<::Reaction> vec;
vec.reserve(list.size());
for (const auto &r : list) for (const auto &r : list)
vec.push_back(r.value<Reaction>()); vec.push_back(r.value<Reaction>());
return vec; return vec;

View file

@ -103,10 +103,12 @@ TimelineViewManager::updateColorPalette()
if (ChatPage::instance()->userSettings()->theme() == QLatin1String("light")) { if (ChatPage::instance()->userSettings()->theme() == QLatin1String("light")) {
view->rootContext()->setContextProperty(QStringLiteral("currentActivePalette"), QPalette()); view->rootContext()->setContextProperty(QStringLiteral("currentActivePalette"), QPalette());
view->rootContext()->setContextProperty(QStringLiteral("currentInactivePalette"), QPalette()); view->rootContext()->setContextProperty(QStringLiteral("currentInactivePalette"),
QPalette());
} else if (ChatPage::instance()->userSettings()->theme() == QLatin1String("dark")) { } else if (ChatPage::instance()->userSettings()->theme() == QLatin1String("dark")) {
view->rootContext()->setContextProperty(QStringLiteral("currentActivePalette"), QPalette()); view->rootContext()->setContextProperty(QStringLiteral("currentActivePalette"), QPalette());
view->rootContext()->setContextProperty(QStringLiteral("currentInactivePalette"), QPalette()); view->rootContext()->setContextProperty(QStringLiteral("currentInactivePalette"),
QPalette());
} else { } else {
view->rootContext()->setContextProperty(QStringLiteral("currentActivePalette"), QPalette()); view->rootContext()->setContextProperty(QStringLiteral("currentActivePalette"), QPalette());
view->rootContext()->setContextProperty(QStringLiteral("currentInactivePalette"), nullptr); view->rootContext()->setContextProperty(QStringLiteral("currentInactivePalette"), nullptr);
@ -161,12 +163,20 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
qRegisterMetaType<std::vector<mtx::responses::PublicRoomsChunk>>(); qRegisterMetaType<std::vector<mtx::responses::PublicRoomsChunk>>();
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject,
qml_mtx_events::staticMetaObject, "im.nheko", 1, 0, "MtxEvent", QStringLiteral("Can't instantiate enum!")); "im.nheko",
1,
0,
"MtxEvent",
QStringLiteral("Can't instantiate enum!"));
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(
olm::staticMetaObject, "im.nheko", 1, 0, "Olm", QStringLiteral("Can't instantiate enum!")); olm::staticMetaObject, "im.nheko", 1, 0, "Olm", QStringLiteral("Can't instantiate enum!"));
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(crypto::staticMetaObject,
crypto::staticMetaObject, "im.nheko", 1, 0, "Crypto", QStringLiteral("Can't instantiate enum!")); "im.nheko",
1,
0,
"Crypto",
QStringLiteral("Can't instantiate enum!"));
qmlRegisterUncreatableMetaObject(verification::staticMetaObject, qmlRegisterUncreatableMetaObject(verification::staticMetaObject,
"im.nheko", "im.nheko",
1, 1,
@ -181,11 +191,23 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
qmlRegisterType<MxcAnimatedImage>("im.nheko", 1, 0, "MxcAnimatedImage"); qmlRegisterType<MxcAnimatedImage>("im.nheko", 1, 0, "MxcAnimatedImage");
qmlRegisterType<MxcMediaProxy>("im.nheko", 1, 0, "MxcMedia"); qmlRegisterType<MxcMediaProxy>("im.nheko", 1, 0, "MxcMedia");
qmlRegisterUncreatableType<DeviceVerificationFlow>( qmlRegisterUncreatableType<DeviceVerificationFlow>(
"im.nheko", 1, 0, "DeviceVerificationFlow", QStringLiteral("Can't create verification flow from QML!")); "im.nheko",
1,
0,
"DeviceVerificationFlow",
QStringLiteral("Can't create verification flow from QML!"));
qmlRegisterUncreatableType<UserProfile>( qmlRegisterUncreatableType<UserProfile>(
"im.nheko", 1, 0, "UserProfileModel", QStringLiteral("UserProfile needs to be instantiated on the C++ side")); "im.nheko",
1,
0,
"UserProfileModel",
QStringLiteral("UserProfile needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<MemberList>( qmlRegisterUncreatableType<MemberList>(
"im.nheko", 1, 0, "MemberList", QStringLiteral("MemberList needs to be instantiated on the C++ side")); "im.nheko",
1,
0,
"MemberList",
QStringLiteral("MemberList needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<RoomSettings>( qmlRegisterUncreatableType<RoomSettings>(
"im.nheko", "im.nheko",
1, 1,
@ -207,7 +229,11 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
"SingleImagePackModel", "SingleImagePackModel",
QStringLiteral("SingleImagePackModel needs to be instantiated on the C++ side")); QStringLiteral("SingleImagePackModel needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<InviteesModel>( qmlRegisterUncreatableType<InviteesModel>(
"im.nheko", 1, 0, "InviteesModel", QStringLiteral("InviteesModel needs to be instantiated on the C++ side")); "im.nheko",
1,
0,
"InviteesModel",
QStringLiteral("InviteesModel needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<ReadReceiptsProxy>( qmlRegisterUncreatableType<ReadReceiptsProxy>(
"im.nheko", "im.nheko",
1, 1,
@ -270,8 +296,12 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel"); qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
qmlRegisterUncreatableType<emoji::Emoji>( qmlRegisterUncreatableType<emoji::Emoji>(
"im.nheko.EmojiModel", 1, 0, "Emoji", QStringLiteral("Used by emoji models")); "im.nheko.EmojiModel", 1, 0, "Emoji", QStringLiteral("Used by emoji models"));
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(emoji::staticMetaObject,
emoji::staticMetaObject, "im.nheko.EmojiModel", 1, 0, "EmojiCategory", QStringLiteral("Error: Only enums")); "im.nheko.EmojiModel",
1,
0,
"EmojiCategory",
QStringLiteral("Error: Only enums"));
qmlRegisterType<RoomDirectoryModel>("im.nheko", 1, 0, "RoomDirectoryModel"); qmlRegisterType<RoomDirectoryModel>("im.nheko", 1, 0, "RoomDirectoryModel");
@ -404,10 +434,12 @@ TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId)
return; return;
} }
MxcImageProvider::download( MxcImageProvider::download(mxcUrl.remove(QStringLiteral("mxc://")),
mxcUrl.remove(QStringLiteral("mxc://")), QSize(), [this, eventId](QString, QSize, QImage img, QString) { QSize(),
[this, eventId](QString, QSize, QImage img, QString) {
if (img.isNull()) { if (img.isNull()) {
nhlog::ui()->error("Error when retrieving image for overlay."); nhlog::ui()->error(
"Error when retrieving image for overlay.");
return; return;
} }

View file

@ -28,8 +28,8 @@ void
Nheko::updateUserProfile() Nheko::updateUserProfile()
{ {
if (cache::client() && cache::client()->isInitialized()) if (cache::client() && cache::client()->isInitialized())
currentUser_.reset( currentUser_.reset(new UserProfile(
new UserProfile(QLatin1String(""), utils::localUser(), ChatPage::instance()->timelineManager())); QLatin1String(""), utils::localUser(), ChatPage::instance()->timelineManager()));
else else
currentUser_.reset(); currentUser_.reset();
emit profileChanged(); emit profileChanged();

View file

@ -234,8 +234,10 @@ RoomSettings::roomName() const
QString QString
RoomSettings::roomTopic() const RoomSettings::roomTopic() const
{ {
return utils::replaceEmoji(utils::linkifyMessage( return utils::replaceEmoji(
QString::fromStdString(info_.topic).toHtmlEscaped().replace(QLatin1String("\n"), QLatin1String("<br>")))); utils::linkifyMessage(QString::fromStdString(info_.topic)
.toHtmlEscaped()
.replace(QLatin1String("\n"), QLatin1String("<br>"))));
} }
QString QString

View file

@ -232,6 +232,7 @@ UserProfile::updateVerificationStatus()
this->isUserVerified = verificationStatus.user_verified; this->isUserVerified = verificationStatus.user_verified;
emit userStatusChanged(); emit userStatusChanged();
deviceInfo.reserve(devices.size());
for (const auto &d : devices) { for (const auto &d : devices) {
auto device = d.second; auto device = d.second;
verification::Status verified = verification::Status verified =
@ -244,9 +245,9 @@ UserProfile::updateVerificationStatus()
if (isSelf() && device.device_id == ::http::client()->device_id()) if (isSelf() && device.device_id == ::http::client()->device_id())
verified = verification::Status::SELF; verified = verification::Status::SELF;
deviceInfo.push_back({QString::fromStdString(d.first), deviceInfo.emplace_back(QString::fromStdString(d.first),
QString::fromStdString(device.unsigned_info.device_display_name), QString::fromStdString(device.unsigned_info.device_display_name),
verified}); verified);
} }
// For self, also query devices without keys // For self, also query devices without keys
@ -270,17 +271,17 @@ UserProfile::updateVerificationStatus()
found = true; found = true;
// Gottem! Let's fill in the blanks // Gottem! Let's fill in the blanks
e.lastIp = QString::fromStdString(d.last_seen_ip); e.lastIp = QString::fromStdString(d.last_seen_ip);
e.lastTs = d.last_seen_ts; e.lastTs = static_cast<qlonglong>(d.last_seen_ts);
break; break;
} }
} }
// No entry? Let's add one. // No entry? Let's add one.
if (!found) { if (!found) {
deviceInfo.push_back({QString::fromStdString(d.device_id), deviceInfo.emplace_back(QString::fromStdString(d.device_id),
QString::fromStdString(d.display_name), QString::fromStdString(d.display_name),
verification::NOT_APPLICABLE, verification::NOT_APPLICABLE,
QString::fromStdString(d.last_seen_ip), QString::fromStdString(d.last_seen_ip),
d.last_seen_ts}); d.last_seen_ts);
} }
} }

View file

@ -70,7 +70,8 @@ CallManager::CallManager(QObject *parent)
QTimer::singleShot(timeoutms_, this, [this, callid]() { QTimer::singleShot(timeoutms_, this, [this, callid]() {
if (session_.state() == webrtc::State::OFFERSENT && callid == callid_) { if (session_.state() == webrtc::State::OFFERSENT && callid == callid_) {
hangUp(CallHangUp::Reason::InviteTimeOut); hangUp(CallHangUp::Reason::InviteTimeOut);
emit ChatPage::instance()->showNotification(QStringLiteral("The remote side failed to pick up.")); emit ChatPage::instance()->showNotification(
QStringLiteral("The remote side failed to pick up."));
} }
}); });
}); });
@ -177,7 +178,8 @@ CallManager::sendInvite(const QString &roomid, CallType callType, unsigned int w
auto roomInfo = cache::singleRoomInfo(roomid.toStdString()); auto roomInfo = cache::singleRoomInfo(roomid.toStdString());
if (roomInfo.member_count != 2) { if (roomInfo.member_count != 2) {
emit ChatPage::instance()->showNotification(QStringLiteral("Calls are limited to 1:1 rooms.")); emit ChatPage::instance()->showNotification(
QStringLiteral("Calls are limited to 1:1 rooms."));
return; return;
} }
@ -291,7 +293,8 @@ CallManager::handleEvent(const RoomEvent<CallInvite> &callInviteEvent)
const QString &ringtone = ChatPage::instance()->userSettings()->ringtone(); const QString &ringtone = ChatPage::instance()->userSettings()->ringtone();
if (ringtone != QLatin1String("Mute")) if (ringtone != QLatin1String("Mute"))
playRingtone(ringtone == QLatin1String("Default") ? QUrl(QStringLiteral("qrc:/media/media/ring.ogg")) playRingtone(ringtone == QLatin1String("Default")
? QUrl(QStringLiteral("qrc:/media/media/ring.ogg"))
: QUrl::fromLocalFile(ringtone), : QUrl::fromLocalFile(ringtone),
true); true);
roomid_ = QString::fromStdString(callInviteEvent.room_id); roomid_ = QString::fromStdString(callInviteEvent.room_id);
@ -370,7 +373,8 @@ CallManager::handleEvent(const RoomEvent<CallAnswer> &callAnswerEvent)
if (callAnswerEvent.sender == utils::localUser().toStdString() && if (callAnswerEvent.sender == utils::localUser().toStdString() &&
callid_ == callAnswerEvent.content.call_id) { callid_ == callAnswerEvent.content.call_id) {
if (!isOnCall()) { if (!isOnCall()) {
emit ChatPage::instance()->showNotification(QStringLiteral("Call answered on another device.")); emit ChatPage::instance()->showNotification(
QStringLiteral("Call answered on another device."));
stopRingtone(); stopRingtone();
haveCallInvite_ = false; haveCallInvite_ = false;
emit newInviteState(); emit newInviteState();

View file

@ -44,12 +44,20 @@ WebRTCSession::WebRTCSession()
: devices_(CallDevices::instance()) : devices_(CallDevices::instance())
{ {
qRegisterMetaType<webrtc::CallType>(); qRegisterMetaType<webrtc::CallType>();
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
webrtc::staticMetaObject, "im.nheko", 1, 0, "CallType", QStringLiteral("Can't instantiate enum")); "im.nheko",
1,
0,
"CallType",
QStringLiteral("Can't instantiate enum"));
qRegisterMetaType<webrtc::State>(); qRegisterMetaType<webrtc::State>();
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
webrtc::staticMetaObject, "im.nheko", 1, 0, "WebRTCState", QStringLiteral("Can't instantiate enum")); "im.nheko",
1,
0,
"WebRTCState",
QStringLiteral("Can't instantiate enum"));
connect(this, &WebRTCSession::stateChanged, this, &WebRTCSession::setState); connect(this, &WebRTCSession::stateChanged, this, &WebRTCSession::setState);
init(); init();