From d8b89e2ef0a1a650a4bc249025ad6987cbf2176d Mon Sep 17 00:00:00 2001 From: lkito Date: Tue, 19 May 2020 23:04:38 +0400 Subject: [PATCH 01/24] Added an optional feature to show bigger emoji-only messages with 3 or less emoji --- resources/qml/TimelineView.qml | 2 ++ resources/qml/delegates/TextMessage.qml | 1 + src/UserSettingsPage.cpp | 42 +++++++++++++++---------- src/UserSettingsPage.h | 11 +++++++ src/Utils.cpp | 12 +++++-- src/Utils.h | 3 ++ src/timeline/TimelineModel.cpp | 18 +++++++++++ src/timeline/TimelineModel.h | 1 + 8 files changed, 71 insertions(+), 19 deletions(-) diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index b5097bc7..145a82ce 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -26,6 +26,7 @@ Page { category: "user" property bool avatar_circles: true property string emoji_font_family: "default" + property double font_size: Qt.application.font.pointSize } Settings { @@ -33,6 +34,7 @@ Page { category: "user/timeline" property bool buttons: true property bool message_hover_highlight: false + property bool enlarge_emoji_only_msg: false } Menu { diff --git a/resources/qml/delegates/TextMessage.qml b/resources/qml/delegates/TextMessage.qml index bef4f76d..d17723f3 100644 --- a/resources/qml/delegates/TextMessage.qml +++ b/resources/qml/delegates/TextMessage.qml @@ -6,4 +6,5 @@ MatrixText { width: parent ? parent.width : undefined height: isReply ? Math.min(chat.height / 8, implicitHeight) : undefined clip: true + font.pointSize: (timelineSettings.enlarge_emoji_only_msg && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? settings.font_size * 3 : settings.font_size } diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index 6af08e12..36fd768c 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -58,6 +58,8 @@ UserSettings::load() isButtonsInTimelineEnabled_ = settings.value("user/timeline/buttons", true).toBool(); isMessageHoverHighlightEnabled_ = settings.value("user/timeline/message_hover_highlight", false).toBool(); + isEnlargeEmojiOnlyMessagesEnabled_ = + settings.value("user/timeline/enlarge_emoji_only_msg", false).toBool(); isMarkdownEnabled_ = settings.value("user/markdown_enabled", true).toBool(); isTypingNotificationsEnabled_ = settings.value("user/typing_notifications", true).toBool(); sortByImportance_ = settings.value("user/sort_by_unread", true).toBool(); @@ -168,6 +170,7 @@ UserSettings::save() settings.beginGroup("timeline"); settings.setValue("buttons", isButtonsInTimelineEnabled_); settings.setValue("message_hover_highlight", isMessageHoverHighlightEnabled_); + settings.setValue("enlarge_emoji_only_msg", isEnlargeEmojiOnlyMessagesEnabled_); settings.endGroup(); settings.setValue("avatar_circles", avatarCircles_); @@ -231,22 +234,23 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge general_->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); general_->setFont(font); - trayToggle_ = new Toggle{this}; - startInTrayToggle_ = new Toggle{this}; - avatarCircles_ = new Toggle{this}; - decryptSidebar_ = new Toggle(this); - groupViewToggle_ = new Toggle{this}; - timelineButtonsToggle_ = new Toggle{this}; - typingNotifications_ = new Toggle{this}; - messageHoverHighlight_ = new Toggle{this}; - sortByImportance_ = new Toggle{this}; - readReceipts_ = new Toggle{this}; - markdownEnabled_ = new Toggle{this}; - desktopNotifications_ = new Toggle{this}; - scaleFactorCombo_ = new QComboBox{this}; - fontSizeCombo_ = new QComboBox{this}; - fontSelectionCombo_ = new QComboBox{this}; - emojiFontSelectionCombo_ = new QComboBox{this}; + trayToggle_ = new Toggle{this}; + startInTrayToggle_ = new Toggle{this}; + avatarCircles_ = new Toggle{this}; + decryptSidebar_ = new Toggle(this); + groupViewToggle_ = new Toggle{this}; + timelineButtonsToggle_ = new Toggle{this}; + typingNotifications_ = new Toggle{this}; + messageHoverHighlight_ = new Toggle{this}; + enlargeEmojiOnlyMessages_ = new Toggle{this}; + sortByImportance_ = new Toggle{this}; + readReceipts_ = new Toggle{this}; + markdownEnabled_ = new Toggle{this}; + desktopNotifications_ = new Toggle{this}; + scaleFactorCombo_ = new QComboBox{this}; + fontSizeCombo_ = new QComboBox{this}; + fontSelectionCombo_ = new QComboBox{this}; + emojiFontSelectionCombo_ = new QComboBox{this}; if (!settings_->isTrayEnabled()) startInTrayToggle_->setDisabled(true); @@ -350,6 +354,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge boxWrap(tr("Send messages as Markdown"), markdownEnabled_); boxWrap(tr("Desktop notifications"), desktopNotifications_); boxWrap(tr("Highlight message on hover"), messageHoverHighlight_); + boxWrap(tr("Large Emoji in timeline"), enlargeEmojiOnlyMessages_); formLayout_->addRow(uiLabel_); formLayout_->addRow(new HorizontalLine{this}); @@ -472,6 +477,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge settings_->setMessageHoverHighlight(!isDisabled); }); + connect(enlargeEmojiOnlyMessages_, &Toggle::toggled, this, [this](bool isDisabled) { + settings_->setEnlargeEmojiOnlyMessages(!isDisabled); + }); + connect( sessionKeysImportBtn, &QPushButton::clicked, this, &UserSettingsPage::importSessionKeys); @@ -505,6 +514,7 @@ UserSettingsPage::showEvent(QShowEvent *) markdownEnabled_->setState(!settings_->isMarkdownEnabled()); desktopNotifications_->setState(!settings_->hasDesktopNotifications()); messageHoverHighlight_->setState(!settings_->isMessageHoverHighlightEnabled()); + enlargeEmojiOnlyMessages_->setState(!settings_->isEnlargeEmojiOnlyMessagesEnabled()); deviceIdValue_->setText(QString::fromStdString(http::client()->device_id())); deviceFingerprintValue_->setText( diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index 088bbfb5..7dfa3913 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -49,6 +49,11 @@ public: isMessageHoverHighlightEnabled_ = state; save(); } + void setEnlargeEmojiOnlyMessages(bool state) + { + isEnlargeEmojiOnlyMessagesEnabled_ = state; + save(); + } void setTray(bool state) { isTrayEnabled_ = state; @@ -124,6 +129,10 @@ public: QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; } bool isMessageHoverHighlightEnabled() const { return isMessageHoverHighlightEnabled_; } + bool isEnlargeEmojiOnlyMessagesEnabled() const + { + return isEnlargeEmojiOnlyMessagesEnabled_; + } bool isTrayEnabled() const { return isTrayEnabled_; } bool isStartInTrayEnabled() const { return isStartInTrayEnabled_; } bool isGroupViewEnabled() const { return isGroupViewEnabled_; } @@ -151,6 +160,7 @@ private: : "system"; QString theme_; bool isMessageHoverHighlightEnabled_; + bool isEnlargeEmojiOnlyMessagesEnabled_; bool isTrayEnabled_; bool isStartInTrayEnabled_; bool isGroupViewEnabled_; @@ -211,6 +221,7 @@ private: Toggle *timelineButtonsToggle_; Toggle *typingNotifications_; Toggle *messageHoverHighlight_; + Toggle *enlargeEmojiOnlyMessages_; Toggle *sortByImportance_; Toggle *readReceipts_; Toggle *markdownEnabled_; diff --git a/src/Utils.cpp b/src/Utils.cpp index 7f11a8cd..d539eac5 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -51,6 +51,14 @@ utils::localUser() return QString::fromStdString(http::client()->user_id().to_string()); } +bool +utils::codepointIsEmoji(uint code) +{ + // TODO: Be more precise here. + return (code >= 0x2600 && code <= 0x27bf) || (code >= 0x1f300 && code <= 0x1f3ff) || + (code >= 0x1f000 && code <= 0x1faff); +} + QString utils::replaceEmoji(const QString &body) { @@ -63,9 +71,7 @@ utils::replaceEmoji(const QString &body) bool insideFontBlock = false; for (auto &code : utf32_string) { - // TODO: Be more precise here. - if ((code >= 0x2600 && code <= 0x27bf) || (code >= 0x1f300 && code <= 0x1f3ff) || - (code >= 0x1f000 && code <= 0x1faff)) { + if (utils::codepointIsEmoji(code)) { if (!insideFontBlock) { fmtBody += QString(""); insideFontBlock = true; diff --git a/src/Utils.h b/src/Utils.h index d3f66246..80f2aa70 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -36,6 +36,9 @@ namespace utils { using TimelineEvent = mtx::events::collections::TimelineEvents; +bool +codepointIsEmoji(uint code); + QString replaceEmoji(const QString &body); diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 6e653f10..6a4de92c 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -207,6 +207,7 @@ TimelineModel::roleNames() const {Section, "section"}, {Type, "type"}, {TypeString, "typeString"}, + {IsOnlyEmoji, "isOnlyEmoji"}, {Body, "body"}, {FormattedBody, "formattedBody"}, {UserId, "userId"}, @@ -272,6 +273,22 @@ TimelineModel::data(const QString &id, int role) const return QVariant(toRoomEventType(event)); case TypeString: return QVariant(toRoomEventTypeString(event)); + case IsOnlyEmoji: { + QString qBody = QString::fromStdString(body(event)); + + QVector utf32_string = qBody.toUcs4(); + int emojiCount = 0; + + for (auto &code : utf32_string) { + if (utils::codepointIsEmoji(code)) { + emojiCount++; + } else { + return QVariant(0); + } + } + + return QVariant(emojiCount); + } case Body: return QVariant(utils::replaceEmoji(QString::fromStdString(body(event)))); case FormattedBody: { @@ -374,6 +391,7 @@ TimelineModel::data(const QString &id, int role) const // m.insert(names[Section], data(id, static_cast(Section))); m.insert(names[Type], data(id, static_cast(Type))); m.insert(names[TypeString], data(id, static_cast(TypeString))); + m.insert(names[IsOnlyEmoji], data(id, static_cast(IsOnlyEmoji))); m.insert(names[Body], data(id, static_cast(Body))); m.insert(names[FormattedBody], data(id, static_cast(FormattedBody))); m.insert(names[UserId], data(id, static_cast(UserId))); diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 0e9ddb72..dc7b4985 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -140,6 +140,7 @@ public: Section, Type, TypeString, + IsOnlyEmoji, Body, FormattedBody, UserId, From 60ad6ce2772b1ce3b7d012e5b8767248d150f646 Mon Sep 17 00:00:00 2001 From: lkito Date: Sat, 23 May 2020 17:15:46 +0400 Subject: [PATCH 02/24] Added an option to have descriptions for user settings. --- src/UserSettingsPage.cpp | 74 ++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index 36fd768c..c151cad2 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -327,11 +327,15 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge sessionKeysLayout->addWidget(sessionKeysExportBtn, 0, Qt::AlignRight); sessionKeysLayout->addWidget(sessionKeysImportBtn, 0, Qt::AlignRight); - auto boxWrap = [this, &font](QString labelText, QWidget *field) { + auto boxWrap = [this, &font](QString labelText, QWidget *field, QString tooltipText = "") { auto label = new QLabel{labelText, this}; label->setFont(font); label->setMargin(OptionMargin); + if (!tooltipText.isEmpty()) { + label->setToolTip(tooltipText); + } + auto layout = new QHBoxLayout; layout->addWidget(field, 0, Qt::AlignRight); @@ -340,26 +344,66 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge formLayout_->addRow(general_); formLayout_->addRow(new HorizontalLine{this}); - boxWrap(tr("Minimize to tray"), trayToggle_); - boxWrap(tr("Start in tray"), startInTrayToggle_); + boxWrap( + tr("Minimize to tray"), + trayToggle_, + tr("Keep the application running in the background after closing the client window.")); + boxWrap(tr("Start in tray"), + startInTrayToggle_, + tr("Start the application in the background without showing the client window.")); formLayout_->addRow(new HorizontalLine{this}); - boxWrap(tr("Circular Avatars"), avatarCircles_); - boxWrap(tr("Group's sidebar"), groupViewToggle_); - boxWrap(tr("Decrypt messages in sidebar"), decryptSidebar_); - boxWrap(tr("Show buttons in timeline"), timelineButtonsToggle_); - boxWrap(tr("Typing notifications"), typingNotifications_); - boxWrap(tr("Sort rooms by unreads"), sortByImportance_); + boxWrap(tr("Circular Avatars"), + avatarCircles_, + tr("Change the appearance of user avatars in chats.\nOFF - square, ON - Circle.")); + boxWrap(tr("Group's sidebar"), + groupViewToggle_, + tr("Show a column containing groups and tags next to the room list.")); + boxWrap(tr("Decrypt messages in sidebar"), + decryptSidebar_, + tr("Decrypt the messages shown in the sidebar.\nOnly affects messages in " + "encrypted chats.")); + boxWrap(tr("Show buttons in timeline"), + timelineButtonsToggle_, + tr("Show buttons to quickly reply, react or access additional options next to each " + "message.")); + boxWrap(tr("Typing notifications"), + typingNotifications_, + tr("Show who is typing in a room.\nThis will also enable or disable sending typing " + "notifications to others.")); + boxWrap( + tr("Sort rooms by unreads"), + sortByImportance_, + tr( + "Display rooms with new messages first.\nIf this is off, the list of rooms will only " + "be sorted by the timestamp of the last message in a room.\nIf this is on, rooms which " + "have active notifications (the small circle with a number in it) will be sorted on " + "top. Rooms, that you have muted, will still be sorted by timestamp, since you don't " + "seem to consider them as important as the other rooms.")); formLayout_->addRow(new HorizontalLine{this}); - boxWrap(tr("Read receipts"), readReceipts_); - boxWrap(tr("Send messages as Markdown"), markdownEnabled_); - boxWrap(tr("Desktop notifications"), desktopNotifications_); - boxWrap(tr("Highlight message on hover"), messageHoverHighlight_); - boxWrap(tr("Large Emoji in timeline"), enlargeEmojiOnlyMessages_); + boxWrap(tr("Read receipts"), + readReceipts_, + tr("Show if your message was read.\nStatus is displayed next to timestamps.")); + boxWrap( + tr("Send messages as Markdown"), + markdownEnabled_, + tr("Allow using markdown in messages.\nWhen disabled, all messages are sent as a plain " + "text.")); + boxWrap(tr("Desktop notifications"), + desktopNotifications_, + tr("Notify about received message when the client is not currently focused.")); + boxWrap(tr("Highlight message on hover"), + messageHoverHighlight_, + tr("Change the background color of messages when you hover over them.")); + boxWrap(tr("Large Emoji in timeline"), + enlargeEmojiOnlyMessages_, + tr("Make font size larger if messages with only a few emojis are displayed.")); formLayout_->addRow(uiLabel_); formLayout_->addRow(new HorizontalLine{this}); #if !defined(Q_OS_MAC) - boxWrap(tr("Scale factor"), scaleFactorCombo_); + boxWrap(tr("Scale factor"), + scaleFactorCombo_, + tr("Change the scale factor of the whole user interface.")); #else scaleFactorCombo_->hide(); #endif From f7cd0c41378c74b7ffcd931c7852aa5c43d8222b Mon Sep 17 00:00:00 2001 From: Lorenzo Ancora Date: Tue, 26 May 2020 11:27:33 +0000 Subject: [PATCH 03/24] Added translation using Weblate (Italian) --- resources/langs/nheko_it.ts | 1553 +++++++++++++++++++++++++++++++++++ 1 file changed, 1553 insertions(+) create mode 100644 resources/langs/nheko_it.ts diff --git a/resources/langs/nheko_it.ts b/resources/langs/nheko_it.ts new file mode 100644 index 00000000..e599c01f --- /dev/null +++ b/resources/langs/nheko_it.ts @@ -0,0 +1,1553 @@ + + + + + Cache + + + You joined this room. + + + + + ChatPage + + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. + + + + + Room %1 created. + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + + Failed to upload media. Please try again. + + + + + Cache migration failed! + + + + + Incompatible cache version + + + + + The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. + + + + + Failed to restore OLM account. Please login again. + + + + + Failed to restore save data. Please login again. + + + + + Failed to setup encryption keys. Server response: %1 %2. Please try again later. + + + + + + Please try to login again: %1 + + + + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + + Room creation failed: %1 + + + + + Failed to leave room: %1 + + + + + CommunitiesListItem + + + All rooms + + + + + Favourite rooms + + + + + Low priority rooms + + + + + + (tag) + + + + + (community) + + + + + EditModal + + + Apply + + + + + Cancel + + + + + Name + + + + + Topic + + + + + EncryptionIndicator + + + Encrypted + + + + + This message is not encrypted! + + + + + InviteeItem + + + Remove + + + + + LoginPage + + + Matrix ID + + + + + e.g @joe:matrix.org + + + + + Your login name. A mxid should start with @ followed by the user id. After the user id you need to include your server name after a :. +You can also put your homeserver address there, if your server doesn't support .well-known lookup. +Example: @user:server.my +If Nheko fails to discover your homeserver, it will show you a field to enter the server manually. + + + + + Password + + + + + Device name + + + + + A name for this device, which will be shown to others, when verifying your devices. If none is provided, a random string is used for privacy purposes. + + + + + The address that can be used to contact you homeservers client API. +Example: https://server.my:8787 + + + + + + LOGIN + + + + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + + SSO LOGIN + + + + + Empty password + + + + + SSO login failed + + + + + MemberList + + + Room members + + + + + OK + + + + + MessageDelegate + + + redacted + + + + + Encryption enabled + + + + + room name changed to: %1 + + + + + removed room name + + + + + topic changed to: %1 + + + + + removed topic + + + + + %1 created and configured room: %2 + + + + + Placeholder + + + unimplemented event: + + + + + QuickSwitcher + + + Search for a room... + + + + + RegisterPage + + + Username + + + + + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. + + + + + Password + + + + + Please choose a secure password. The exact requirements for password strength may depend on your server. + + + + + Password confirmation + + + + + Homeserver + + + + + A server that allows registration. Since matrix is decentralized, you need to first find a server you can register on or host your own. + + + + + REGISTER + + + + + No supported registration flows! + + + + + Invalid username + + + + + Password is not long enough (min 8 chars) + + + + + Passwords don't match + + + + + Invalid server name + + + + + RoomInfo + + + no version stored + + + + + RoomInfoListItem + + + Leave room + + + + + Accept + + + + + Decline + + + + + SideBarActions + + + User settings + + + + + Create new room + + + + + Join a room + + + + + Start a new chat + + + + + Room directory + + + + + StatusIndicator + + + Failed + + + + + Sent + + + + + Received + + + + + Read + + + + + TextInputWidget + + + Send a file + + + + + + Write a message... + + + + + Send a message + + + + + Emoji + + + + + Select a file + + + + + All Files (*) + + + + + Connection lost. Nheko is trying to re-connect... + + + + + TimelineModel + + + -- Decryption Error (failed to communicate with DB) -- + Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + -- Decryption Error (%1) -- + Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. + + + + + Message redaction failed: %1 + + + + + Save image + + + + + Save video + + + + + Save audio + + + + + Save file + + + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Encrypted Event (Unknown event type) -- + Placeholder, when the message was decrypted, but we couldn't parse it, because Nheko/mtxclient don't support that event type yet. + + + + + %1 and %2 are typing. + Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) + + + + + + + + %1 opened the room to the public. + + + + + %1 made this room require and invitation to join. + + + + + %1 made the room open to guests. + + + + + %1 has closed the room to guest access. + + + + + %1 made the room history world readable. Events may be now read by non-joined people. + + + + + %1 set the room history visible to members from this point on. + + + + + %1 set the room history visible to members since they were invited. + + + + + %1 set the room history visible to members since they joined the room. + + + + + %1 has changed the room's permissions. + + + + + %1 was invited. + + + + + %1 changed their display name and avatar. + + + + + %1 changed their display name. + + + + + %1 changed their avatar. + + + + + %1 joined. + + + + + %1 rejected their invite. + + + + + Revoked the invite to %1. + + + + + %1 left the room. + + + + + Kicked %1. + + + + + Unbanned %1. + + + + + %1 was banned. + + + + + %1 redacted their knock. + + + + + You joined this room. + + + + + Rejected the knock from %1. + + + + + %1 left after having already left! + This is a leave event after the user already left and shouldn't happen apart from state resets + + + + + Reason: %1 + + + + + %1 knocked. + + + + + TimelineRow + + + Reply + + + + + Options + + + + + TimelineView + + + Reply + + + + + Read receipts + + + + + Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Redact message + + + + + Save as + + + + + No room open + + + + + Close + + + + + TopRoomBar + + + Room options + + + + + Mentions + + + + + Invite users + + + + + Members + + + + + Leave room + + + + + Settings + + + + + TrayIcon + + + Show + + + + + Quit + + + + + UserInfoWidget + + + Logout + + + + + UserSettingsPage + + + Minimize to tray + + + + + Start in tray + + + + + Group's sidebar + + + + + Circular Avatars + + + + + Decrypt messages in sidebar + + + + + Show buttons in timeline + + + + + Typing notifications + + + + + Sort rooms by unreads + + + + + Read receipts + + + + + Send messages as Markdown + + + + + Desktop notifications + + + + + Scale factor + + + + + Font size + + + + + Font Family + + + + + Theme + + + + + Device ID + + + + + Device Fingerprint + + + + + Session Keys + + + + + IMPORT + + + + + EXPORT + + + + + ENCRYPTION + + + + + GENERAL + + + + + INTERFACE + + + + + Emoji Font Family + + + + + Open Sessions File + + + + + + + + + + + + + + Error + + + + + + File Password + + + + + Enter the passphrase to decrypt the file: + + + + + + The password cannot be empty + + + + + Enter passphrase to encrypt your session keys: + + + + + File to save the exported session keys + + + + + WelcomePage + + + Welcome to nheko! The desktop client for the Matrix protocol. + + + + + Enjoy your stay! + + + + + REGISTER + + + + + LOGIN + + + + + descriptiveTime + + + Yesterday + + + + + dialogs::CreateRoom + + + Create room + + + + + Cancel + + + + + Name + + + + + Topic + + + + + Alias + + + + + Room Visibility + + + + + Room Preset + + + + + Direct Chat + + + + + dialogs::FallbackAuth + + + Open Fallback in Browser + + + + + Cancel + + + + + Confirm + + + + + Open the fallback, follow the steps and confirm after completing them. + + + + + dialogs::InviteUsers + + + Cancel + + + + + User ID to invite + + + + + dialogs::JoinRoom + + + Join + + + + + Cancel + + + + + Room ID or alias + + + + + dialogs::LeaveRoom + + + Cancel + + + + + Are you sure you want to leave? + + + + + dialogs::Logout + + + Cancel + + + + + Logout. Are you sure? + + + + + dialogs::PreviewUploadOverlay + + + Upload + + + + + Cancel + + + + + Media type: %1 +Media size: %2 + + + + + + dialogs::ReCaptcha + + + Cancel + + + + + Confirm + + + + + Solve the reCAPTCHA and press the confirm button + + + + + dialogs::ReadReceipts + + + Read receipts + + + + + Close + + + + + dialogs::ReceiptItem + + + Today %1 + + + + + Yesterday %1 + + + + + dialogs::RoomSettings + + + Settings + + + + + Info + + + + + Internal ID + + + + + Room Version + + + + + Notifications + + + + + Muted + + + + + Mentions only + + + + + All messages + + + + + Room access + + + + + Anyone and guests + + + + + Anyone + + + + + Invited users + + + + + Encryption + + + + + End-to-End Encryption + + + + + Encryption is currently experimental and things might break unexpectedly. <br>Please take note that it can't be disabled afterwards. + + + + + Respond to key requests + + + + + Whether or not the client should respond automatically with the session keys + upon request. Use with caution, this is a temporary measure to test the + E2E implementation until device verification is completed. + + + + + %n member(s) + + + + + + + + Failed to enable encryption: %1 + + + + + Select an avatar + + + + + All Files (*) + + + + + The selected file is not an image + + + + + Error while reading file: %1 + + + + + + Failed to upload image: %s + + + + + dialogs::UserProfile + + + Ban the user from the room + + + + + Ignore messages from this user + + + + + Kick the user from the room + + + + + Start a conversation + + + + + Devices + + + + + emoji::Panel + + + Smileys & People + + + + + Animals & Nature + + + + + Food & Drink + + + + + Activity + + + + + Travel & Places + + + + + Objects + + + + + Symbols + + + + + Flags + + + + + message-description sent: + + + You sent an audio clip + + + + + %1 sent an audio clip + + + + + You sent an image + + + + + %1 sent an image + + + + + You sent a file + + + + + %1 sent a file + + + + + You sent a video + + + + + %1 sent a video + + + + + You sent a sticker + + + + + %1 sent a sticker + + + + + You sent a notification + + + + + %1 sent a notification + + + + + You: %1 + + + + + %1: %2 + + + + + You sent an encrypted message + + + + + %1 sent an encrypted message + + + + + popups::UserMentions + + + This Room + + + + + All Rooms + + + + + utils + + + Unknown Message Type + + + + From 937b35ca8aeda51b564d4d957f8819228b7a17c1 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 23 May 2020 00:24:58 +0200 Subject: [PATCH 04/24] Fix some join messages showing as empty --- src/timeline/TimelineModel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 6a4de92c..b5b05768 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -1807,6 +1807,8 @@ TimelineModel::formatMemberEvent(QString id) rendered = tr("%1 changed their display name.").arg(name); else if (avatarChanged) rendered = tr("%1 changed their avatar.").arg(name); + else + rendered = tr("%1 changed some profile info.").arg(name); // the case of nothing changed but join follows join shouldn't happen, so // just show it as join } else { From 247539cb5a21814647aaf9f72031c000cbd49fe6 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 25 May 2020 11:12:01 +0200 Subject: [PATCH 05/24] Set cxx standard as cache variable for when toolchain file is not used --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5b046f4..91a4111b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,9 @@ set( CACHE FILEPATH "Default toolchain" ) - +set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard") +set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE BOOL "Require C++ standard to be supported") +set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "compile as PIC by default") option(HUNTER_ENABLED "Enable Hunter package manager" OFF) include("cmake/HunterGate.cmake") From fe45c49e56eb167d0dd950e473de7576cd333faf Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 25 May 2020 13:01:37 +0200 Subject: [PATCH 06/24] Bump singleapplication version --- CMakeLists.txt | 2 +- .../.gitignore | 9 +- .../CHANGELOG.md | 34 ++++++ .../CMakeLists.txt | 35 +++--- .../LICENSE | 2 +- .../README.md | 48 ++++++--- .../SingleApplication | 1 + .../Windows.md | 0 .../singleapplication.cpp | 18 +++- .../singleapplication.h | 18 +++- .../singleapplication.pri | 20 ++++ .../singleapplication_p.cpp | 102 +++++++++++------- .../singleapplication_p.h | 15 +-- 13 files changed, 213 insertions(+), 91 deletions(-) rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/.gitignore (58%) rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/CHANGELOG.md (91%) rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/CMakeLists.txt (52%) rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/LICENSE (96%) rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/README.md (93%) create mode 100644 third_party/SingleApplication-3.1.3.1/SingleApplication rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/Windows.md (100%) rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/singleapplication.cpp (93%) rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/singleapplication.h (91%) create mode 100644 third_party/SingleApplication-3.1.3.1/singleapplication.pri rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/singleapplication_p.cpp (85%) rename third_party/{SingleApplication-3.0.19 => SingleApplication-3.1.3.1}/singleapplication_p.h (92%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91a4111b..9a6a284b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -422,7 +422,7 @@ endif() # single instance functionality set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication") -add_subdirectory(third_party/SingleApplication-3.0.19/) +add_subdirectory(third_party/SingleApplication-3.1.3.1/) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/third_party/SingleApplication-3.0.19/.gitignore b/third_party/SingleApplication-3.1.3.1/.gitignore similarity index 58% rename from third_party/SingleApplication-3.0.19/.gitignore rename to third_party/SingleApplication-3.1.3.1/.gitignore index ad390758..35533fe8 100644 --- a/third_party/SingleApplication-3.0.19/.gitignore +++ b/third_party/SingleApplication-3.1.3.1/.gitignore @@ -6,4 +6,11 @@ /examples/basic/basic /examples/calculator/calculator /examples/sending_arguments/sending_arguments -CMakeLists.txt.user +/**/CMakeLists.txt.user +/**/CMakeCache.txt +/**/CMakeCache/* +/**/CMakeFiles/* +/**/Makefile +/**/cmake_install.cmake +/**/*_autogen/ +libSingleApplication.a diff --git a/third_party/SingleApplication-3.0.19/CHANGELOG.md b/third_party/SingleApplication-3.1.3.1/CHANGELOG.md similarity index 91% rename from third_party/SingleApplication-3.0.19/CHANGELOG.md rename to third_party/SingleApplication-3.1.3.1/CHANGELOG.md index 36f1e261..3662b0b2 100644 --- a/third_party/SingleApplication-3.0.19/CHANGELOG.md +++ b/third_party/SingleApplication-3.1.3.1/CHANGELOG.md @@ -1,6 +1,40 @@ Changelog ========= +If by accident I have forgotten to credit someone in the CHANGELOG, email me and I will fix it. + +__3.1.3.1__ +--------- +* CMake build system improvements +* Fixed Clang Tidy warnings + + _Hennadii Chernyshchyk_ + +__3.1.3__ +--------- +* Improved `CMakeLists.txt` + + _Hennadii Chernyshchyk_ + +__3.1.2__ +--------- + +* Fix a crash when exiting an application on Android and iOS + + _Emeric Grange_ + +__3.1.1a__ +---------- + +* Added currentUser() method that returns the user the current instance is running as. + + _Leander Schulten_ + +__3.1.0a__ +---------- + +* Added primaryUser() method that returns the user the primary instance is running as. + __3.0.19__ ---------- diff --git a/third_party/SingleApplication-3.0.19/CMakeLists.txt b/third_party/SingleApplication-3.1.3.1/CMakeLists.txt similarity index 52% rename from third_party/SingleApplication-3.0.19/CMakeLists.txt rename to third_party/SingleApplication-3.1.3.1/CMakeLists.txt index 076d514d..85dba84c 100644 --- a/third_party/SingleApplication-3.0.19/CMakeLists.txt +++ b/third_party/SingleApplication-3.1.3.1/CMakeLists.txt @@ -1,45 +1,34 @@ -cmake_minimum_required(VERSION 3.1.0) +cmake_minimum_required(VERSION 3.7.0) -project(SingleApplication) +project(SingleApplication LANGUAGES CXX) -set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -# SingleApplication base class -set(QAPPLICATION_CLASS QCoreApplication CACHE STRING "Inheritance class for SingleApplication") -set_property(CACHE QAPPLICATION_CLASS PROPERTY STRINGS QApplication QGuiApplication QCoreApplication) - -# Libary target add_library(${PROJECT_NAME} STATIC singleapplication.cpp singleapplication_p.cpp - ) +) +add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) # Find dependencies -find_package(Qt5Network) +find_package(Qt5 COMPONENTS Network REQUIRED) +target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Network) + if(QAPPLICATION_CLASS STREQUAL QApplication) find_package(Qt5 COMPONENTS Widgets REQUIRED) + target_link_libraries(${PROJECT_NAME} PUBLIC Qt5::Widgets) elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication) find_package(Qt5 COMPONENTS Gui REQUIRED) + target_link_libraries(${PROJECT_NAME} PUBLIC Qt5::Gui) else() + set(QAPPLICATION_CLASS QCoreApplication) find_package(Qt5 COMPONENTS Core REQUIRED) -endif() -target_compile_definitions(${PROJECT_NAME} PUBLIC QAPPLICATION_CLASS=${QAPPLICATION_CLASS}) - -# Link dependencies -target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Network) -if(QAPPLICATION_CLASS STREQUAL QApplication) - target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets) -elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication) - target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Gui) -else() - target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core) + target_link_libraries(${PROJECT_NAME} PUBLIC Qt5::Core) endif() if(WIN32) target_link_libraries(${PROJECT_NAME} PRIVATE advapi32) endif() +target_compile_definitions(${PROJECT_NAME} PUBLIC QAPPLICATION_CLASS=${QAPPLICATION_CLASS}) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - -add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) diff --git a/third_party/SingleApplication-3.0.19/LICENSE b/third_party/SingleApplication-3.1.3.1/LICENSE similarity index 96% rename from third_party/SingleApplication-3.0.19/LICENSE rename to third_party/SingleApplication-3.1.3.1/LICENSE index 85b2a149..a82e5a68 100644 --- a/third_party/SingleApplication-3.0.19/LICENSE +++ b/third_party/SingleApplication-3.1.3.1/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) Itay Grudev 2015 - 2016 +Copyright (c) Itay Grudev 2015 - 2020 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/third_party/SingleApplication-3.0.19/README.md b/third_party/SingleApplication-3.1.3.1/README.md similarity index 93% rename from third_party/SingleApplication-3.0.19/README.md rename to third_party/SingleApplication-3.1.3.1/README.md index 5d609865..3c36b557 100644 --- a/third_party/SingleApplication-3.0.19/README.md +++ b/third_party/SingleApplication-3.1.3.1/README.md @@ -1,5 +1,6 @@ SingleApplication ================= +[![CI](https://github.com/itay-grudev/SingleApplication/workflows/CI:%20Build%20Test/badge.svg)](https://github.com/itay-grudev/SingleApplication/actions) This is a replacement of the QtSingleApplication for `Qt5`. @@ -15,18 +16,6 @@ class you specify via the `QAPPLICATION_CLASS` macro (`QCoreApplication` is the default). Further usage is similar to the use of the `Q[Core|Gui]Application` classes. -The library sets up a `QLocalServer` and a `QSharedMemory` block. The first -instance of your Application is your Primary Instance. It would check if the -shared memory block exists and if not it will start a `QLocalServer` and listen -for connections. Each subsequent instance of your application would check if the -shared memory block exists and if it does, it will connect to the QLocalServer -to notify the primary instance that a new instance had been started, after which -it would terminate with status code `0`. In the Primary Instance -`SingleApplication` would emit the `instanceStarted()` signal upon detecting -that a new instance had been started. - -The library uses `stdlib` to terminate the program with the `exit()` function. - You can use the library as if you use any other `QCoreApplication` derived class: @@ -43,8 +32,7 @@ int main( int argc, char* argv[] ) ``` To include the library files I would recommend that you add it as a git -submodule to your project and include it's contents with a `.pri` file. Here is -how: +submodule to your project. Here is how: ```bash git submodule add git@github.com:itay-grudev/SingleApplication.git singleapplication @@ -66,13 +54,27 @@ Then include the subdirectory in your `CMakeLists.txt` project file. ```cmake set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication") add_subdirectory(src/third-party/singleapplication) +target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication) ``` + +The library sets up a `QLocalServer` and a `QSharedMemory` block. The first +instance of your Application is your Primary Instance. It would check if the +shared memory block exists and if not it will start a `QLocalServer` and listen +for connections. Each subsequent instance of your application would check if the +shared memory block exists and if it does, it will connect to the QLocalServer +to notify the primary instance that a new instance had been started, after which +it would terminate with status code `0`. In the Primary Instance +`SingleApplication` would emit the `instanceStarted()` signal upon detecting +that a new instance had been started. + +The library uses `stdlib` to terminate the program with the `exit()` function. + Also don't forget to specify which `QCoreApplication` class your app is using if it is not `QCoreApplication` as in examples above. The `Instance Started` signal ------------------------- +----------------------------- The SingleApplication class implements a `instanceStarted()` signal. You can bind to that signal to raise your application's window when a new instance had @@ -204,6 +206,22 @@ qint64 SingleApplication::primaryPid() Returns the process ID (PID) of the primary instance. +--- + +```cpp +QString SingleApplication::primaryUser() +``` + +Returns the username the primary instance is running as. + +--- + +```cpp +QString SingleApplication::currentUser() +``` + +Returns the username the current instance is running as. + ### Signals ```cpp diff --git a/third_party/SingleApplication-3.1.3.1/SingleApplication b/third_party/SingleApplication-3.1.3.1/SingleApplication new file mode 100644 index 00000000..8ead1a42 --- /dev/null +++ b/third_party/SingleApplication-3.1.3.1/SingleApplication @@ -0,0 +1 @@ +#include "singleapplication.h" diff --git a/third_party/SingleApplication-3.0.19/Windows.md b/third_party/SingleApplication-3.1.3.1/Windows.md similarity index 100% rename from third_party/SingleApplication-3.0.19/Windows.md rename to third_party/SingleApplication-3.1.3.1/Windows.md diff --git a/third_party/SingleApplication-3.0.19/singleapplication.cpp b/third_party/SingleApplication-3.1.3.1/singleapplication.cpp similarity index 93% rename from third_party/SingleApplication-3.0.19/singleapplication.cpp rename to third_party/SingleApplication-3.1.3.1/singleapplication.cpp index 8ff8747a..9af38804 100644 --- a/third_party/SingleApplication-3.0.19/singleapplication.cpp +++ b/third_party/SingleApplication-3.1.3.1/singleapplication.cpp @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) Itay Grudev 2015 - 2018 +// Copyright (c) Itay Grudev 2015 - 2020 // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -85,7 +85,7 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda } } - InstancesInfo* inst = static_cast( d->memory->data() ); + auto *inst = static_cast( d->memory->data() ); QElapsedTimer time; time.start(); @@ -172,7 +172,19 @@ qint64 SingleApplication::primaryPid() return d->primaryPid(); } -bool SingleApplication::sendMessage( QByteArray message, int timeout ) +QString SingleApplication::primaryUser() +{ + Q_D(SingleApplication); + return d->primaryUser(); +} + +QString SingleApplication::currentUser() +{ + Q_D(SingleApplication); + return d->getUsername(); +} + +bool SingleApplication::sendMessage( const QByteArray &message, int timeout ) { Q_D(SingleApplication); diff --git a/third_party/SingleApplication-3.0.19/singleapplication.h b/third_party/SingleApplication-3.1.3.1/singleapplication.h similarity index 91% rename from third_party/SingleApplication-3.0.19/singleapplication.h rename to third_party/SingleApplication-3.1.3.1/singleapplication.h index cb505971..fd806a3d 100644 --- a/third_party/SingleApplication-3.0.19/singleapplication.h +++ b/third_party/SingleApplication-3.1.3.1/singleapplication.h @@ -43,7 +43,7 @@ class SingleApplication : public QAPPLICATION_CLASS { Q_OBJECT - typedef QAPPLICATION_CLASS app_t; + using app_t = QAPPLICATION_CLASS; public: /** @@ -86,7 +86,7 @@ public: * @see See the corresponding QAPPLICATION_CLASS constructor for reference */ explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000 ); - ~SingleApplication(); + ~SingleApplication() override; /** * @brief Returns if the instance is the primary instance @@ -112,6 +112,18 @@ public: */ qint64 primaryPid(); + /** + * @brief Returns the username of the user running the primary instance + * @returns {QString} + */ + QString primaryUser(); + + /** + * @brief Returns the username of the current user + * @returns {QString} + */ + QString currentUser(); + /** * @brief Sends a message to the primary instance. Returns true on success. * @param {int} timeout - Timeout for connecting @@ -119,7 +131,7 @@ public: * @note sendMessage() will return false if invoked from the primary * instance. */ - bool sendMessage( QByteArray message, int timeout = 100 ); + bool sendMessage( const QByteArray &message, int timeout = 100 ); Q_SIGNALS: void instanceStarted(); diff --git a/third_party/SingleApplication-3.1.3.1/singleapplication.pri b/third_party/SingleApplication-3.1.3.1/singleapplication.pri new file mode 100644 index 00000000..ae81f599 --- /dev/null +++ b/third_party/SingleApplication-3.1.3.1/singleapplication.pri @@ -0,0 +1,20 @@ +QT += core network +CONFIG += c++11 + +HEADERS += $$PWD/SingleApplication \ + $$PWD/singleapplication.h \ + $$PWD/singleapplication_p.h +SOURCES += $$PWD/singleapplication.cpp \ + $$PWD/singleapplication_p.cpp + +INCLUDEPATH += $$PWD + +win32 { + msvc:LIBS += Advapi32.lib + gcc:LIBS += -ladvapi32 +} + +DISTFILES += \ + $$PWD/README.md \ + $$PWD/CHANGELOG.md \ + $$PWD/Windows.md diff --git a/third_party/SingleApplication-3.0.19/singleapplication_p.cpp b/third_party/SingleApplication-3.1.3.1/singleapplication_p.cpp similarity index 85% rename from third_party/SingleApplication-3.0.19/singleapplication_p.cpp rename to third_party/SingleApplication-3.1.3.1/singleapplication_p.cpp index 884fe631..705609f2 100644 --- a/third_party/SingleApplication-3.0.19/singleapplication_p.cpp +++ b/third_party/SingleApplication-3.1.3.1/singleapplication_p.cpp @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) Itay Grudev 2015 - 2018 +// Copyright (c) Itay Grudev 2015 - 2020 // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -69,18 +69,52 @@ SingleApplicationPrivate::~SingleApplicationPrivate() delete socket; } - memory->lock(); - InstancesInfo* inst = static_cast(memory->data()); - if( server != nullptr ) { - server->close(); - delete server; - inst->primary = false; - inst->primaryPid = -1; - inst->checksum = blockChecksum(); - } - memory->unlock(); + if( memory != nullptr ) { + memory->lock(); + auto *inst = static_cast(memory->data()); + if( server != nullptr ) { + server->close(); + delete server; + inst->primary = false; + inst->primaryPid = -1; + inst->primaryUser[0] = '\0'; + inst->checksum = blockChecksum(); + } + memory->unlock(); - delete memory; + delete memory; + } +} + +QString SingleApplicationPrivate::getUsername() +{ +#ifdef Q_OS_WIN + wchar_t username[UNLEN + 1]; + // Specifies size of the buffer on input + DWORD usernameLength = UNLEN + 1; + if( GetUserNameW( username, &usernameLength ) ) + return QString::fromWCharArray( username ); +#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) + return QString::fromLocal8Bit( qgetenv( "USERNAME" ) ); +#else + return qEnvironmentVariable( "USERNAME" ); +#endif +#endif +#ifdef Q_OS_UNIX + QString username; + uid_t uid = geteuid(); + struct passwd *pw = getpwuid( uid ); + if( pw ) + username = QString::fromLocal8Bit( pw->pw_name ); + if ( username.isEmpty() ) { +#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) + username = QString::fromLocal8Bit( qgetenv( "USER" ) ); +#else + username = qEnvironmentVariable( "USER" ); +#endif + } + return username; +#endif } void SingleApplicationPrivate::genBlockServerName() @@ -105,28 +139,7 @@ void SingleApplicationPrivate::genBlockServerName() // User level block requires a user specific data in the hash if( options & SingleApplication::Mode::User ) { -#ifdef Q_OS_WIN - wchar_t username [ UNLEN + 1 ]; - // Specifies size of the buffer on input - DWORD usernameLength = UNLEN + 1; - if( GetUserNameW( username, &usernameLength ) ) { - appData.addData( QString::fromWCharArray(username).toUtf8() ); - } else { - appData.addData( qgetenv("USERNAME") ); - } -#endif -#ifdef Q_OS_UNIX - QByteArray username; - uid_t uid = geteuid(); - struct passwd *pw = getpwuid(uid); - if( pw ) { - username = pw->pw_name; - } - if( username.isEmpty() ) { - username = qgetenv("USER"); - } - appData.addData(username); -#endif + appData.addData( getUsername().toUtf8() ); } // Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with @@ -136,10 +149,11 @@ void SingleApplicationPrivate::genBlockServerName() void SingleApplicationPrivate::initializeMemoryBlock() { - InstancesInfo* inst = static_cast( memory->data() ); + auto *inst = static_cast( memory->data() ); inst->primary = false; inst->secondary = 0; inst->primaryPid = -1; + inst->primaryUser[0] = '\0'; inst->checksum = blockChecksum(); } @@ -169,10 +183,12 @@ void SingleApplicationPrivate::startPrimary() ); // Reset the number of connections - InstancesInfo* inst = static_cast ( memory->data() ); + auto *inst = static_cast ( memory->data() ); inst->primary = true; inst->primaryPid = q->applicationPid(); + strncpy( inst->primaryUser, getUsername().toUtf8().data(), 127 ); + inst->primaryUser[127] = '\0'; inst->checksum = blockChecksum(); instanceNumber = 0; @@ -250,13 +266,25 @@ qint64 SingleApplicationPrivate::primaryPid() qint64 pid; memory->lock(); - InstancesInfo* inst = static_cast( memory->data() ); + auto *inst = static_cast( memory->data() ); pid = inst->primaryPid; memory->unlock(); return pid; } +QString SingleApplicationPrivate::primaryUser() +{ + QByteArray username; + + memory->lock(); + auto *inst = static_cast( memory->data() ); + username = inst->primaryUser; + memory->unlock(); + + return QString::fromUtf8( username ); +} + /** * @brief Executed when a connection has been made to the LocalServer */ diff --git a/third_party/SingleApplication-3.0.19/singleapplication_p.h b/third_party/SingleApplication-3.1.3.1/singleapplication_p.h similarity index 92% rename from third_party/SingleApplication-3.0.19/singleapplication_p.h rename to third_party/SingleApplication-3.1.3.1/singleapplication_p.h index e2c361fb..29ba346b 100644 --- a/third_party/SingleApplication-3.0.19/singleapplication_p.h +++ b/third_party/SingleApplication-3.1.3.1/singleapplication_p.h @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) Itay Grudev 2015 - 2016 +// Copyright (c) Itay Grudev 2015 - 2020 // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -42,14 +42,13 @@ struct InstancesInfo { quint32 secondary; qint64 primaryPid; quint16 checksum; + char primaryUser[128]; }; struct ConnectionInfo { - explicit ConnectionInfo() : - msgLen(0), instanceId(0), stage(0) {} - qint64 msgLen; - quint32 instanceId; - quint8 stage; + qint64 msgLen = 0; + quint32 instanceId = 0; + quint8 stage = 0; }; class SingleApplicationPrivate : public QObject { @@ -69,8 +68,9 @@ public: Q_DECLARE_PUBLIC(SingleApplication) SingleApplicationPrivate( SingleApplication *q_ptr ); - ~SingleApplicationPrivate(); + ~SingleApplicationPrivate() override; + QString getUsername(); void genBlockServerName(); void initializeMemoryBlock(); void startPrimary(); @@ -78,6 +78,7 @@ public: void connectToPrimary(int msecs, ConnectionType connectionType ); quint16 blockChecksum(); qint64 primaryPid(); + QString primaryUser(); void readInitMessageHeader(QLocalSocket *socket); void readInitMessageBody(QLocalSocket *socket); From 4e5bd53b1329896da6b4344815def48c7800f198 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 25 May 2020 13:02:31 +0200 Subject: [PATCH 07/24] Optionally use precompiled headers --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a6a284b..0e0a5518 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -577,6 +577,13 @@ target_link_libraries(nheko PRIVATE tweeny SingleApplication::SingleApplication) +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0") +target_precompile_headers(nheko + PRIVATE + + ) +endif() + if(MSVC) target_link_libraries(nheko PRIVATE ntdll) endif() From 4ee9e5c27ce1788db42728ace2df2b4c6aa9ceed Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 25 May 2020 13:03:49 +0200 Subject: [PATCH 08/24] Improve compile times a tiny bit --- src/CommunitiesListItem.h | 1 - src/InviteeItem.cpp | 1 + src/InviteeItem.h | 2 +- src/LoginPage.cpp | 9 ++++++++- src/LoginPage.h | 7 ++++--- src/RegisterPage.cpp | 1 + src/RegisterPage.h | 7 +++++-- src/RoomList.cpp | 2 ++ src/SideBarActions.cpp | 2 ++ src/TopRoomBar.h | 1 - src/UserInfoWidget.cpp | 3 +++ src/UserInfoWidget.h | 7 +++++-- src/UserSettingsPage.h | 9 +++++---- src/dialogs/InviteUsers.cpp | 1 + src/dialogs/InviteUsers.h | 4 ++-- src/dialogs/ReadReceipts.cpp | 8 ++++++++ src/dialogs/ReadReceipts.h | 14 +++++--------- src/dialogs/RoomSettings.cpp | 34 ++++++++++++++++++++++++++++++++++ src/dialogs/RoomSettings.h | 35 ++++++----------------------------- src/emoji/Category.cpp | 3 +++ src/emoji/Category.h | 9 +++++---- src/popups/PopupItem.cpp | 1 + src/popups/PopupItem.h | 5 ++--- src/popups/SuggestionsPopup.h | 3 --- 24 files changed, 104 insertions(+), 65 deletions(-) diff --git a/src/CommunitiesListItem.h b/src/CommunitiesListItem.h index 0cc5d60c..535a6ec0 100644 --- a/src/CommunitiesListItem.h +++ b/src/CommunitiesListItem.h @@ -7,7 +7,6 @@ #include "ui/Theme.h" class RippleOverlay; -class QPainter; class QMouseEvent; class CommunitiesListItem : public QWidget diff --git a/src/InviteeItem.cpp b/src/InviteeItem.cpp index 906a3bfe..a6b471dc 100644 --- a/src/InviteeItem.cpp +++ b/src/InviteeItem.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "InviteeItem.h" diff --git a/src/InviteeItem.h b/src/InviteeItem.h index 582904b4..54c61938 100644 --- a/src/InviteeItem.h +++ b/src/InviteeItem.h @@ -1,11 +1,11 @@ #pragma once -#include #include #include class QPushButton; +class QLabel; class InviteeItem : public QWidget { diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp index bb329699..4ed08901 100644 --- a/src/LoginPage.cpp +++ b/src/LoginPage.cpp @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -118,7 +119,7 @@ LoginPage::LoginPage(QWidget *parent) deviceName_->setLabel(tr("Device name")); deviceName_->setToolTip( tr("A name for this device, which will be shown to others, when verifying your devices. " - "If none is provided, a random string is used for privacy purposes.")); + "If none is provided a default is used.")); serverInput_ = new TextField(this); serverInput_->setLabel("Homeserver address"); @@ -179,6 +180,12 @@ LoginPage::LoginPage(QWidget *parent) connect(serverInput_, SIGNAL(editingFinished()), this, SLOT(onServerAddressEntered())); } +void +LoginPage::loginError(const QString &msg) +{ + error_label_->setText(msg); +} + void LoginPage::onMatrixIdEntered() { diff --git a/src/LoginPage.h b/src/LoginPage.h index 8a402aea..c9220297 100644 --- a/src/LoginPage.h +++ b/src/LoginPage.h @@ -17,8 +17,6 @@ #pragma once -#include -#include #include class FlatButton; @@ -26,6 +24,9 @@ class LoadingIndicator; class OverlayModal; class RaisedButton; class TextField; +class QLabel; +class QVBoxLayout; +class QHBoxLayout; namespace mtx { namespace responses { @@ -65,7 +66,7 @@ protected: public slots: // Displays errors produced during the login. - void loginError(const QString &msg) { error_label_->setText(msg); } + void loginError(const QString &msg); private slots: // Callback for the back button. diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp index 03e9ab34..e57961ef 100644 --- a/src/RegisterPage.cpp +++ b/src/RegisterPage.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +#include #include #include #include diff --git a/src/RegisterPage.h b/src/RegisterPage.h index ebc24bb1..59ba3d1d 100644 --- a/src/RegisterPage.h +++ b/src/RegisterPage.h @@ -17,8 +17,8 @@ #pragma once -#include -#include +#include + #include #include @@ -26,6 +26,9 @@ class FlatButton; class RaisedButton; class TextField; +class QLabel; +class QVBoxLayout; +class QHBoxLayout; class RegisterPage : public QWidget { diff --git a/src/RoomList.cpp b/src/RoomList.cpp index 85a22026..b4c507b5 100644 --- a/src/RoomList.cpp +++ b/src/RoomList.cpp @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include "Logging.h" diff --git a/src/SideBarActions.cpp b/src/SideBarActions.cpp index 4934ec05..5af01cc2 100644 --- a/src/SideBarActions.cpp +++ b/src/SideBarActions.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include diff --git a/src/TopRoomBar.h b/src/TopRoomBar.h index 1aa5934b..0c33c1e0 100644 --- a/src/TopRoomBar.h +++ b/src/TopRoomBar.h @@ -27,7 +27,6 @@ class Menu; class TextLabel; class OverlayModal; -class QPainter; class QLabel; class QHBoxLayout; class QVBoxLayout; diff --git a/src/UserInfoWidget.cpp b/src/UserInfoWidget.cpp index 2e21d41f..e11aa6aa 100644 --- a/src/UserInfoWidget.cpp +++ b/src/UserInfoWidget.cpp @@ -16,7 +16,10 @@ * along with this program. If not, see . */ +#include #include +#include +#include #include #include diff --git a/src/UserInfoWidget.h b/src/UserInfoWidget.h index e1a925a4..575ade52 100644 --- a/src/UserInfoWidget.h +++ b/src/UserInfoWidget.h @@ -17,13 +17,16 @@ #pragma once -#include -#include +#include class Avatar; class FlatButton; class OverlayModal; +class QLabel; +class QHBoxLayout; +class QVBoxLayout; + class UserInfoWidget : public QWidget { Q_OBJECT diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index 7dfa3913..f80c2b2b 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -17,17 +17,18 @@ #pragma once -#include #include -#include #include -#include -#include #include #include #include class Toggle; +class QLabel; +class QFormLayout; +class QComboBox; +class QHBoxLayout; +class QVBoxLayout; constexpr int OptionMargin = 6; constexpr int LayoutTopMargin = 50; diff --git a/src/dialogs/InviteUsers.cpp b/src/dialogs/InviteUsers.cpp index 691035ce..f85adb8f 100644 --- a/src/dialogs/InviteUsers.cpp +++ b/src/dialogs/InviteUsers.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/src/dialogs/InviteUsers.h b/src/dialogs/InviteUsers.h index 952c97a5..684f60b4 100644 --- a/src/dialogs/InviteUsers.h +++ b/src/dialogs/InviteUsers.h @@ -1,13 +1,13 @@ #pragma once #include -#include -#include #include class QPushButton; +class QLabel; class TextField; class QListWidget; +class QListWidgetItem; namespace dialogs { diff --git a/src/dialogs/ReadReceipts.cpp b/src/dialogs/ReadReceipts.cpp index 0edd1ebf..970d9125 100644 --- a/src/dialogs/ReadReceipts.cpp +++ b/src/dialogs/ReadReceipts.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -163,3 +164,10 @@ ReadReceipts::paintEvent(QPaintEvent *) QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } + +void +ReadReceipts::hideEvent(QHideEvent *event) +{ + userList_->clear(); + QFrame::hideEvent(event); +} diff --git a/src/dialogs/ReadReceipts.h b/src/dialogs/ReadReceipts.h index e298af0a..2e7a0217 100644 --- a/src/dialogs/ReadReceipts.h +++ b/src/dialogs/ReadReceipts.h @@ -2,12 +2,12 @@ #include #include -#include -#include -#include -#include class Avatar; +class QLabel; +class QListWidget; +class QHBoxLayout; +class QVBoxLayout; namespace dialogs { @@ -47,11 +47,7 @@ public slots: protected: void paintEvent(QPaintEvent *event) override; - void hideEvent(QHideEvent *event) override - { - userList_->clear(); - QFrame::hideEvent(event); - } + void hideEvent(QHideEvent *event) override; private: QLabel *topLabel_; diff --git a/src/dialogs/RoomSettings.cpp b/src/dialogs/RoomSettings.cpp index cc10ac91..26aece32 100644 --- a/src/dialogs/RoomSettings.cpp +++ b/src/dialogs/RoomSettings.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -41,6 +42,17 @@ constexpr int WIDGET_SPACING = 15; constexpr int TEXT_SPACING = 4; constexpr int BUTTON_SPACING = 2 * TEXT_SPACING; +bool +ClickableFilter::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonRelease) { + emit clicked(); + return true; + } + + return QObject::eventFilter(obj, event); +} + EditModal::EditModal(const QString &roomId, QWidget *parent) : QWidget(parent) , roomId_{roomId} @@ -93,6 +105,28 @@ EditModal::EditModal(const QString &roomId, QWidget *parent) move(center.x() - (width() * 0.5), center.y() - (height() * 0.5)); } +void +EditModal::topicEventSent() +{ + errorField_->hide(); + close(); +} + +void +EditModal::nameEventSent(const QString &name) +{ + errorField_->hide(); + emit nameChanged(name); + close(); +} + +void +EditModal::error(const QString &msg) +{ + errorField_->setText(msg); + errorField_->show(); +} + void EditModal::applyClicked() { diff --git a/src/dialogs/RoomSettings.h b/src/dialogs/RoomSettings.h index e41c866c..e0918afd 100644 --- a/src/dialogs/RoomSettings.h +++ b/src/dialogs/RoomSettings.h @@ -1,9 +1,7 @@ #pragma once -#include #include #include -#include #include @@ -21,6 +19,8 @@ class QPixmap; class TextField; class TextField; class Toggle; +class QLabel; +class QEvent; class ClickableFilter : public QObject { @@ -35,15 +35,7 @@ signals: void clicked(); protected: - bool eventFilter(QObject *obj, QEvent *event) override - { - if (event->type() == QEvent::MouseButtonRelease) { - emit clicked(); - return true; - } - - return QObject::eventFilter(obj, event); - } + bool eventFilter(QObject *obj, QEvent *event) override; }; /// Convenience class which connects events emmited from threads @@ -72,24 +64,9 @@ signals: void nameChanged(const QString &roomName); private slots: - void topicEventSent() - { - errorField_->hide(); - close(); - } - - void nameEventSent(const QString &name) - { - errorField_->hide(); - emit nameChanged(name); - close(); - } - - void error(const QString &msg) - { - errorField_->setText(msg); - errorField_->show(); - } + void topicEventSent(); + void nameEventSent(const QString &name); + void error(const QString &msg); void applyClicked(); diff --git a/src/emoji/Category.cpp b/src/emoji/Category.cpp index e674e9db..5197c474 100644 --- a/src/emoji/Category.cpp +++ b/src/emoji/Category.cpp @@ -15,9 +15,12 @@ * along with this program. If not, see . */ +#include +#include #include #include #include +#include #include "Config.h" diff --git a/src/emoji/Category.h b/src/emoji/Category.h index 2f39d621..79e616ee 100644 --- a/src/emoji/Category.h +++ b/src/emoji/Category.h @@ -18,13 +18,14 @@ #pragma once #include -#include -#include -#include -#include #include "ItemDelegate.h" +class QLabel; +class QListView; +class QStandardItemModel; +class QVBoxLayout; + namespace emoji { class Category : public QWidget diff --git a/src/popups/PopupItem.cpp b/src/popups/PopupItem.cpp index 5513f942..b3784843 100644 --- a/src/popups/PopupItem.cpp +++ b/src/popups/PopupItem.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/src/popups/PopupItem.h b/src/popups/PopupItem.h index 7a710fdb..17a4f6bc 100644 --- a/src/popups/PopupItem.h +++ b/src/popups/PopupItem.h @@ -1,8 +1,5 @@ #pragma once -#include -#include -#include #include #include "../AvatarProvider.h" @@ -10,6 +7,8 @@ class Avatar; struct SearchResult; +class QLabel; +class QHBoxLayout; class PopupItem : public QWidget { diff --git a/src/popups/SuggestionsPopup.h b/src/popups/SuggestionsPopup.h index 63c44538..73bfe6f7 100644 --- a/src/popups/SuggestionsPopup.h +++ b/src/popups/SuggestionsPopup.h @@ -1,8 +1,5 @@ #pragma once -#include -#include -#include #include #include "CacheStructs.h" From f452bdf2b01ca6c39bdb3ecd4f61ec1eb1eef211 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 26 May 2020 22:27:05 +0200 Subject: [PATCH 09/24] Make settings update immediately in qml and allow limiting timeline width Limiting improves readability on wide monitors. The immediate update of the settings is done by just exposing settings as properties and then setting the settings as a context property. --- resources/qml/Avatar.qml | 4 +- resources/qml/Reactions.qml | 8 +- resources/qml/TimelineRow.qml | 8 +- resources/qml/TimelineView.qml | 33 ++--- resources/qml/delegates/TextMessage.qml | 2 +- src/UserSettingsPage.cpp | 169 ++++++++++++++++++++++++ src/UserSettingsPage.h | 149 ++++++++++----------- src/timeline/TimelineViewManager.cpp | 1 + 8 files changed, 259 insertions(+), 115 deletions(-) diff --git a/resources/qml/Avatar.qml b/resources/qml/Avatar.qml index ed065270..465a8e1c 100644 --- a/resources/qml/Avatar.qml +++ b/resources/qml/Avatar.qml @@ -6,7 +6,7 @@ Rectangle { id: avatar width: 48 height: 48 - radius: settings.avatar_circles ? height/2 : 3 + radius: settings.avatarCircles ? height/2 : 3 property alias url: img.source property string displayName @@ -39,7 +39,7 @@ Rectangle { anchors.fill: parent width: avatar.width height: avatar.height - radius: settings.avatar_circles ? height/2 : 3 + radius: settings.avatarCircles ? height/2 : 3 } } } diff --git a/resources/qml/Reactions.qml b/resources/qml/Reactions.qml index cb15b723..f42e8612 100644 --- a/resources/qml/Reactions.qml +++ b/resources/qml/Reactions.qml @@ -30,7 +30,7 @@ Flow { TextMetrics { id: textMetrics - font.family: settings.emoji_font_family + font.family: settings.emojiFont elide: Text.ElideRight elideWidth: 150 text: reaction.text @@ -40,14 +40,14 @@ Flow { anchors.baseline: reactionCounter.baseline id: reactionText text: textMetrics.elidedText + (textMetrics.elidedText == textMetrics.text ? "" : "…") - font.family: settings.emoji_font_family + font.family: settings.emojiFont color: reaction.hovered ? colors.highlight : colors.text maximumLineCount: 1 } Rectangle { id: divider - height: reactionCounter.implicitHeight * 1.4 + height: Math.floor(reactionCounter.implicitHeight * 1.4) width: 1 color: reaction.hovered ? colors.highlight : colors.text } @@ -64,7 +64,7 @@ Flow { background: Rectangle { anchors.centerIn: parent implicitWidth: reaction.implicitWidth - implicitHeight: reaction.implicitHeight + height: reaction.implicitHeight border.color: (reaction.hovered || model.selfReacted )? colors.highlight : colors.text color: colors.base border.width: 1 diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index 42791e0b..c8e6eb09 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -25,13 +25,13 @@ MouseArea { messageContextMenu.show(model.id, model.type, model.isEncrypted, row) } Rectangle { - color: (timelineSettings.message_hover_highlight && parent.containsMouse) ? colors.base : "transparent" + color: (settings.isMessageHoverHighlightEnabled && parent.containsMouse) ? colors.base : "transparent" anchors.fill: row } RowLayout { id: row - anchors.leftMargin: avatarSize + 4 + anchors.leftMargin: avatarSize + 16 anchors.left: parent.left anchors.right: parent.right @@ -78,7 +78,7 @@ MouseArea { } ImageButton { - visible: timelineSettings.buttons + visible: settings.buttonsInTimeline Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.preferredHeight: 16 width: 16 @@ -94,7 +94,7 @@ MouseArea { onClicked: chat.model.replyAction(model.id) } ImageButton { - visible: timelineSettings.buttons + visible: settings.buttonsInTimeline Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.preferredHeight: 16 width: 16 diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 145a82ce..08130033 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -3,7 +3,6 @@ import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 import QtQuick.Window 2.2 -import Qt.labs.settings 1.0 import im.nheko 1.0 @@ -21,22 +20,6 @@ Page { id: fontMetrics } - Settings { - id: settings - category: "user" - property bool avatar_circles: true - property string emoji_font_family: "default" - property double font_size: Qt.application.font.pointSize - } - - Settings { - id: timelineSettings - category: "user/timeline" - property bool buttons: true - property bool message_hover_highlight: false - property bool enlarge_emoji_only_msg: false - } - Menu { id: messageContextMenu modal: true @@ -102,7 +85,7 @@ Page { BusyIndicator { visible: running anchors.centerIn: parent - running: timelineManager.isInitialSync + running: timelineManager.isInitialSync height: 200 width: 200 z: 3 @@ -113,12 +96,12 @@ Page { visible: timelineManager.timeline != null - cacheBuffer: 500 + cacheBuffer: 400 - anchors.left: parent.left - anchors.right: parent.right + anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top anchors.bottom: chatFooter.top + width: parent.width anchors.leftMargin: 4 anchors.rightMargin: scrollbar.width @@ -160,7 +143,7 @@ Page { id: scrollbar parent: chat.parent anchors.top: chat.top - anchors.left: chat.right + anchors.right: chat.right anchors.bottom: chat.bottom } @@ -175,7 +158,8 @@ Page { id: wrapper property Item section - width: chat.width + anchors.horizontalCenter: parent.horizontalCenter + width: (settings.timelineMaxWidth > 100 && (parent.width - settings.timelineMaxWidth) > 32) ? settings.timelineMaxWidth : (parent.width - 32) height: section ? section.height + timelinerow.height : timelinerow.height color: "transparent" @@ -245,7 +229,8 @@ Page { } Row { height: userName.height - spacing: 4 + spacing: 8 + Avatar { width: avatarSize height: avatarSize diff --git a/resources/qml/delegates/TextMessage.qml b/resources/qml/delegates/TextMessage.qml index d17723f3..b3c45c36 100644 --- a/resources/qml/delegates/TextMessage.qml +++ b/resources/qml/delegates/TextMessage.qml @@ -6,5 +6,5 @@ MatrixText { width: parent ? parent.width : undefined height: isReply ? Math.min(chat.height / 8, implicitHeight) : undefined clip: true - font.pointSize: (timelineSettings.enlarge_emoji_only_msg && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? settings.font_size * 3 : settings.font_size + font.pointSize: (settings.enlargeEmojiOnlyMessages && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? settings.fontSize * 3 : settings.fontSize } diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index c151cad2..393b4861 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,7 @@ UserSettings::load() isStartInTrayEnabled_ = settings.value("user/window/start_in_tray", false).toBool(); isGroupViewEnabled_ = settings.value("user/group_view", true).toBool(); isButtonsInTimelineEnabled_ = settings.value("user/timeline/buttons", true).toBool(); + timelineMaxWidth_ = settings.value("user/timeline/max_width", 0).toInt(); isMessageHoverHighlightEnabled_ = settings.value("user/timeline/message_hover_highlight", false).toBool(); isEnlargeEmojiOnlyMessagesEnabled_ = @@ -73,34 +75,183 @@ UserSettings::load() applyTheme(); } +void +UserSettings::setMessageHoverHighlight(bool state) +{ + if (state == isMessageHoverHighlightEnabled_) + return; + isMessageHoverHighlightEnabled_ = state; + emit messageHoverHighlightChanged(state); + save(); +} +void +UserSettings::setEnlargeEmojiOnlyMessages(bool state) +{ + if (state == isEnlargeEmojiOnlyMessagesEnabled_) + return; + isEnlargeEmojiOnlyMessagesEnabled_ = state; + emit enlargeEmojiOnlyMessagesChanged(state); + save(); +} +void +UserSettings::setTray(bool state) +{ + if (state == isTrayEnabled_) + return; + isTrayEnabled_ = state; + emit trayChanged(state); + save(); +} + +void +UserSettings::setStartInTray(bool state) +{ + if (state == isStartInTrayEnabled_) + return; + isStartInTrayEnabled_ = state; + emit startInTrayChanged(state); + save(); +} + +void +UserSettings::setGroupView(bool state) +{ + if (isGroupViewEnabled_ != state) + emit groupViewStateChanged(state); + + isGroupViewEnabled_ = state; + save(); +} + +void +UserSettings::setMarkdownEnabled(bool state) +{ + if (state == isMarkdownEnabled_) + return; + isMarkdownEnabled_ = state; + emit markdownChanged(state); + save(); +} + +void +UserSettings::setReadReceipts(bool state) +{ + if (state == isReadReceiptsEnabled_) + return; + isReadReceiptsEnabled_ = state; + emit readReceiptsChanged(state); + save(); +} + +void +UserSettings::setTypingNotifications(bool state) +{ + if (state == isTypingNotificationsEnabled_) + return; + isTypingNotificationsEnabled_ = state; + emit typingNotificationsChanged(state); + save(); +} + +void +UserSettings::setSortByImportance(bool state) +{ + if (state == sortByImportance_) + return; + sortByImportance_ = state; + emit roomSortingChanged(state); + save(); +} + +void +UserSettings::setButtonsInTimeline(bool state) +{ + if (state == isButtonsInTimelineEnabled_) + return; + isButtonsInTimelineEnabled_ = state; + emit buttonInTimelineChanged(state); + save(); +} + +void +UserSettings::setTimelineMaxWidth(int state) +{ + if (state == timelineMaxWidth_) + return; + timelineMaxWidth_ = state; + emit timelineMaxWidthChanged(state); + save(); +} + +void +UserSettings::setDesktopNotifications(bool state) +{ + if (state == hasDesktopNotifications_) + return; + hasDesktopNotifications_ = state; + emit desktopNotificationsChanged(state); + save(); +} + +void +UserSettings::setAvatarCircles(bool state) +{ + if (state == avatarCircles_) + return; + avatarCircles_ = state; + emit avatarCirclesChanged(state); + save(); +} + +void +UserSettings::setDecryptSidebar(bool state) +{ + if (state == decryptSidebar_) + return; + decryptSidebar_ = state; + emit decryptSidebarChanged(state); + save(); +} void UserSettings::setFontSize(double size) { + if (size == baseFontSize_) + return; baseFontSize_ = size; + emit fontSizeChanged(size); save(); } void UserSettings::setFontFamily(QString family) { + if (family == font_) + return; font_ = family; + emit fontChanged(family); save(); } void UserSettings::setEmojiFontFamily(QString family) { + if (family == emojiFont_) + return; emojiFont_ = family; + emit emojiFontChanged(family); save(); } void UserSettings::setTheme(QString theme) { + if (theme == theme) + return; theme_ = theme; save(); applyTheme(); + emit themeChanged(theme); } void @@ -171,6 +322,7 @@ UserSettings::save() settings.setValue("buttons", isButtonsInTimelineEnabled_); settings.setValue("message_hover_highlight", isMessageHoverHighlightEnabled_); settings.setValue("enlarge_emoji_only_msg", isEnlargeEmojiOnlyMessagesEnabled_); + settings.setValue("max_width", timelineMaxWidth_); settings.endGroup(); settings.setValue("avatar_circles", avatarCircles_); @@ -187,6 +339,8 @@ UserSettings::save() settings.setValue("emoji_font_family", emojiFont_); settings.endGroup(); + + settings.sync(); } HorizontalLine::HorizontalLine(QWidget *parent) @@ -251,6 +405,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge fontSizeCombo_ = new QComboBox{this}; fontSelectionCombo_ = new QComboBox{this}; emojiFontSelectionCombo_ = new QComboBox{this}; + timelineMaxWidthSpin_ = new QSpinBox{this}; if (!settings_->isTrayEnabled()) startInTrayToggle_->setDisabled(true); @@ -295,6 +450,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge int themeIndex = themeCombo_->findText(themeStr); themeCombo_->setCurrentIndex(themeIndex); + timelineMaxWidthSpin_->setMinimum(0); + timelineMaxWidthSpin_->setMaximum(100'000'000); + timelineMaxWidthSpin_->setSingleStep(10); + auto encryptionLabel_ = new QLabel{tr("ENCRYPTION"), this}; encryptionLabel_->setFixedHeight(encryptionLabel_->minimumHeight() + LayoutTopMargin); encryptionLabel_->setAlignment(Qt::AlignBottom); @@ -366,6 +525,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge timelineButtonsToggle_, tr("Show buttons to quickly reply, react or access additional options next to each " "message.")); + boxWrap(tr("Limit width of timeline"), + timelineMaxWidthSpin_, + tr("Set the max width of messages in the timeline (in pixels). This can help " + "readability on wide screen, when Nheko is maximised")); boxWrap(tr("Typing notifications"), typingNotifications_, tr("Show who is typing in a room.\nThis will also enable or disable sending typing " @@ -525,6 +688,11 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge settings_->setEnlargeEmojiOnlyMessages(!isDisabled); }); + connect(timelineMaxWidthSpin_, + qOverload(&QSpinBox::valueChanged), + this, + [this](int newValue) { settings_->setTimelineMaxWidth(newValue); }); + connect( sessionKeysImportBtn, &QPushButton::clicked, this, &UserSettingsPage::importSessionKeys); @@ -560,6 +728,7 @@ UserSettingsPage::showEvent(QShowEvent *) messageHoverHighlight_->setState(!settings_->isMessageHoverHighlightEnabled()); enlargeEmojiOnlyMessages_->setState(!settings_->isEnlargeEmojiOnlyMessagesEnabled()); deviceIdValue_->setText(QString::fromStdString(http::client()->device_id())); + timelineMaxWidthSpin_->setValue(settings_->timelineMaxWidth()); deviceFingerprintValue_->setText( utils::humanReadableFingerprint(olm::client()->identity_keys().ed25519)); diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index f80c2b2b..cade8c22 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -27,6 +27,7 @@ class Toggle; class QLabel; class QFormLayout; class QComboBox; +class QSpinBox; class QHBoxLayout; class QVBoxLayout; @@ -38,6 +39,39 @@ class UserSettings : public QObject { Q_OBJECT + Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) + Q_PROPERTY(bool isMessageHoverHighlightEnabled READ isMessageHoverHighlightEnabled WRITE + setMessageHoverHighlight NOTIFY messageHoverHighlightChanged) + Q_PROPERTY(bool enlargeEmojiOnlyMessages READ isEnlargeEmojiOnlyMessagesEnabled WRITE + setEnlargeEmojiOnlyMessages NOTIFY enlargeEmojiOnlyMessagesChanged) + Q_PROPERTY(bool trayEnabled READ isTrayEnabled WRITE setTray NOTIFY trayChanged) + Q_PROPERTY(bool startInTrayEnabled READ isStartInTrayEnabled WRITE setStartInTray NOTIFY + startInTrayChanged) + Q_PROPERTY(bool groupViewEnabled READ isGroupViewEnabled WRITE setGroupView NOTIFY + groupViewStateChanged) + Q_PROPERTY( + bool markdown READ isMarkdownEnabled WRITE setMarkdownEnabled NOTIFY markdownChanged) + Q_PROPERTY(bool typingNotifications READ isTypingNotificationsEnabled WRITE + setTypingNotifications NOTIFY typingNotificationsChanged) + Q_PROPERTY(bool sortByImportance READ isSortByImportanceEnabled WRITE setSortByImportance + NOTIFY roomSortingChanged) + Q_PROPERTY(bool buttonsInTimeline READ isButtonsInTimelineEnabled WRITE setButtonsInTimeline + NOTIFY buttonInTimelineChanged) + Q_PROPERTY(bool readReceipts READ isReadReceiptsEnabled WRITE setReadReceipts NOTIFY + readReceiptsChanged) + Q_PROPERTY(bool desktopNotifications READ hasDesktopNotifications WRITE + setDesktopNotifications NOTIFY desktopNotificationsChanged) + Q_PROPERTY(bool avatarCircles READ isAvatarCirclesEnabled WRITE setAvatarCircles NOTIFY + avatarCirclesChanged) + Q_PROPERTY(bool decryptSidebar READ isDecryptSidebarEnabled WRITE setDecryptSidebar NOTIFY + decryptSidebarChanged) + Q_PROPERTY(int timelineMaxWidth READ timelineMaxWidth WRITE setTimelineMaxWidth NOTIFY + timelineMaxWidthChanged) + Q_PROPERTY(double fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged) + Q_PROPERTY(QString font READ font WRITE setFontFamily NOTIFY fontChanged) + Q_PROPERTY( + QString emojiFont READ emojiFont WRITE setEmojiFontFamily NOTIFY emojiFontChanged) + public: UserSettings(); @@ -45,88 +79,23 @@ public: void load(); void applyTheme(); void setTheme(QString theme); - void setMessageHoverHighlight(bool state) - { - isMessageHoverHighlightEnabled_ = state; - save(); - } - void setEnlargeEmojiOnlyMessages(bool state) - { - isEnlargeEmojiOnlyMessagesEnabled_ = state; - save(); - } - void setTray(bool state) - { - isTrayEnabled_ = state; - save(); - } - - void setStartInTray(bool state) - { - isStartInTrayEnabled_ = state; - save(); - } - + void setMessageHoverHighlight(bool state); + void setEnlargeEmojiOnlyMessages(bool state); + void setTray(bool state); + void setStartInTray(bool state); void setFontSize(double size); void setFontFamily(QString family); void setEmojiFontFamily(QString family); - - void setGroupView(bool state) - { - if (isGroupViewEnabled_ != state) - emit groupViewStateChanged(state); - - isGroupViewEnabled_ = state; - save(); - } - - void setMarkdownEnabled(bool state) - { - isMarkdownEnabled_ = state; - save(); - } - - void setReadReceipts(bool state) - { - isReadReceiptsEnabled_ = state; - save(); - } - - void setTypingNotifications(bool state) - { - isTypingNotificationsEnabled_ = state; - save(); - } - - void setSortByImportance(bool state) - { - sortByImportance_ = state; - emit roomSortingChanged(); - } - - void setButtonsInTimeline(bool state) - { - isButtonsInTimelineEnabled_ = state; - save(); - } - - void setDesktopNotifications(bool state) - { - hasDesktopNotifications_ = state; - save(); - } - - void setAvatarCircles(bool state) - { - avatarCircles_ = state; - save(); - } - - void setDecryptSidebar(bool state) - { - decryptSidebar_ = state; - save(); - } + void setGroupView(bool state); + void setMarkdownEnabled(bool state); + void setReadReceipts(bool state); + void setTypingNotifications(bool state); + void setSortByImportance(bool state); + void setButtonsInTimeline(bool state); + void setTimelineMaxWidth(int state); + void setDesktopNotifications(bool state); + void setAvatarCircles(bool state); + void setDecryptSidebar(bool state); QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; } bool isMessageHoverHighlightEnabled() const { return isMessageHoverHighlightEnabled_; } @@ -145,13 +114,30 @@ public: bool isButtonsInTimelineEnabled() const { return isButtonsInTimelineEnabled_; } bool isReadReceiptsEnabled() const { return isReadReceiptsEnabled_; } bool hasDesktopNotifications() const { return hasDesktopNotifications_; } + int timelineMaxWidth() const { return timelineMaxWidth_; } double fontSize() const { return baseFontSize_; } QString font() const { return font_; } QString emojiFont() const { return emojiFont_; } signals: void groupViewStateChanged(bool state); - void roomSortingChanged(); + void roomSortingChanged(bool state); + void themeChanged(QString state); + void messageHoverHighlightChanged(bool state); + void enlargeEmojiOnlyMessagesChanged(bool state); + void trayChanged(bool state); + void startInTrayChanged(bool state); + void markdownChanged(bool state); + void typingNotificationsChanged(bool state); + void buttonInTimelineChanged(bool state); + void readReceiptsChanged(bool state); + void desktopNotificationsChanged(bool state); + void avatarCirclesChanged(bool state); + void decryptSidebarChanged(bool state); + void timelineMaxWidthChanged(int state); + void fontSizeChanged(double state); + void fontChanged(QString state); + void emojiFontChanged(QString state); private: // Default to system theme if QT_QPA_PLATFORMTHEME var is set. @@ -173,6 +159,7 @@ private: bool hasDesktopNotifications_; bool avatarCircles_; bool decryptSidebar_; + int timelineMaxWidth_; double baseFontSize_; QString font_; QString emojiFont_; @@ -238,5 +225,7 @@ private: QComboBox *fontSelectionCombo_; QComboBox *emojiFontSelectionCombo_; + QSpinBox *timelineMaxWidthSpin_; + int sideMargin_ = 0; }; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index b9565be8..89882e9d 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -88,6 +88,7 @@ TimelineViewManager::TimelineViewManager(QSharedPointer userSettin #endif container->setMinimumSize(200, 200); view->rootContext()->setContextProperty("timelineManager", this); + view->rootContext()->setContextProperty("settings", settings.data()); updateColorPalette(); view->engine()->addImageProvider("MxcImage", imgProvider); view->engine()->addImageProvider("colorimage", colorImgProvider); From 6b60ff77135c3717159f760e82f14841c50816aa Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 26 May 2020 22:53:21 +0200 Subject: [PATCH 10/24] Rename settings to be more consistent --- resources/qml/TimelineRow.qml | 2 +- src/ChatPage.cpp | 8 +- src/MainWindow.cpp | 4 +- src/RoomInfoListItem.cpp | 2 +- src/UserSettingsPage.cpp | 178 +++++++++++++-------------- src/UserSettingsPage.h | 84 ++++++------- src/timeline/TimelineViewManager.cpp | 12 +- 7 files changed, 142 insertions(+), 148 deletions(-) diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index c8e6eb09..528dce85 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -25,7 +25,7 @@ MouseArea { messageContextMenu.show(model.id, model.type, model.isEncrypted, row) } Rectangle { - color: (settings.isMessageHoverHighlightEnabled && parent.containsMouse) ? colors.base : "transparent" + color: (settings.messageHoverHighlight && parent.containsMouse) ? colors.base : "transparent" anchors.fill: row } RowLayout { diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 90abc63e..2b55b91e 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -255,7 +255,7 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) text_input_, &TextInputWidget::startedTyping, this, &ChatPage::sendTypingNotifications); connect(typingRefresher_, &QTimer::timeout, this, &ChatPage::sendTypingNotifications); connect(text_input_, &TextInputWidget::stoppedTyping, this, [this]() { - if (!userSettings_->isTypingNotificationsEnabled()) + if (!userSettings_->typingNotifications()) return; typingRefresher_->stop(); @@ -482,7 +482,7 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) activateWindow(); }); - setGroupViewState(userSettings_->isGroupViewEnabled()); + setGroupViewState(userSettings_->groupView()); connect(userSettings_.data(), &UserSettings::groupViewStateChanged, @@ -1207,7 +1207,7 @@ ChatPage::unbanUser(QString userid, QString reason) void ChatPage::sendTypingNotifications() { - if (!userSettings_->isTypingNotificationsEnabled()) + if (!userSettings_->typingNotifications()) return; http::client()->start_typing( @@ -1343,7 +1343,7 @@ ChatPage::hideSideBars() void ChatPage::showSideBars() { - if (userSettings_->isGroupViewEnabled()) + if (userSettings_->groupView()) communitiesList_->show(); sideBar_->show(); diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index c6abdca2..cc1d868b 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -148,7 +148,7 @@ MainWindow::MainWindow(QWidget *parent) QSettings settings; - trayIcon_->setVisible(userSettings_->isTrayEnabled()); + trayIcon_->setVisible(userSettings_->tray()); if (hasActiveUser()) { QString token = settings.value("auth/access_token").toString(); @@ -286,7 +286,7 @@ void MainWindow::closeEvent(QCloseEvent *event) { if (!qApp->isSavingSession() && isVisible() && pageSupportsTray() && - userSettings_->isTrayEnabled()) { + userSettings_->tray()) { event->ignore(); hide(); } diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp index ad774360..f234b59b 100644 --- a/src/RoomInfoListItem.cpp +++ b/src/RoomInfoListItem.cpp @@ -451,7 +451,7 @@ RoomInfoListItem::calculateImportance() const // returns ImportanceDisabled or Invite if (isInvite()) { return Invite; - } else if (!settings->isSortByImportanceEnabled()) { + } else if (!settings->sortByImportance()) { return ImportanceDisabled; } else if (unreadHighlightedMsgCount_) { return NewMentions; diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index 393b4861..38b76404 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -52,53 +52,53 @@ void UserSettings::load() { QSettings settings; - isTrayEnabled_ = settings.value("user/window/tray", false).toBool(); - hasDesktopNotifications_ = settings.value("user/desktop_notifications", true).toBool(); - isStartInTrayEnabled_ = settings.value("user/window/start_in_tray", false).toBool(); - isGroupViewEnabled_ = settings.value("user/group_view", true).toBool(); - isButtonsInTimelineEnabled_ = settings.value("user/timeline/buttons", true).toBool(); - timelineMaxWidth_ = settings.value("user/timeline/max_width", 0).toInt(); - isMessageHoverHighlightEnabled_ = + tray_ = settings.value("user/window/tray", false).toBool(); + hasDesktopNotifications_ = settings.value("user/desktop_notifications", true).toBool(); + startInTray_ = settings.value("user/window/start_in_tray", false).toBool(); + groupView_ = settings.value("user/group_view", true).toBool(); + buttonsInTimeline_ = settings.value("user/timeline/buttons", true).toBool(); + timelineMaxWidth_ = settings.value("user/timeline/max_width", 0).toInt(); + messageHoverHighlight_ = settings.value("user/timeline/message_hover_highlight", false).toBool(); - isEnlargeEmojiOnlyMessagesEnabled_ = + enlargeEmojiOnlyMessages_ = settings.value("user/timeline/enlarge_emoji_only_msg", false).toBool(); - isMarkdownEnabled_ = settings.value("user/markdown_enabled", true).toBool(); - isTypingNotificationsEnabled_ = settings.value("user/typing_notifications", true).toBool(); - sortByImportance_ = settings.value("user/sort_by_unread", true).toBool(); - isReadReceiptsEnabled_ = settings.value("user/read_receipts", true).toBool(); - theme_ = settings.value("user/theme", defaultTheme_).toString(); - font_ = settings.value("user/font_family", "default").toString(); - avatarCircles_ = settings.value("user/avatar_circles", true).toBool(); - decryptSidebar_ = settings.value("user/decrypt_sidebar", true).toBool(); - emojiFont_ = settings.value("user/emoji_font_family", "default").toString(); - baseFontSize_ = settings.value("user/font_size", QFont().pointSizeF()).toDouble(); + markdown_ = settings.value("user/markdown_enabled", true).toBool(); + typingNotifications_ = settings.value("user/typing_notifications", true).toBool(); + sortByImportance_ = settings.value("user/sort_by_unread", true).toBool(); + readReceipts_ = settings.value("user/read_receipts", true).toBool(); + theme_ = settings.value("user/theme", defaultTheme_).toString(); + font_ = settings.value("user/font_family", "default").toString(); + avatarCircles_ = settings.value("user/avatar_circles", true).toBool(); + decryptSidebar_ = settings.value("user/decrypt_sidebar", true).toBool(); + emojiFont_ = settings.value("user/emoji_font_family", "default").toString(); + baseFontSize_ = settings.value("user/font_size", QFont().pointSizeF()).toDouble(); applyTheme(); } void UserSettings::setMessageHoverHighlight(bool state) { - if (state == isMessageHoverHighlightEnabled_) + if (state == messageHoverHighlight_) return; - isMessageHoverHighlightEnabled_ = state; + messageHoverHighlight_ = state; emit messageHoverHighlightChanged(state); save(); } void UserSettings::setEnlargeEmojiOnlyMessages(bool state) { - if (state == isEnlargeEmojiOnlyMessagesEnabled_) + if (state == enlargeEmojiOnlyMessages_) return; - isEnlargeEmojiOnlyMessagesEnabled_ = state; + enlargeEmojiOnlyMessages_ = state; emit enlargeEmojiOnlyMessagesChanged(state); save(); } void UserSettings::setTray(bool state) { - if (state == isTrayEnabled_) + if (state == tray_) return; - isTrayEnabled_ = state; + tray_ = state; emit trayChanged(state); save(); } @@ -106,9 +106,9 @@ UserSettings::setTray(bool state) void UserSettings::setStartInTray(bool state) { - if (state == isStartInTrayEnabled_) + if (state == startInTray_) return; - isStartInTrayEnabled_ = state; + startInTray_ = state; emit startInTrayChanged(state); save(); } @@ -116,19 +116,19 @@ UserSettings::setStartInTray(bool state) void UserSettings::setGroupView(bool state) { - if (isGroupViewEnabled_ != state) + if (groupView_ != state) emit groupViewStateChanged(state); - isGroupViewEnabled_ = state; + groupView_ = state; save(); } void -UserSettings::setMarkdownEnabled(bool state) +UserSettings::setMarkdown(bool state) { - if (state == isMarkdownEnabled_) + if (state == markdown_) return; - isMarkdownEnabled_ = state; + markdown_ = state; emit markdownChanged(state); save(); } @@ -136,9 +136,9 @@ UserSettings::setMarkdownEnabled(bool state) void UserSettings::setReadReceipts(bool state) { - if (state == isReadReceiptsEnabled_) + if (state == readReceipts_) return; - isReadReceiptsEnabled_ = state; + readReceipts_ = state; emit readReceiptsChanged(state); save(); } @@ -146,9 +146,9 @@ UserSettings::setReadReceipts(bool state) void UserSettings::setTypingNotifications(bool state) { - if (state == isTypingNotificationsEnabled_) + if (state == typingNotifications_) return; - isTypingNotificationsEnabled_ = state; + typingNotifications_ = state; emit typingNotificationsChanged(state); save(); } @@ -166,9 +166,9 @@ UserSettings::setSortByImportance(bool state) void UserSettings::setButtonsInTimeline(bool state) { - if (state == isButtonsInTimelineEnabled_) + if (state == buttonsInTimeline_) return; - isButtonsInTimelineEnabled_ = state; + buttonsInTimeline_ = state; emit buttonInTimelineChanged(state); save(); } @@ -314,25 +314,25 @@ UserSettings::save() settings.beginGroup("user"); settings.beginGroup("window"); - settings.setValue("tray", isTrayEnabled_); - settings.setValue("start_in_tray", isStartInTrayEnabled_); + settings.setValue("tray", tray_); + settings.setValue("start_in_tray", startInTray_); settings.endGroup(); settings.beginGroup("timeline"); - settings.setValue("buttons", isButtonsInTimelineEnabled_); - settings.setValue("message_hover_highlight", isMessageHoverHighlightEnabled_); - settings.setValue("enlarge_emoji_only_msg", isEnlargeEmojiOnlyMessagesEnabled_); + settings.setValue("buttons", buttonsInTimeline_); + settings.setValue("message_hover_highlight", messageHoverHighlight_); + settings.setValue("enlarge_emoji_only_msg", enlargeEmojiOnlyMessages_); settings.setValue("max_width", timelineMaxWidth_); settings.endGroup(); settings.setValue("avatar_circles", avatarCircles_); settings.setValue("decrypt_sidebar", decryptSidebar_); settings.setValue("font_size", baseFontSize_); - settings.setValue("typing_notifications", isTypingNotificationsEnabled_); + settings.setValue("typing_notifications", typingNotifications_); settings.setValue("minor_events", sortByImportance_); - settings.setValue("read_receipts", isReadReceiptsEnabled_); - settings.setValue("group_view", isGroupViewEnabled_); - settings.setValue("markdown_enabled", isMarkdownEnabled_); + settings.setValue("read_receipts", readReceipts_); + settings.setValue("group_view", groupView_); + settings.setValue("markdown_enabled", markdown_); settings.setValue("desktop_notifications", hasDesktopNotifications_); settings.setValue("theme", theme()); settings.setValue("font_family", font_); @@ -399,7 +399,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge enlargeEmojiOnlyMessages_ = new Toggle{this}; sortByImportance_ = new Toggle{this}; readReceipts_ = new Toggle{this}; - markdownEnabled_ = new Toggle{this}; + markdown_ = new Toggle{this}; desktopNotifications_ = new Toggle{this}; scaleFactorCombo_ = new QComboBox{this}; fontSizeCombo_ = new QComboBox{this}; @@ -407,7 +407,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge emojiFontSelectionCombo_ = new QComboBox{this}; timelineMaxWidthSpin_ = new QSpinBox{this}; - if (!settings_->isTrayEnabled()) + if (!settings_->tray()) startInTrayToggle_->setDisabled(true); avatarCircles_->setFixedSize(64, 48); @@ -548,7 +548,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge tr("Show if your message was read.\nStatus is displayed next to timestamps.")); boxWrap( tr("Send messages as Markdown"), - markdownEnabled_, + markdown_, tr("Allow using markdown in messages.\nWhen disabled, all messages are sent as a plain " "text.")); boxWrap(tr("Desktop notifications"), @@ -629,63 +629,63 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge connect(emojiFontSelectionCombo_, static_cast(&QComboBox::activated), [this](const QString &family) { settings_->setEmojiFontFamily(family.trimmed()); }); - connect(trayToggle_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setTray(!isDisabled); - if (isDisabled) { + connect(trayToggle_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setTray(!disabled); + if (disabled) { startInTrayToggle_->setDisabled(true); } else { startInTrayToggle_->setEnabled(true); } - emit trayOptionChanged(!isDisabled); + emit trayOptionChanged(!disabled); }); - connect(startInTrayToggle_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setStartInTray(!isDisabled); + connect(startInTrayToggle_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setStartInTray(!disabled); }); - connect(groupViewToggle_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setGroupView(!isDisabled); + connect(groupViewToggle_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setGroupView(!disabled); }); - connect(decryptSidebar_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setDecryptSidebar(!isDisabled); + connect(decryptSidebar_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setDecryptSidebar(!disabled); emit decryptSidebarChanged(); }); - connect(avatarCircles_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setAvatarCircles(!isDisabled); + connect(avatarCircles_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setAvatarCircles(!disabled); }); - connect(markdownEnabled_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setMarkdownEnabled(!isDisabled); + connect(markdown_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setMarkdown(!disabled); }); - connect(typingNotifications_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setTypingNotifications(!isDisabled); + connect(typingNotifications_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setTypingNotifications(!disabled); }); - connect(sortByImportance_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setSortByImportance(!isDisabled); + connect(sortByImportance_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setSortByImportance(!disabled); }); - connect(timelineButtonsToggle_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setButtonsInTimeline(!isDisabled); + connect(timelineButtonsToggle_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setButtonsInTimeline(!disabled); }); - connect(readReceipts_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setReadReceipts(!isDisabled); + connect(readReceipts_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setReadReceipts(!disabled); }); - connect(desktopNotifications_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setDesktopNotifications(!isDisabled); + connect(desktopNotifications_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setDesktopNotifications(!disabled); }); - connect(messageHoverHighlight_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setMessageHoverHighlight(!isDisabled); + connect(messageHoverHighlight_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setMessageHoverHighlight(!disabled); }); - connect(enlargeEmojiOnlyMessages_, &Toggle::toggled, this, [this](bool isDisabled) { - settings_->setEnlargeEmojiOnlyMessages(!isDisabled); + connect(enlargeEmojiOnlyMessages_, &Toggle::toggled, this, [this](bool disabled) { + settings_->setEnlargeEmojiOnlyMessages(!disabled); }); connect(timelineMaxWidthSpin_, @@ -714,19 +714,19 @@ UserSettingsPage::showEvent(QShowEvent *) utils::restoreCombobox(themeCombo_, settings_->theme()); // FIXME: Toggle treats true as "off" - trayToggle_->setState(!settings_->isTrayEnabled()); - startInTrayToggle_->setState(!settings_->isStartInTrayEnabled()); - groupViewToggle_->setState(!settings_->isGroupViewEnabled()); - decryptSidebar_->setState(!settings_->isDecryptSidebarEnabled()); - avatarCircles_->setState(!settings_->isAvatarCirclesEnabled()); - typingNotifications_->setState(!settings_->isTypingNotificationsEnabled()); - sortByImportance_->setState(!settings_->isSortByImportanceEnabled()); - timelineButtonsToggle_->setState(!settings_->isButtonsInTimelineEnabled()); - readReceipts_->setState(!settings_->isReadReceiptsEnabled()); - markdownEnabled_->setState(!settings_->isMarkdownEnabled()); + trayToggle_->setState(!settings_->tray()); + startInTrayToggle_->setState(!settings_->startInTray()); + groupViewToggle_->setState(!settings_->groupView()); + decryptSidebar_->setState(!settings_->decryptSidebar()); + avatarCircles_->setState(!settings_->avatarCircles()); + typingNotifications_->setState(!settings_->typingNotifications()); + sortByImportance_->setState(!settings_->sortByImportance()); + timelineButtonsToggle_->setState(!settings_->buttonsInTimeline()); + readReceipts_->setState(!settings_->readReceipts()); + markdown_->setState(!settings_->markdown()); desktopNotifications_->setState(!settings_->hasDesktopNotifications()); - messageHoverHighlight_->setState(!settings_->isMessageHoverHighlightEnabled()); - enlargeEmojiOnlyMessages_->setState(!settings_->isEnlargeEmojiOnlyMessagesEnabled()); + messageHoverHighlight_->setState(!settings_->messageHoverHighlight()); + enlargeEmojiOnlyMessages_->setState(!settings_->enlargeEmojiOnlyMessages()); deviceIdValue_->setText(QString::fromStdString(http::client()->device_id())); timelineMaxWidthSpin_->setValue(settings_->timelineMaxWidth()); diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index cade8c22..fb807067 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -40,30 +40,27 @@ class UserSettings : public QObject Q_OBJECT Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) - Q_PROPERTY(bool isMessageHoverHighlightEnabled READ isMessageHoverHighlightEnabled WRITE + Q_PROPERTY(bool messageHoverHighlight READ messageHoverHighlight WRITE setMessageHoverHighlight NOTIFY messageHoverHighlightChanged) - Q_PROPERTY(bool enlargeEmojiOnlyMessages READ isEnlargeEmojiOnlyMessagesEnabled WRITE + Q_PROPERTY(bool enlargeEmojiOnlyMessages READ enlargeEmojiOnlyMessages WRITE setEnlargeEmojiOnlyMessages NOTIFY enlargeEmojiOnlyMessagesChanged) - Q_PROPERTY(bool trayEnabled READ isTrayEnabled WRITE setTray NOTIFY trayChanged) - Q_PROPERTY(bool startInTrayEnabled READ isStartInTrayEnabled WRITE setStartInTray NOTIFY - startInTrayChanged) - Q_PROPERTY(bool groupViewEnabled READ isGroupViewEnabled WRITE setGroupView NOTIFY - groupViewStateChanged) + Q_PROPERTY(bool tray READ tray WRITE setTray NOTIFY trayChanged) + Q_PROPERTY(bool startInTray READ startInTray WRITE setStartInTray NOTIFY startInTrayChanged) + Q_PROPERTY(bool groupView READ groupView WRITE setGroupView NOTIFY groupViewStateChanged) + Q_PROPERTY(bool markdown READ markdown WRITE setMarkdown NOTIFY markdownChanged) + Q_PROPERTY(bool typingNotifications READ typingNotifications WRITE setTypingNotifications + NOTIFY typingNotificationsChanged) + Q_PROPERTY(bool sortByImportance READ sortByImportance WRITE setSortByImportance NOTIFY + roomSortingChanged) + Q_PROPERTY(bool buttonsInTimeline READ buttonsInTimeline WRITE setButtonsInTimeline NOTIFY + buttonInTimelineChanged) Q_PROPERTY( - bool markdown READ isMarkdownEnabled WRITE setMarkdownEnabled NOTIFY markdownChanged) - Q_PROPERTY(bool typingNotifications READ isTypingNotificationsEnabled WRITE - setTypingNotifications NOTIFY typingNotificationsChanged) - Q_PROPERTY(bool sortByImportance READ isSortByImportanceEnabled WRITE setSortByImportance - NOTIFY roomSortingChanged) - Q_PROPERTY(bool buttonsInTimeline READ isButtonsInTimelineEnabled WRITE setButtonsInTimeline - NOTIFY buttonInTimelineChanged) - Q_PROPERTY(bool readReceipts READ isReadReceiptsEnabled WRITE setReadReceipts NOTIFY - readReceiptsChanged) + bool readReceipts READ readReceipts WRITE setReadReceipts NOTIFY readReceiptsChanged) Q_PROPERTY(bool desktopNotifications READ hasDesktopNotifications WRITE setDesktopNotifications NOTIFY desktopNotificationsChanged) - Q_PROPERTY(bool avatarCircles READ isAvatarCirclesEnabled WRITE setAvatarCircles NOTIFY - avatarCirclesChanged) - Q_PROPERTY(bool decryptSidebar READ isDecryptSidebarEnabled WRITE setDecryptSidebar NOTIFY + Q_PROPERTY( + bool avatarCircles READ avatarCircles WRITE setAvatarCircles NOTIFY avatarCirclesChanged) + Q_PROPERTY(bool decryptSidebar READ decryptSidebar WRITE setDecryptSidebar NOTIFY decryptSidebarChanged) Q_PROPERTY(int timelineMaxWidth READ timelineMaxWidth WRITE setTimelineMaxWidth NOTIFY timelineMaxWidthChanged) @@ -87,7 +84,7 @@ public: void setFontFamily(QString family); void setEmojiFontFamily(QString family); void setGroupView(bool state); - void setMarkdownEnabled(bool state); + void setMarkdown(bool state); void setReadReceipts(bool state); void setTypingNotifications(bool state); void setSortByImportance(bool state); @@ -98,21 +95,18 @@ public: void setDecryptSidebar(bool state); QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; } - bool isMessageHoverHighlightEnabled() const { return isMessageHoverHighlightEnabled_; } - bool isEnlargeEmojiOnlyMessagesEnabled() const - { - return isEnlargeEmojiOnlyMessagesEnabled_; - } - bool isTrayEnabled() const { return isTrayEnabled_; } - bool isStartInTrayEnabled() const { return isStartInTrayEnabled_; } - bool isGroupViewEnabled() const { return isGroupViewEnabled_; } - bool isAvatarCirclesEnabled() const { return avatarCircles_; } - bool isDecryptSidebarEnabled() const { return decryptSidebar_; } - bool isMarkdownEnabled() const { return isMarkdownEnabled_; } - bool isTypingNotificationsEnabled() const { return isTypingNotificationsEnabled_; } - bool isSortByImportanceEnabled() const { return sortByImportance_; } - bool isButtonsInTimelineEnabled() const { return isButtonsInTimelineEnabled_; } - bool isReadReceiptsEnabled() const { return isReadReceiptsEnabled_; } + bool messageHoverHighlight() const { return messageHoverHighlight_; } + bool enlargeEmojiOnlyMessages() const { return enlargeEmojiOnlyMessages_; } + bool tray() const { return tray_; } + bool startInTray() const { return startInTray_; } + bool groupView() const { return groupView_; } + bool avatarCircles() const { return avatarCircles_; } + bool decryptSidebar() const { return decryptSidebar_; } + bool markdown() const { return markdown_; } + bool typingNotifications() const { return typingNotifications_; } + bool sortByImportance() const { return sortByImportance_; } + bool buttonsInTimeline() const { return buttonsInTimeline_; } + bool readReceipts() const { return readReceipts_; } bool hasDesktopNotifications() const { return hasDesktopNotifications_; } int timelineMaxWidth() const { return timelineMaxWidth_; } double fontSize() const { return baseFontSize_; } @@ -146,16 +140,16 @@ private: ? "light" : "system"; QString theme_; - bool isMessageHoverHighlightEnabled_; - bool isEnlargeEmojiOnlyMessagesEnabled_; - bool isTrayEnabled_; - bool isStartInTrayEnabled_; - bool isGroupViewEnabled_; - bool isMarkdownEnabled_; - bool isTypingNotificationsEnabled_; + bool messageHoverHighlight_; + bool enlargeEmojiOnlyMessages_; + bool tray_; + bool startInTray_; + bool groupView_; + bool markdown_; + bool typingNotifications_; bool sortByImportance_; - bool isButtonsInTimelineEnabled_; - bool isReadReceiptsEnabled_; + bool buttonsInTimeline_; + bool readReceipts_; bool hasDesktopNotifications_; bool avatarCircles_; bool decryptSidebar_; @@ -212,7 +206,7 @@ private: Toggle *enlargeEmojiOnlyMessages_; Toggle *sortByImportance_; Toggle *readReceipts_; - Toggle *markdownEnabled_; + Toggle *markdown_; Toggle *desktopNotifications_; Toggle *avatarCircles_; Toggle *decryptSidebar_; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 89882e9d..30abe506 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -19,7 +19,7 @@ Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents) void TimelineViewManager::updateEncryptedDescriptions() { - auto decrypt = settings->isDecryptSidebarEnabled(); + auto decrypt = settings->decryptSidebar(); QHash>::iterator i; for (i = models.begin(); i != models.end(); ++i) { auto ptr = i.value(); @@ -114,7 +114,7 @@ TimelineViewManager::sync(const mtx::responses::Rooms &rooms) const auto &room_model = models.value(QString::fromStdString(room_id)); room_model->addEvents(room.timeline); - if (ChatPage::instance()->userSettings()->isTypingNotificationsEnabled()) { + if (ChatPage::instance()->userSettings()->typingNotifications()) { std::vector typing; typing.reserve(room.ephemeral.typing.size()); for (const auto &user : room.ephemeral.typing) { @@ -134,7 +134,7 @@ TimelineViewManager::addRoom(const QString &room_id) { if (!models.contains(room_id)) { QSharedPointer newRoom(new TimelineModel(this, room_id)); - newRoom->setDecryptDescription(settings->isDecryptSidebarEnabled()); + newRoom->setDecryptDescription(settings->decryptSidebar()); connect(newRoom.data(), &TimelineModel::newEncryptedImage, @@ -218,7 +218,7 @@ TimelineViewManager::queueTextMessage(const QString &msg) mtx::events::msg::Text text = {}; text.body = msg.trimmed().toStdString(); - if (settings->isMarkdownEnabled()) { + if (settings->markdown()) { text.formatted_body = utils::markdownToHtml(msg).toStdString(); // Don't send formatted_body, when we don't need to @@ -246,7 +246,7 @@ TimelineViewManager::queueTextMessage(const QString &msg) // NOTE(Nico): rich replies always need a formatted_body! text.format = "org.matrix.custom.html"; - if (settings->isMarkdownEnabled()) + if (settings->markdown()) text.formatted_body = utils::getFormattedQuoteBody(related, utils::markdownToHtml(msg)) .toStdString(); @@ -269,7 +269,7 @@ TimelineViewManager::queueEmoteMessage(const QString &msg) mtx::events::msg::Emote emote; emote.body = msg.trimmed().toStdString(); - if (html != msg.trimmed().toHtmlEscaped() && settings->isMarkdownEnabled()) { + if (html != msg.trimmed().toHtmlEscaped() && settings->markdown()) { emote.formatted_body = html.toStdString(); emote.format = "org.matrix.custom.html"; } From fd270dcd55216549c83395a3f3d8280145fa76f0 Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Tue, 26 May 2020 14:46:05 +0000 Subject: [PATCH 11/24] Translated using Weblate (Italian) Currently translated at 98.2% (281 of 286 strings) Translation: Nheko/nheko Translate-URL: http://weblate.nheko.im/projects/nheko/nheko-master/it/ --- resources/langs/nheko_it.ts | 595 +++++++++++++++++++----------------- 1 file changed, 314 insertions(+), 281 deletions(-) diff --git a/resources/langs/nheko_it.ts b/resources/langs/nheko_it.ts index e599c01f..38566eca 100644 --- a/resources/langs/nheko_it.ts +++ b/resources/langs/nheko_it.ts @@ -6,7 +6,7 @@ You joined this room. - + Sei entrato in questa stanza. @@ -14,124 +14,124 @@ Failed to invite user: %1 - + Impossibile invitare l'utente: %1 Invited user: %1 - + Invitato utente: %1 Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Migrazione della cache alla versione corrente fallita. Questo può avere diverse cause. Per favore apri una issue e nel frattempo prova ad usare una versione più vecchia. In alternativa puoi provare a cancellare la cache manualmente. Room %1 created. - + Stanza %1 creata. Failed to invite %1 to %2: %3 - + Impossibile invitare %1 a %2: %3 Failed to kick %1 to %2: %3 - + Impossibile scacciare %1 a %2: %3 Kicked user: %1 - + Scacciato utente: %1 Failed to ban %1 in %2: %3 - + Impossibile bannare %1 in %2: %3 Banned user: %1 - + Utente bannato: %1 Failed to unban %1 in %2: %3 - + Impossibile rimuovere il ban di %1 in %2: %3 Unbanned user: %1 - + Rimosso il ban dall'utente: %1 Failed to upload media. Please try again. - + Impossibile inviare il file multimediale. Per favore riprova. Cache migration failed! - + Migrazione della cache fallita! Incompatible cache version - + Versione della cache incompatibile The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. - + La cache sul tuo disco è più nuova di quella supportata da questa versione di Nheko. Per favore aggiorna o pulisci la tua cache. Failed to restore OLM account. Please login again. - + Impossibile ripristinare l'account OLM. Per favore accedi nuovamente. Failed to restore save data. Please login again. - + Impossibile ripristinare i dati salvati. Per favore accedi nuovamente. Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Impossibile configurare le chiavi crittografiche. Risposta del server: %1 %2. Per favore riprova in seguito. Please try to login again: %1 - + Per favore prova ad accedere nuovamente: %1 Failed to join room: %1 - + Impossibile accedere alla stanza: %1 You joined the room - + Sei entrato nella stanza Failed to remove invite: %1 - + Impossibile rimuovere l'invito: %1 Room creation failed: %1 - + Creazione della stanza fallita: %1 Failed to leave room: %1 - + Impossibile lasciare la stanza: %1 @@ -139,28 +139,28 @@ All rooms - + Tutte le stanze Favourite rooms - + Stanze preferite Low priority rooms - + Stanze a bassa priorità (tag) - + (tag) (community) - + (comunità) @@ -168,22 +168,22 @@ Apply - + Applica Cancel - + Annulla Name - + Nome Topic - + Argomento @@ -191,12 +191,12 @@ Encrypted - + Criptato This message is not encrypted! - + Questo messaggio è in chiaro! @@ -204,7 +204,7 @@ Remove - + Rimuovi @@ -212,12 +212,12 @@ Matrix ID - + ID Matrix e.g @joe:matrix.org - + es. @joe:matrix.org @@ -225,74 +225,78 @@ You can also put your homeserver address there, if your server doesn't support .well-known lookup. Example: @user:server.my If Nheko fails to discover your homeserver, it will show you a field to enter the server manually. - + Il tuo nome utente. Un mxid dovrebbe iniziare con @ seguita dall'user id. Dopo l'user id hai bisogno di includere il nome del tuo server dopo un :. +Puoi anche inserire qui l'indirizzo del tuo homeserver, se il tuo server non supporta la ricerca con .well-known. +Esempio: @utente:server.mio +Se Nheko non conclude la ricerca del tuo homeserver, ti mostrerà un campo in cui inserire il server manualmente. Password - + Password Device name - + Nome del dispositivo A name for this device, which will be shown to others, when verifying your devices. If none is provided, a random string is used for privacy purposes. - + Un nome per questo dispositivo, che sarà mostrato agli altri mentre si verificano i tuoi dispositivi. Se non ne fornisci uno, verrà usata una stringa casuale per ragioni di privacy. The address that can be used to contact you homeservers client API. Example: https://server.my:8787 - + L'indirizzo che può essere usato per contattare le API client del tuo homeserver. +Esempio: https://server.mio:8787 LOGIN - + ACCEDI Autodiscovery failed. Received malformed response. - + Ricerca automatica fallita. Ricevuta risposta malformata. Autodiscovery failed. Unknown error when requesting .well-known. - + Ricerca automatica fallita. Errore ignoto durante la richiesta di .well-known. The required endpoints were not found. Possibly not a Matrix server. - + Gli endpoint richiesti non sono stati trovati. Forse non è un server Matrix. Received malformed response. Make sure the homeserver domain is valid. - + Ricevuta risposta malformata. Assicurati che il dominio dell'homeserver sia valido. An unknown error occured. Make sure the homeserver domain is valid. - + Avvenuto un errore sconosciuto. Assicurati che il dominio dell'homeserver sia valido. SSO LOGIN - + ACCESSO SSO Empty password - + Password vuota SSO login failed - + Accesso SSO fallito @@ -300,12 +304,12 @@ Example: https://server.my:8787 Room members - + Membri della stanza OK - + OK @@ -313,37 +317,37 @@ Example: https://server.my:8787 redacted - + oscurato Encryption enabled - + Crittografia abilitata room name changed to: %1 - + nome della stanza cambiato in: %1 removed room name - + nome della stanza rimosso topic changed to: %1 - + argomento cambiato in: %1 removed topic - + argomento rimosso %1 created and configured room: %2 - + %1 creato e configurata stanza: %2 @@ -351,7 +355,7 @@ Example: https://server.my:8787 unimplemented event: - + event non implementato: @@ -359,7 +363,7 @@ Example: https://server.my:8787 Search for a room... - + Cerca una stanza… @@ -367,67 +371,67 @@ Example: https://server.my:8787 Username - + Nome utente The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Il nome utente non deve essere vuoto e deve contenere solo i caratteri a-z, 0-9, ., _, =, -, e /. Password - + Password Please choose a secure password. The exact requirements for password strength may depend on your server. - + Per favore scegli una password sicura. I requisiti di robustezza della password potrebbero dipendere dal server. Password confirmation - + Conferma della password Homeserver - + Homeserver A server that allows registration. Since matrix is decentralized, you need to first find a server you can register on or host your own. - + Un server che consente la registrazione. Siccome matrix è decentralizzata, devi prima trovare un server su cui registrarti o ospitarne uno tuo. REGISTER - + REGISTRATI No supported registration flows! - + Non ci sono processi di registrazione supportati! Invalid username - + Nome utente non valido Password is not long enough (min 8 chars) - + La password non è abbastanza lunga (minimo 8 caratteri) Passwords don't match - + Le password non corrispondono Invalid server name - + Nome del server non valido @@ -435,7 +439,7 @@ Example: https://server.my:8787 no version stored - + nessuna versione memorizzata @@ -443,17 +447,17 @@ Example: https://server.my:8787 Leave room - + Lascia la stanza Accept - + Accetta Decline - + Rifiuta @@ -461,27 +465,27 @@ Example: https://server.my:8787 User settings - + Impostazioni utente Create new room - + Crea una nuova stanza Join a room - + Entra in una stanza Start a new chat - + Inizia una nuova discussione Room directory - + Elenco delle stanze @@ -489,22 +493,22 @@ Example: https://server.my:8787 Failed - + Fallito Sent - + Inviato Received - + Ricevuto Read - + Letto @@ -512,38 +516,38 @@ Example: https://server.my:8787 Send a file - + Invia un file Write a message... - + Scrivi un messaggio… Send a message - + Invia un messaggio Emoji - + Emoji Select a file - + Seleziona un file All Files (*) - + Tutti i file (*) Connection lost. Nheko is trying to re-connect... - + Connessione interrotta. Nheko sta provando a riconnettersi… @@ -552,196 +556,196 @@ Example: https://server.my:8787 -- Decryption Error (failed to communicate with DB) -- Placeholder, when the message can't be decrypted, because the DB access failed when trying to lookup the session. - + -- Errore di Decriptazione (impossibile comunicare con il DB) -- -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. - + -- Errore di Decrittazione (impossibile recuperare le chiavi megolm dal DB) -- -- Decryption Error (%1) -- Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed ad %1. - + -- Errore di Decrittazione (%1) -- Message redaction failed: %1 - + Oscuramento del messaggio fallito: %1 Save image - + Salva immagine Save video - + Salva video Save audio - + Salva audio Save file - + Salva file -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. - + -- Evento Criptato (Chiavi per la decriptazione non trovate) -- -- Encrypted Event (Unknown event type) -- Placeholder, when the message was decrypted, but we couldn't parse it, because Nheko/mtxclient don't support that event type yet. - + -- Evento Criptato (Tipo di evento ignoto) -- %1 and %2 are typing. Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) - - - + + %1%2 sta scrivendo. + %1 e %2 stanno scrivendo. %1 opened the room to the public. - + %1 ha aperto la stanza al pubblico. %1 made this room require and invitation to join. - + %1 ha configurato questa stanza per richiedere un invito per entrare. %1 made the room open to guests. - + %1 ha configurato questa stanza affinché sia aperta ai visitatori. %1 has closed the room to guest access. - + %1 ha chiuso la stanza ai visitatori. %1 made the room history world readable. Events may be now read by non-joined people. - + %1 ha reso la cronologia della stanza leggibile da tutti. Gli eventi adesso possono essere letti da persone esterne. %1 set the room history visible to members from this point on. - + %1 ha reso la cronologia della stanza visibile ai membri da questo momento in poi. %1 set the room history visible to members since they were invited. - + %1 ha reso la cronologia della stanza visibile ai membri dal momento in cui sono stati invitati. %1 set the room history visible to members since they joined the room. - + %1 ha reso la cronologia della stanza visibile ai membri dal momento in cui sono entrati nella stanza. %1 has changed the room's permissions. - + %1 ha cambiato i permessi della stanza. %1 was invited. - + %1 è stato invitato. %1 changed their display name and avatar. - + %1 ha cambiato il suo nome visualizzato e l'avatar. %1 changed their display name. - + %1 ha cambiato il suo nome visualizzato. %1 changed their avatar. - + %1 ha cambiato il suo avatar. %1 joined. - + %1 è entrato. %1 rejected their invite. - + %1 ha rifiutato il suo invito. Revoked the invite to %1. - + Revocato l'invito a %1. %1 left the room. - + %1 ha lasciato la stanza. Kicked %1. - + Scacciato %1. Unbanned %1. - + Rimosso ban da %1. %1 was banned. - + %1 è stato bannato. %1 redacted their knock. - + %1 ha oscurato la sua bussata. You joined this room. - + Sei entrato in questa stanza. Rejected the knock from %1. - + Rifiutata la bussata di %1. %1 left after having already left! This is a leave event after the user already left and shouldn't happen apart from state resets - + %1 è uscito dopo essere già uscito! Reason: %1 - + Motivazione: %1 %1 knocked. - + %1 ha bussato. @@ -749,12 +753,12 @@ Example: https://server.my:8787 Reply - + Rispondi Options - + Opzioni @@ -762,47 +766,47 @@ Example: https://server.my:8787 Reply - + Risposta Read receipts - + Leggi le ricevute Mark as read - + Segna come letto View raw message - + Mostra il messaggio grezzo View decrypted raw message - + Mostra il messaggio grezzo decriptato Redact message - + Oscura messaggio Save as - + Salva come No room open - + Nessuna stanza aperta Close - + Chiudi @@ -810,32 +814,32 @@ Example: https://server.my:8787 Room options - + Opzioni della stanza Mentions - + Menzioni Invite users - + Invita utenti Members - + Membri Leave room - + Lascia la stanza Settings - + Impostazioni @@ -843,12 +847,12 @@ Example: https://server.my:8787 Show - + Rivela Quit - + Esci @@ -856,7 +860,7 @@ Example: https://server.my:8787 Logout - + Disconnettiti @@ -864,127 +868,127 @@ Example: https://server.my:8787 Minimize to tray - + Minimizza nella tray Start in tray - + Avvia nella tray Group's sidebar - + Barra laterale dei gruppi Circular Avatars - + Avatar Circolari Decrypt messages in sidebar - + Decripta messaggi nella barra laterale Show buttons in timeline - + Mostra pulsanti nella timeline Typing notifications - + Notifiche di scrittura Sort rooms by unreads - + Ordina stanze per non letti Read receipts - + Ricevute di lettura Send messages as Markdown - + Invia messaggi come Markdown Desktop notifications - + Notifiche desktop Scale factor - + Fattore di scala Font size - + Dimensione dei caratteri Font Family - + Famiglia dei caratteri Theme - + Tema Device ID - + ID Dispositivo Device Fingerprint - + Impronta digitale del dispositivo Session Keys - + Chiavi di Sessione IMPORT - + IMPORTA EXPORT - + ESPORTA ENCRYPTION - + CRITTOGRAFIA GENERAL - + GENERALE INTERFACE - + INTERFACCIA Emoji Font Family - + Famiglia dei caratteri delle Emoji Open Sessions File - + Apri File delle Sessioni @@ -998,34 +1002,34 @@ Example: https://server.my:8787 Error - + Errore File Password - + Password del File Enter the passphrase to decrypt the file: - + Inserisci la passphrase per decriptare il file: The password cannot be empty - + La password non può essere vuota Enter passphrase to encrypt your session keys: - + Inserisci la passphrase per criptare le tue chiavi di sessione: File to save the exported session keys - + File ove salvare le chiavi di sessione esportate @@ -1033,22 +1037,22 @@ Example: https://server.my:8787 Welcome to nheko! The desktop client for the Matrix protocol. - + Benvenuto su nheko! Il client desktop per il protocollo Matrix. Enjoy your stay! - + Goditi la permanenza! REGISTER - + REGISTRATI LOGIN - + ACCEDI @@ -1056,7 +1060,7 @@ Example: https://server.my:8787 Yesterday - + Ieri @@ -1064,42 +1068,42 @@ Example: https://server.my:8787 Create room - + Crea stanza Cancel - + Annulla Name - + Nome Topic - + Argomento Alias - + Alias Room Visibility - + Visibilità Stanza Room Preset - + Preset Stanza Direct Chat - + Chat Diretta @@ -1107,22 +1111,22 @@ Example: https://server.my:8787 Open Fallback in Browser - + Apertura di Ripiego nel Browser Cancel - + Annulla Confirm - + Conferma Open the fallback, follow the steps and confirm after completing them. - + Apri il ripiego, segui i passaggi e conferma dopo averli completati. @@ -1130,12 +1134,12 @@ Example: https://server.my:8787 Cancel - + Annulla User ID to invite - + ID utente da invitare @@ -1143,17 +1147,17 @@ Example: https://server.my:8787 Join - + Entra Cancel - + Annulla Room ID or alias - + ID della stanza o alias @@ -1161,12 +1165,12 @@ Example: https://server.my:8787 Cancel - + Annulla Are you sure you want to leave? - + Sei sicuro di voler uscire? @@ -1174,12 +1178,12 @@ Example: https://server.my:8787 Cancel - + Annulla Logout. Are you sure? - + Uscita. Ne sei certo? @@ -1187,19 +1191,21 @@ Example: https://server.my:8787 Upload - + Upload Cancel - + Annulla Media type: %1 Media size: %2 - + Tipo media: %1 +Peso media: %2 + @@ -1207,17 +1213,17 @@ Media size: %2 Cancel - + Annulla Confirm - + Conferma Solve the reCAPTCHA and press the confirm button - + Risolvi il reCAPTCHA e premi il pulsante di conferma @@ -1225,12 +1231,12 @@ Media size: %2 Read receipts - + Ricevute di lettura Close - + Chiudi @@ -1238,12 +1244,12 @@ Media size: %2 Today %1 - + Oggi %1 Yesterday %1 - + Ieri %1 @@ -1251,128 +1257,130 @@ Media size: %2 Settings - + Impostazioni Info - + Informazioni Internal ID - + ID interno Room Version - + Versione Stanza Notifications - + Notifiche Muted - + Silenziata Mentions only - + Solo menzioni All messages - + Tutti i messaggi Room access - + Accesso stanza Anyone and guests - + Chiunque ed ospiti Anyone - + Chiunque conosca il link della stanza (no ospiti) Invited users - + Utenti invitati Encryption - + Crittografia End-to-End Encryption - + Crittografia End-to-End Encryption is currently experimental and things might break unexpectedly. <br>Please take note that it can't be disabled afterwards. - + La crittografia è ancora sperimentale e le cose potrebbero rompersi inaspettatamente. <br>Per favore prendi nota che in seguito non potrà essere disabilitata. Respond to key requests - + Rispondi alle richieste di chiavi Whether or not the client should respond automatically with the session keys upon request. Use with caution, this is a temporary measure to test the E2E implementation until device verification is completed. - + Indica se il client deve rispondere automaticamente con le chiavi di sessione + su richiesta. Usa con cautela, questa è una misura temporanea per testare + l'implementazione di E2E fino al completamento della verifica dei dispositivi. %n member(s) - - - + + %n membro + %n membri Failed to enable encryption: %1 - + Impossibile abilitare la crittografia: %1 Select an avatar - + Scegli un avatar All Files (*) - + Tutti i File (*) The selected file is not an image - + Il file selezionato non è un'immagine Error while reading file: %1 - + Errore durante la lettura del file: %1 Failed to upload image: %s - + Impossibile fare l'upload dell'immagine: %s @@ -1380,27 +1388,27 @@ Media size: %2 Ban the user from the room - + Banna l'utente dalla stanza Ignore messages from this user - + Ignora i messaggi da questo utente Kick the user from the room - + Scaccia l'utente dalla stanza Start a conversation - + Inizia una conversazione Devices - + Dispositivi @@ -1408,42 +1416,42 @@ Media size: %2 Smileys & People - + Faccine & Persone Animals & Nature - + Animali & Natura Food & Drink - + Cibi & Bevande Activity - + Attività Travel & Places - + Viaggi & Luoghi Objects - + Oggetti Symbols - + Simboli Flags - + Bandiere @@ -1451,82 +1459,82 @@ Media size: %2 You sent an audio clip - + Hai inviato una clip audio %1 sent an audio clip - + %1 ha inviato una clip audio You sent an image - + Hai inviato un'immagine %1 sent an image - + %1 ha inviato un'immagine You sent a file - + Hai inviato un file %1 sent a file - + %1 ha inviato un file You sent a video - + Hai inviato un video %1 sent a video - + %1 ha inviato un video You sent a sticker - + Hai inviato uno sticker %1 sent a sticker - + %1 ha inviato uno sticker You sent a notification - + Hai inviato una notifica %1 sent a notification - + %1 ha inviato una notifica You: %1 - + Tu: %1 %1: %2 - + %1: %2 You sent an encrypted message - + Hai inviato un messaggio criptato %1 sent an encrypted message - + %1 ha inviato un messaggio criptato @@ -1534,12 +1542,12 @@ Media size: %2 This Room - + Questa Stanza All Rooms - + Tutte le Stanze @@ -1547,7 +1555,32 @@ Media size: %2 Unknown Message Type - + Tipo di Messaggio sconosciuto + + + + + + + Tag room as: + stanza come: + + + + Favourite + Standard matrix tag for favourites + Tag matrix standard per i preferiti + + + + Adds or removes the specified tag. + WhatsThis hint for tag menu actions + Aggiungi o rimuovi il tag specificato. + + + + Highlight message on hover + Evidenzia il messaggio al passaggio del mouse From 9eddcfc42f3cd4e513f72d9b7fef9a98b43a378d Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 30 May 2020 16:37:51 +0200 Subject: [PATCH 12/24] Remove some redundant functions --- src/Cache.cpp | 14 +++++++------ src/ChatPage.cpp | 6 ++++-- src/EventAccessors.cpp | 6 ++++++ src/EventAccessors.h | 3 +++ src/Utils.h | 36 ---------------------------------- src/popups/UserMentions.cpp | 11 +++++++---- src/timeline/TimelineModel.cpp | 4 ++-- 7 files changed, 30 insertions(+), 50 deletions(-) diff --git a/src/Cache.cpp b/src/Cache.cpp index 1061e60e..009cbabc 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -31,6 +31,7 @@ #include "Cache.h" #include "Cache_p.h" +#include "EventAccessors.h" #include "Logging.h" #include "Utils.h" @@ -1947,13 +1948,14 @@ Cache::saveTimelineMessages(lmdb::txn &txn, json obj = json::object(); - obj["event"] = utils::serialize_event(e); + obj["event"] = mtx::accessors::serialize_event(e); obj["token"] = res.prev_batch; - lmdb::dbi_put(txn, - db, - lmdb::val(std::to_string(utils::event_timestamp(e))), - lmdb::val(obj.dump())); + lmdb::dbi_put( + txn, + db, + lmdb::val(std::to_string(obj["event"]["origin_server_ts"].get())), + lmdb::val(obj.dump())); } } @@ -2026,7 +2028,7 @@ Cache::saveTimelineMentions(lmdb::txn &txn, using namespace mtx::events::state; for (const auto ¬if : res) { - const auto event_id = utils::event_id(notif.event); + const auto event_id = mtx::accessors::event_id(notif.event); // double check that we have the correct room_id... if (room_id.compare(notif.room_id) != 0) { diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 2b55b91e..c7f5164a 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -26,6 +26,7 @@ #include "Cache.h" #include "Cache_p.h" #include "ChatPage.h" +#include "EventAccessors.h" #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" @@ -885,7 +886,7 @@ void ChatPage::sendDesktopNotifications(const mtx::responses::Notifications &res) { for (const auto &item : res.notifications) { - const auto event_id = utils::event_id(item.event); + const auto event_id = mtx::accessors::event_id(item.event); try { if (item.read) { @@ -895,7 +896,8 @@ ChatPage::sendDesktopNotifications(const mtx::responses::Notifications &res) if (!cache::isNotificationSent(event_id)) { const auto room_id = QString::fromStdString(item.room_id); - const auto user_id = utils::event_sender(item.event); + const auto user_id = + QString::fromStdString(mtx::accessors::sender(item.event)); // We should only sent one notification per event. cache::markSentNotification(event_id); diff --git a/src/EventAccessors.cpp b/src/EventAccessors.cpp index 7f28eb46..da4e324a 100644 --- a/src/EventAccessors.cpp +++ b/src/EventAccessors.cpp @@ -400,3 +400,9 @@ mtx::accessors::media_width(const mtx::events::collections::TimelineEvents &even { return std::visit(EventMediaWidth{}, event); } + +nlohmann::json +mtx::accessors::serialize_event(const mtx::events::collections::TimelineEvents &event) +{ + return std::visit([](const auto &e) { return nlohmann::json{e}; }, event); +} diff --git a/src/EventAccessors.h b/src/EventAccessors.h index c9ac4d00..a7577d86 100644 --- a/src/EventAccessors.h +++ b/src/EventAccessors.h @@ -63,4 +63,7 @@ media_height(const mtx::events::collections::TimelineEvents &event); uint64_t media_width(const mtx::events::collections::TimelineEvents &event); + +nlohmann::json +serialize_event(const mtx::events::collections::TimelineEvents &event); } diff --git a/src/Utils.h b/src/Utils.h index 80f2aa70..07a4a648 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -186,42 +186,6 @@ erase_if(ContainerT &items, const PredicateT &predicate) } } -inline uint64_t -event_timestamp(const mtx::events::collections::TimelineEvents &event) -{ - return std::visit([](auto msg) { return msg.origin_server_ts; }, event); -} - -inline nlohmann::json -serialize_event(const mtx::events::collections::TimelineEvents &event) -{ - return std::visit([](auto msg) { return json(msg); }, event); -} - -inline mtx::events::EventType -event_type(const mtx::events::collections::TimelineEvents &event) -{ - return std::visit([](auto msg) { return msg.type; }, event); -} - -inline std::string -event_id(const mtx::events::collections::TimelineEvents &event) -{ - return std::visit([](auto msg) { return msg.event_id; }, event); -} - -inline QString -eventId(const mtx::events::collections::TimelineEvents &event) -{ - return QString::fromStdString(event_id(event)); -} - -inline QString -event_sender(const mtx::events::collections::TimelineEvents &event) -{ - return std::visit([](auto msg) { return QString::fromStdString(msg.sender); }, event); -} - template QString message_body(const mtx::events::collections::TimelineEvents &event) diff --git a/src/popups/UserMentions.cpp b/src/popups/UserMentions.cpp index 2e70dbd3..23a679f1 100644 --- a/src/popups/UserMentions.cpp +++ b/src/popups/UserMentions.cpp @@ -8,9 +8,9 @@ #include "Cache.h" #include "ChatPage.h" +#include "EventAccessors.h" #include "Logging.h" #include "UserMentions.h" -//#include "timeline/TimelineItem.h" using namespace popups; @@ -75,12 +75,15 @@ UserMentions::initializeMentions(const QMap Date: Sat, 30 May 2020 16:53:57 +0200 Subject: [PATCH 13/24] Skip precompiled headers for obc-c code --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e0a5518..09b1c1fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -514,6 +514,9 @@ set(TRANSLATION_DEPS ${LANG_QRC} ${QRC} ${QM_SRC}) if (APPLE) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Foundation -framework Cocoa") set(SRC_FILES ${SRC_FILES} src/notifications/ManagerMac.mm src/emoji/MacHelper.mm) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0") + set_source_files_properties( src/notifications/ManagerMac.mm src/emoji/MacHelper.mm PROPERTIES SKIP_PRECOMPILE_HEADERS ON) + endif() elseif (WIN32) file(DOWNLOAD "https://raw.githubusercontent.com/mohabouje/WinToast/41ed1c58d5dce0ee9c01dbdeac05be45358d4f57/src/wintoastlib.cpp" From 50d5891493a2454b8e90520f28adc1bec38122ea Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 30 May 2020 17:25:18 +0200 Subject: [PATCH 14/24] Fix serialization bug introduced in 9eddcfc42f3cd4e513f72d9b7fef9a98b43a378d --- src/EventAccessors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EventAccessors.cpp b/src/EventAccessors.cpp index da4e324a..a2d8adbb 100644 --- a/src/EventAccessors.cpp +++ b/src/EventAccessors.cpp @@ -404,5 +404,5 @@ mtx::accessors::media_width(const mtx::events::collections::TimelineEvents &even nlohmann::json mtx::accessors::serialize_event(const mtx::events::collections::TimelineEvents &event) { - return std::visit([](const auto &e) { return nlohmann::json{e}; }, event); + return std::visit([](const auto &e) { return nlohmann::json(e); }, event); } From c8ba385cb9144e31d6f1fdf4b3ec6bccfc4123dd Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 30 May 2020 17:37:18 +0200 Subject: [PATCH 15/24] Install dependencies for arm manually to prevent timeout --- .ci/install.sh | 1 + .travis.yml | 11 ++--------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.ci/install.sh b/.ci/install.sh index d1bff54b..8d27d301 100755 --- a/.ci/install.sh +++ b/.ci/install.sh @@ -3,6 +3,7 @@ set -ex if [ "$FLATPAK" ]; then + sudo apt-get -y install flatpak flatpak-builder elfutils flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo flatpak --noninteractive install --user flathub org.kde.Platform//5.14 flatpak --noninteractive install --user flathub org.kde.Sdk//5.14 diff --git a/.travis.yml b/.travis.yml index 443836cf..eec32290 100644 --- a/.travis.yml +++ b/.travis.yml @@ -113,10 +113,6 @@ matrix: apt: sources: - sourceline: 'ppa:alexlarsson/flatpak' - packages: - - flatpak - - flatpak-builder - - elfutils - os: linux arch: arm64 env: @@ -128,20 +124,17 @@ matrix: sources: - sourceline: 'ppa:alexlarsson/flatpak' packages: - - flatpak - - flatpak-builder - - elfutils - librsvg2-bin before_install: # Use TRAVIS_TAG if defined, or the short commit SHA otherwise - export VERSION=${TRAVIS_TAG:-$(git rev-parse --short HEAD)} install: - - travis_wait ./.ci/install.sh + - ./.ci/install.sh - export PATH=/usr/local/bin:${PATH} script: - - travis_wait ./.ci/script.sh + - ./.ci/script.sh - sed -i -e "s/VERSION_NAME_VALUE/${VERSION}/g" ./.ci/bintray-release.json || true - cp ./.ci/bintray-release.json . deploy: From 190b6cb3c70366f420e42b91117c90c4bd2b5bd3 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 30 May 2020 18:29:40 +0200 Subject: [PATCH 16/24] Add travis_wait to flatpak builds --- .ci/script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/script.sh b/.ci/script.sh index 15e7f8cf..555b4825 100755 --- a/.ci/script.sh +++ b/.ci/script.sh @@ -6,7 +6,7 @@ if [ "$FLATPAK" ]; then mkdir -p build-flatpak cd build-flatpak - flatpak-builder --ccache --repo=repo --subject="Build of Nheko ${VERSION} `date`" app ../io.github.NhekoReborn.Nheko.json + travis_wait flatpak-builder --ccache --repo=repo --subject="Build of Nheko ${VERSION} `date`" app ../io.github.NhekoReborn.Nheko.json flatpak build-bundle repo nheko-${VERSION}-${ARCH}.flatpak io.github.NhekoReborn.Nheko master mkdir ../artifacts From 5ca5b4561ed00a15d3ccb2eb92360ddf241b778d Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 30 May 2020 18:37:00 +0200 Subject: [PATCH 17/24] Travis wait can only be used in a top level command? --- .ci/script.sh | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/script.sh b/.ci/script.sh index 555b4825..15e7f8cf 100755 --- a/.ci/script.sh +++ b/.ci/script.sh @@ -6,7 +6,7 @@ if [ "$FLATPAK" ]; then mkdir -p build-flatpak cd build-flatpak - travis_wait flatpak-builder --ccache --repo=repo --subject="Build of Nheko ${VERSION} `date`" app ../io.github.NhekoReborn.Nheko.json + flatpak-builder --ccache --repo=repo --subject="Build of Nheko ${VERSION} `date`" app ../io.github.NhekoReborn.Nheko.json flatpak build-bundle repo nheko-${VERSION}-${ARCH}.flatpak io.github.NhekoReborn.Nheko master mkdir ../artifacts diff --git a/.travis.yml b/.travis.yml index eec32290..1dc2feeb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -134,7 +134,7 @@ install: - export PATH=/usr/local/bin:${PATH} script: - - ./.ci/script.sh + - travis_wait ./.ci/script.sh - sed -i -e "s/VERSION_NAME_VALUE/${VERSION}/g" ./.ci/bintray-release.json || true - cp ./.ci/bintray-release.json . deploy: From 95f29a3d19d44b3738349dfaa437b600850bef2b Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 30 May 2020 19:01:32 +0200 Subject: [PATCH 18/24] Try travis_wait alternative --- .ci/script.sh | 16 +++++++++++++++- .travis.yml | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.ci/script.sh b/.ci/script.sh index 15e7f8cf..0aa56d50 100755 --- a/.ci/script.sh +++ b/.ci/script.sh @@ -6,7 +6,21 @@ if [ "$FLATPAK" ]; then mkdir -p build-flatpak cd build-flatpak - flatpak-builder --ccache --repo=repo --subject="Build of Nheko ${VERSION} `date`" app ../io.github.NhekoReborn.Nheko.json + flatpak-builder --ccache --repo=repo --subject="Build of Nheko ${VERSION} `date`" app ../io.github.NhekoReborn.Nheko.json & + + # to prevent flatpak builder from timing out on arm, run it in the background and print something every minute for up to 30 minutes. + minutes=0 + limit=30 + while kill -0 $! >/dev/null 2>&1; do + if [ $minutes == $limit ]; then + break; + fi + + minutes=$((minutes+1)) + + sleep 60 + done + flatpak build-bundle repo nheko-${VERSION}-${ARCH}.flatpak io.github.NhekoReborn.Nheko master mkdir ../artifacts diff --git a/.travis.yml b/.travis.yml index 1dc2feeb..eec32290 100644 --- a/.travis.yml +++ b/.travis.yml @@ -134,7 +134,7 @@ install: - export PATH=/usr/local/bin:${PATH} script: - - travis_wait ./.ci/script.sh + - ./.ci/script.sh - sed -i -e "s/VERSION_NAME_VALUE/${VERSION}/g" ./.ci/bintray-release.json || true - cp ./.ci/bintray-release.json . deploy: From f8903f493f561f0cc027887ea71502e26861639e Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 31 May 2020 11:39:39 +0200 Subject: [PATCH 19/24] Extend timeout --- .ci/script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/script.sh b/.ci/script.sh index 0aa56d50..32de9465 100755 --- a/.ci/script.sh +++ b/.ci/script.sh @@ -10,7 +10,7 @@ if [ "$FLATPAK" ]; then # to prevent flatpak builder from timing out on arm, run it in the background and print something every minute for up to 30 minutes. minutes=0 - limit=30 + limit=40 while kill -0 $! >/dev/null 2>&1; do if [ $minutes == $limit ]; then break; From 43d2ebc0958d364ff24ae70920a3edeef7d0ce72 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 5 Jun 2020 23:34:00 +0200 Subject: [PATCH 20/24] Fix Qt5.15 issues fixes #214 --- src/LoginPage.cpp | 2 +- src/RegisterPage.cpp | 8 ++++---- src/UserSettingsPage.cpp | 10 +++++----- src/Utils.cpp | 4 ++-- src/dialogs/CreateRoom.cpp | 4 ++-- src/dialogs/ReadReceipts.cpp | 10 ++++++---- src/ui/Avatar.cpp | 1 + src/ui/InfoMessage.cpp | 1 + src/ui/Painter.h | 3 ++- 9 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp index 4ed08901..9a920d1d 100644 --- a/src/LoginPage.cpp +++ b/src/LoginPage.cpp @@ -133,7 +133,7 @@ LoginPage::LoginPage(QWidget *parent) form_layout_->addLayout(matrixidLayout_); form_layout_->addWidget(password_input_); - form_layout_->addWidget(deviceName_, Qt::AlignHCenter, nullptr); + form_layout_->addWidget(deviceName_, Qt::AlignHCenter); form_layout_->addLayout(serverLayout_); button_layout_ = new QHBoxLayout(); diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp index e57961ef..b8fe93b5 100644 --- a/src/RegisterPage.cpp +++ b/src/RegisterPage.cpp @@ -107,10 +107,10 @@ RegisterPage::RegisterPage(QWidget *parent) tr("A server that allows registration. Since matrix is decentralized, you need to first " "find a server you can register on or host your own.")); - form_layout_->addWidget(username_input_, Qt::AlignHCenter, nullptr); - form_layout_->addWidget(password_input_, Qt::AlignHCenter, nullptr); - form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter, nullptr); - form_layout_->addWidget(server_input_, Qt::AlignHCenter, nullptr); + form_layout_->addWidget(username_input_, Qt::AlignHCenter); + form_layout_->addWidget(password_input_, Qt::AlignHCenter); + form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter); + form_layout_->addWidget(server_input_, Qt::AlignHCenter); button_layout_ = new QHBoxLayout(); button_layout_->setSpacing(0); diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index 38b76404..dfd99069 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -612,22 +612,22 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge topLayout_->addWidget(versionInfo); connect(themeCombo_, - static_cast(&QComboBox::activated), + static_cast(&QComboBox::currentTextChanged), [this](const QString &text) { settings_->setTheme(text.toLower()); emit themeChanged(); }); connect(scaleFactorCombo_, - static_cast(&QComboBox::activated), + static_cast(&QComboBox::currentTextChanged), [](const QString &factor) { utils::setScaleFactor(factor.toFloat()); }); connect(fontSizeCombo_, - static_cast(&QComboBox::activated), + static_cast(&QComboBox::currentTextChanged), [this](const QString &size) { settings_->setFontSize(size.trimmed().toDouble()); }); connect(fontSelectionCombo_, - static_cast(&QComboBox::activated), + static_cast(&QComboBox::currentTextChanged), [this](const QString &family) { settings_->setFontFamily(family.trimmed()); }); connect(emojiFontSelectionCombo_, - static_cast(&QComboBox::activated), + static_cast(&QComboBox::currentTextChanged), [this](const QString &family) { settings_->setEmojiFontFamily(family.trimmed()); }); connect(trayToggle_, &Toggle::toggled, this, [this](bool disabled) { settings_->setTray(!disabled); diff --git a/src/Utils.cpp b/src/Utils.cpp index d539eac5..26ea124c 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -142,13 +142,13 @@ utils::descriptiveTime(const QDateTime &then) const auto days = then.daysTo(now); if (days == 0) - return then.time().toString(Qt::DefaultLocaleShortDate); + return QLocale::system().toString(then.time(), QLocale::ShortFormat); else if (days < 2) return QString(QCoreApplication::translate("descriptiveTime", "Yesterday")); else if (days < 7) return then.toString("dddd"); - return then.date().toString(Qt::DefaultLocaleShortDate); + return QLocale::system().toString(then.date(), QLocale::ShortFormat); } DescInfo diff --git a/src/dialogs/CreateRoom.cpp b/src/dialogs/CreateRoom.cpp index 06676d3d..be5b4638 100644 --- a/src/dialogs/CreateRoom.cpp +++ b/src/dialogs/CreateRoom.cpp @@ -112,7 +112,7 @@ CreateRoom::CreateRoom(QWidget *parent) }); connect(visibilityCombo_, - static_cast(&QComboBox::activated), + static_cast(&QComboBox::currentTextChanged), [this](const QString &text) { if (text == "Private") { request_.visibility = mtx::requests::Visibility::Private; @@ -122,7 +122,7 @@ CreateRoom::CreateRoom(QWidget *parent) }); connect(presetCombo_, - static_cast(&QComboBox::activated), + static_cast(&QComboBox::currentTextChanged), [this](const QString &text) { if (text == "Private Chat") { request_.preset = mtx::requests::Preset::PrivateChat; diff --git a/src/dialogs/ReadReceipts.cpp b/src/dialogs/ReadReceipts.cpp index 970d9125..7dcffc28 100644 --- a/src/dialogs/ReadReceipts.cpp +++ b/src/dialogs/ReadReceipts.cpp @@ -75,15 +75,17 @@ ReceiptItem::dateFormat(const QDateTime &then) const auto days = then.daysTo(now); if (days == 0) - return tr("Today %1").arg(then.time().toString(Qt::DefaultLocaleShortDate)); + return tr("Today %1") + .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); else if (days < 2) - return tr("Yesterday %1").arg(then.time().toString(Qt::DefaultLocaleShortDate)); + 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(then.time().toString(Qt::DefaultLocaleShortDate)); + .arg(QLocale::system().toString(then.time(), QLocale::ShortFormat)); - return then.toString(Qt::DefaultLocaleShortDate); + return QLocale::system().toString(then.time(), QLocale::ShortFormat); } ReadReceipts::ReadReceipts(QWidget *parent) diff --git a/src/ui/Avatar.cpp b/src/ui/Avatar.cpp index cb77d1a8..70ebfcf2 100644 --- a/src/ui/Avatar.cpp +++ b/src/ui/Avatar.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "AvatarProvider.h" diff --git a/src/ui/InfoMessage.cpp b/src/ui/InfoMessage.cpp index 27bc0a5f..0b69564d 100644 --- a/src/ui/InfoMessage.cpp +++ b/src/ui/InfoMessage.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/src/ui/Painter.h b/src/ui/Painter.h index 4d227a5a..2bb0981b 100644 --- a/src/ui/Painter.h +++ b/src/ui/Painter.h @@ -3,6 +3,7 @@ #include #include #include +#include #include class Painter : public QPainter @@ -163,5 +164,5 @@ public: private: Painter &_painter; - QPainter::RenderHints hints_ = 0; + QPainter::RenderHints hints_ = {}; }; From f4b84327e8e71f62134de753c8b5c48c7e1018c1 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 6 Jun 2020 00:04:18 +0200 Subject: [PATCH 21/24] Limit jobs on arm --- .ci/script.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.ci/script.sh b/.ci/script.sh index 32de9465..63e7f135 100755 --- a/.ci/script.sh +++ b/.ci/script.sh @@ -6,7 +6,12 @@ if [ "$FLATPAK" ]; then mkdir -p build-flatpak cd build-flatpak - flatpak-builder --ccache --repo=repo --subject="Build of Nheko ${VERSION} `date`" app ../io.github.NhekoReborn.Nheko.json & + jobsarg="" + if [ "$ARCH" = "arm64" ]; then + jobsarg="--jobs=2" + fi + + flatpak-builder --ccache --repo=repo --subject="Build of Nheko ${VERSION} $jobsarg `date`" app ../io.github.NhekoReborn.Nheko.json & # to prevent flatpak builder from timing out on arm, run it in the background and print something every minute for up to 30 minutes. minutes=0 From c40429af23d42121d3df82b9212928377ff68d9e Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 6 Jun 2020 13:16:38 +0200 Subject: [PATCH 22/24] Bump mtxclient version May fix #213 --- CMakeLists.txt | 2 +- io.github.NhekoReborn.Nheko.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09b1c1fb..4da2373c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -334,7 +334,7 @@ if(USE_BUNDLED_MTXCLIENT) FetchContent_Declare( MatrixClient GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git - GIT_TAG f5c78f4331b62a1e25a2d839cb38b07bb9bd7829 + GIT_TAG 795b6a82d4f10c629ce0eb99803cc677c413f940 ) FetchContent_MakeAvailable(MatrixClient) else() diff --git a/io.github.NhekoReborn.Nheko.json b/io.github.NhekoReborn.Nheko.json index 50fa3b33..299808be 100644 --- a/io.github.NhekoReborn.Nheko.json +++ b/io.github.NhekoReborn.Nheko.json @@ -146,9 +146,9 @@ "name": "mtxclient", "sources": [ { - "sha256": "16203a92b03c488178b31bedca9d9015b1d406443f7e5363a2e09171e50f8dfc", + "sha256": "7ba85bb477c9e17e2389faf2333034aa9ceae4b1c65d6bf5f7067f2799e9b770", "type": "archive", - "url": "https://github.com/Nheko-Reborn/mtxclient/archive/f5c78f4331b62a1e25a2d839cb38b07bb9bd7829.tar.gz" + "url": "https://github.com/Nheko-Reborn/mtxclient/archive/795b6a82d4f10c629ce0eb99803cc677c413f940.tar.gz" } ] }, From 5e684a0a2f509f6b8b202e3955a022c4f5019dfa Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 6 Jun 2020 15:49:19 +0200 Subject: [PATCH 23/24] Download boost from sourceforge Official download links seem to break frequently because of data caps. --- io.github.NhekoReborn.Nheko.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io.github.NhekoReborn.Nheko.json b/io.github.NhekoReborn.Nheko.json index 299808be..7ffb1995 100644 --- a/io.github.NhekoReborn.Nheko.json +++ b/io.github.NhekoReborn.Nheko.json @@ -131,7 +131,7 @@ { "sha256": "59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722", "type": "archive", - "url": "https://dl.bintray.com/boostorg/release/1.72.0/source/boost_1_72_0.tar.bz2" + "url": "https://sourceforge.net/projects/boost/files/boost/1.72.0/boost_1_72_0.tar.bz2" } ] }, From e5a55ab1b9f258b973b4a0c3c48fa88a964c94a5 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 7 Jun 2020 14:53:35 +0200 Subject: [PATCH 24/24] Smooth scaling for images Fixes some issues with inline images. --- src/MxcImageProvider.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp index 8e67375d..a197e4aa 100644 --- a/src/MxcImageProvider.cpp +++ b/src/MxcImageProvider.cpp @@ -17,7 +17,8 @@ MxcImageResponse::run() auto data = cache::image(fileName); if (!data.isNull()) { m_image = utils::readImage(&data); - m_image = m_image.scaled(m_requestedSize, Qt::KeepAspectRatio); + m_image = m_image.scaled( + m_requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); m_image.setText("mxc url", "mxc://" + m_id); if (!m_image.isNull()) {