From b453b6578732a1d71d64ab0e08c924d31cb6b898 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 15 Jul 2021 17:56:32 +0200 Subject: Try to make scrolling emoji picker a bit smoother --- resources/qml/emoji/EmojiPicker.qml | 1 + 1 file changed, 1 insertion(+) (limited to 'resources/qml') diff --git a/resources/qml/emoji/EmojiPicker.qml b/resources/qml/emoji/EmojiPicker.qml index 6f10a230..354e340c 100644 --- a/resources/qml/emoji/EmojiPicker.qml +++ b/resources/qml/emoji/EmojiPicker.qml @@ -130,6 +130,7 @@ Menu { boundsBehavior: Flickable.StopAtBounds clip: true currentIndex: -1 // prevent sorting from stealing focus + cacheBuffer: 500 // Individual emoji delegate: AbstractButton { -- cgit 1.4.1 From 0b864d948586d6cc3ef3968376a5b932e06b793e Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 16 Jul 2021 11:47:49 +0200 Subject: Fix replies not reloading after fetching them --- resources/qml/TimelineRow.qml | 38 +++++++++++++++++++------------------- src/timeline/TimelineModel.cpp | 8 ++++++++ src/timeline/TimelineModel.h | 5 +---- 3 files changed, 28 insertions(+), 23 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index 58e367a0..70db08e7 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -86,29 +86,29 @@ Item { // fancy reply, if this is a reply Reply { function fromModel(role) { - return replyTo != "" ? room.dataById(replyTo, role) : null; + return replyTo != "" ? room.dataById(replyTo, role, r.eventId) : null; } visible: replyTo - userColor: TimelineManager.userColor(userId, Nheko.colors.base) - blurhash: fromModel(Room.Blurhash) ?? "" - body: fromModel(Room.Body) ?? "" - formattedBody: fromModel(Room.FormattedBody) ?? "" + userColor: replyTo, TimelineManager.userColor(userId, Nheko.colors.base) + blurhash: replyTo, fromModel(Room.Blurhash) ?? "" + body: replyTo, fromModel(Room.Body) ?? "" + formattedBody: replyTo, fromModel(Room.FormattedBody) ?? "" eventId: fromModel(Room.EventId) ?? "" - filename: fromModel(Room.Filename) ?? "" - filesize: fromModel(Room.Filesize) ?? "" - proportionalHeight: fromModel(Room.ProportionalHeight) ?? 1 - type: fromModel(Room.Type) ?? MtxEvent.UnknownMessage - typeString: fromModel(Room.TypeString) ?? "" - url: fromModel(Room.Url) ?? "" - originalWidth: fromModel(Room.OriginalWidth) ?? 0 - isOnlyEmoji: fromModel(Room.IsOnlyEmoji) ?? false - userId: fromModel(Room.UserId) ?? "" - userName: fromModel(Room.UserName) ?? "" - thumbnailUrl: fromModel(Room.ThumbnailUrl) ?? "" - roomTopic: fromModel(Room.RoomTopic) ?? "" - roomName: fromModel(Room.RoomName) ?? "" - callType: fromModel(Room.CallType) ?? "" + filename: replyTo, fromModel(Room.Filename) ?? "" + filesize: replyTo, fromModel(Room.Filesize) ?? "" + proportionalHeight: replyTo, fromModel(Room.ProportionalHeight) ?? 1 + type: replyTo, fromModel(Room.Type) ?? MtxEvent.UnknownMessage + typeString: replyTo, fromModel(Room.TypeString) ?? "" + url: replyTo, fromModel(Room.Url) ?? "" + originalWidth: replyTo, fromModel(Room.OriginalWidth) ?? 0 + isOnlyEmoji: replyTo, fromModel(Room.IsOnlyEmoji) ?? false + userId: replyTo, fromModel(Room.UserId) ?? "" + userName: replyTo, fromModel(Room.UserName) ?? "" + thumbnailUrl: replyTo, fromModel(Room.ThumbnailUrl) ?? "" + roomTopic: replyTo, fromModel(Room.RoomTopic) ?? "" + roomName: replyTo, fromModel(Room.RoomName) ?? "" + callType: replyTo, fromModel(Room.CallType) ?? "" } // actual message content diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index ab11f99b..5832f56e 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -710,6 +710,14 @@ TimelineModel::data(const QModelIndex &index, int role) const return data(*event, role); } +QVariant +TimelineModel::dataById(QString id, int role, QString relatedTo) +{ + if (auto event = events.get(id.toStdString(), relatedTo.toStdString())) + return data(*event, role); + return QVariant(); +} + bool TimelineModel::canFetchMore(const QModelIndex &) const { diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index a3c973d6..b67234f2 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -215,10 +215,7 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const mtx::events::collections::TimelineEvents &event, int role) const; - Q_INVOKABLE QVariant dataById(QString id, int role) - { - return data(index(idToIndex(id)), role); - } + Q_INVOKABLE QVariant dataById(QString id, int role, QString relatedTo); bool canFetchMore(const QModelIndex &) const override; void fetchMore(const QModelIndex &) override; -- cgit 1.4.1 From 8a1666bc889d963693b5dff8f0b4c7612319644a Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 15 Jul 2021 20:37:52 +0200 Subject: Basic sticker support --- CMakeLists.txt | 2 + resources/icons/ui/sticky-note-solid.svg | 1 + resources/qml/MatrixText.qml | 8 +- resources/qml/MessageInput.qml | 29 +++++- resources/qml/MessageView.qml | 10 +- resources/qml/emoji/EmojiButton.qml | 23 ---- resources/qml/emoji/StickerPicker.qml | 174 +++++++++++++++++++++++++++++++ resources/res.qrc | 3 +- src/Cache.cpp | 7 ++ src/Cache_p.h | 6 ++ src/ImagePackModel.cpp | 91 ++++++++++++++++ src/ImagePackModel.h | 52 +++++++++ src/timeline/InputBar.cpp | 17 +++ src/timeline/InputBar.h | 2 + src/timeline/TimelineModel.cpp | 9 ++ src/timeline/TimelineModel.h | 15 ++- src/timeline/TimelineViewManager.cpp | 7 ++ 17 files changed, 419 insertions(+), 37 deletions(-) create mode 100644 resources/icons/ui/sticky-note-solid.svg delete mode 100644 resources/qml/emoji/EmojiButton.qml create mode 100644 resources/qml/emoji/StickerPicker.qml create mode 100644 src/ImagePackModel.cpp create mode 100644 src/ImagePackModel.h (limited to 'resources/qml') diff --git a/CMakeLists.txt b/CMakeLists.txt index 78900535..6b26b2e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,7 @@ set(SRC_FILES src/Olm.cpp src/RegisterPage.cpp src/SSOHandler.cpp + src/ImagePackModel.cpp src/TrayIcon.cpp src/UserSettingsPage.cpp src/UsersModel.cpp @@ -559,6 +560,7 @@ qt5_wrap_cpp(MOC_HEADERS src/MxcImageProvider.h src/RegisterPage.h src/SSOHandler.h + src/ImagePackModel.h src/TrayIcon.h src/UserSettingsPage.h src/UsersModel.h diff --git a/resources/icons/ui/sticky-note-solid.svg b/resources/icons/ui/sticky-note-solid.svg new file mode 100644 index 00000000..bc36d474 --- /dev/null +++ b/resources/icons/ui/sticky-note-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/qml/MatrixText.qml b/resources/qml/MatrixText.qml index 9129b154..35e5f7e7 100644 --- a/resources/qml/MatrixText.qml +++ b/resources/qml/MatrixText.qml @@ -8,6 +8,7 @@ import im.nheko 1.0 TextEdit { id: r + textFormat: TextEdit.RichText readOnly: true focus: false @@ -19,14 +20,13 @@ TextEdit { onLinkActivated: Nheko.openLink(link) ToolTip.visible: hoveredLink ToolTip.text: hoveredLink + Component.onCompleted: { + TimelineManager.fixImageRendering(r.textDocument, r); + } CursorShape { anchors.fill: parent cursorShape: hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor } - Component.onCompleted: { - TimelineManager.fixImageRendering(r.textDocument, r) - } - } diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index 24f9b0e8..d4f7ca62 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later +import "./emoji" import "./voip" import QtQuick 2.12 import QtQuick.Controls 2.3 @@ -87,7 +88,7 @@ Rectangle { Layout.alignment: Qt.AlignBottom // | Qt.AlignHCenter Layout.maximumHeight: Window.height / 4 Layout.minimumHeight: Settings.fontSize - implicitWidth: inputBar.width - 4 * (22 + 16) - 24 + implicitWidth: inputBar.width - 5 * (22 + 16) - 24 TextArea { id: messageInput @@ -319,6 +320,30 @@ Rectangle { } + ImageButton { + id: stickerButton + + Layout.alignment: Qt.AlignRight | Qt.AlignBottom + Layout.margins: 8 + hoverEnabled: true + width: 22 + height: 22 + image: ":/icons/icons/ui/sticky-note-solid.svg" + ToolTip.visible: hovered + ToolTip.text: qsTr("Stickers") + onClicked: stickerPopup.visible ? stickerPopup.close() : stickerPopup.show(stickerButton, TimelineManager.completerFor("stickers", room.roomId()), function(row) { + room.input.sticker(stickerPopup.model.sourceModel, row); + TimelineManager.focusMessageInput(); + }) + + StickerPicker { + id: stickerPopup + + colors: Nheko.colors + } + + } + ImageButton { id: emojiButton @@ -330,7 +355,7 @@ Rectangle { image: ":/icons/icons/ui/smile.png" ToolTip.visible: hovered ToolTip.text: qsTr("Emoji") - onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(emojiButton, function(emoji) { + onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(function(emoji) { messageInput.insert(messageInput.cursorPosition, emoji); TimelineManager.focusMessageInput(); }) diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index 33dff122..4e605ad7 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -92,16 +92,20 @@ ScrollView { } } - EmojiButton { + ImageButton { id: reactButton visible: chat.model ? chat.model.permissions.canSend(MtxEvent.Reaction) : false width: 16 hoverEnabled: true + image: ":/icons/icons/ui/smile.png" ToolTip.visible: hovered ToolTip.text: qsTr("React") - emojiPicker: emojiPopup - event_id: row.model ? row.model.eventId : "" + onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(emojiButton, function(emoji) { + var event_id = row.model ? row.model.eventId : ""; + room.input.reaction(event_id, emoji); + TimelineManager.focusMessageInput(); + }) } ImageButton { diff --git a/resources/qml/emoji/EmojiButton.qml b/resources/qml/emoji/EmojiButton.qml deleted file mode 100644 index 5f4d23d3..00000000 --- a/resources/qml/emoji/EmojiButton.qml +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -import "../" -import QtQuick 2.10 -import QtQuick.Controls 2.1 -import im.nheko 1.0 -import im.nheko.EmojiModel 1.0 - -ImageButton { - id: emojiButton - - property var colors: currentActivePalette - property var emojiPicker - property string event_id - - image: ":/icons/icons/ui/smile.png" - onClicked: emojiPicker.visible ? emojiPicker.close() : emojiPicker.show(emojiButton, function(emoji) { - room.input.reaction(event_id, emoji); - TimelineManager.focusMessageInput(); - }) -} diff --git a/resources/qml/emoji/StickerPicker.qml b/resources/qml/emoji/StickerPicker.qml new file mode 100644 index 00000000..3fe17ef2 --- /dev/null +++ b/resources/qml/emoji/StickerPicker.qml @@ -0,0 +1,174 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import "../" +import QtGraphicalEffects 1.0 +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import im.nheko 1.0 +import im.nheko.EmojiModel 1.0 + +Menu { + id: stickerPopup + + property var callback + property var colors + property alias model: gridView.model + property var textArea + property real highlightHue: Nheko.colors.highlight.hslHue + property real highlightSat: Nheko.colors.highlight.hslSaturation + property real highlightLight: Nheko.colors.highlight.hslLightness + readonly property int stickerDim: 128 + readonly property int stickerDimPad: 128 + Nheko.paddingSmall + readonly property int stickersPerRow: 3 + + function show(showAt, model_, callback) { + console.debug("Showing sticker picker"); + model = model_; + stickerPopup.callback = callback; + popup(showAt ? showAt : null); + } + + margins: 0 + bottomPadding: 1 + leftPadding: 1 + rightPadding: 1 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + //height: columnView.implicitHeight + 4 + //width: columnView.implicitWidth + width: stickersPerRow * stickerDimPad + 20 + + Rectangle { + color: Nheko.colors.window + height: columnView.implicitHeight + 4 + width: stickersPerRow * stickerDimPad + 20 + + ColumnLayout { + id: columnView + + spacing: 0 + anchors.leftMargin: 3 + anchors.rightMargin: 3 + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.topMargin: 2 + + // Search field + TextField { + id: emojiSearch + + Layout.topMargin: 3 + Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 - 6 + palette: Nheko.colors + background: null + placeholderTextColor: Nheko.colors.buttonText + color: Nheko.colors.text + placeholderText: qsTr("Search") + selectByMouse: true + rightPadding: clearSearch.width + onTextChanged: searchTimer.restart() + onVisibleChanged: { + if (visible) + forceActiveFocus(); + + } + + Timer { + id: searchTimer + + interval: 350 // tweak as needed? + onTriggered: stickerPopup.model.searchString = emojiSearch.text + } + + ToolButton { + id: clearSearch + + visible: emojiSearch.text !== '' + icon.source: "image://colorimage/:/icons/icons/ui/round-remove-button.png?" + (clearSearch.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText) + focusPolicy: Qt.NoFocus + onClicked: emojiSearch.clear() + hoverEnabled: true + background: null + + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + } + // clear the default hover effects. + + Image { + height: parent.height - 2 * Nheko.paddingSmall + width: height + source: "image://colorimage/:/icons/icons/ui/round-remove-button.png?" + (clearSearch.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText) + + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + margins: Nheko.paddingSmall + } + + } + + } + + } + + // emoji grid + GridView { + id: gridView + + Layout.preferredHeight: cellHeight * 3.5 + Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 + Layout.leftMargin: 4 + cellWidth: stickerDimPad + cellHeight: stickerDimPad + boundsBehavior: Flickable.StopAtBounds + clip: true + currentIndex: -1 // prevent sorting from stealing focus + cacheBuffer: 500 + + // Individual emoji + delegate: AbstractButton { + width: stickerDim + height: stickerDim + hoverEnabled: true + ToolTip.text: ":" + model.shortcode + ": - " + model.body + ToolTip.visible: hovered + // TODO: maybe add favorites at some point? + onClicked: { + console.debug("Picked " + model.shortcode); + stickerPopup.close(); + callback(model.originalRow); + } + + contentItem: Image { + height: stickerDim + width: stickerDim + source: model.url.replace("mxc://", "image://MxcImage/") + fillMode: Image.PreserveAspectFit + } + + background: Rectangle { + anchors.fill: parent + color: hovered ? Nheko.colors.highlight : 'transparent' + radius: 5 + } + + } + + ScrollBar.vertical: ScrollBar { + id: emojiScroll + } + + } + + } + + } + +} diff --git a/resources/res.qrc b/resources/res.qrc index f41835f9..e9479e57 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -26,6 +26,7 @@ icons/ui/search@2x.png icons/ui/settings.png icons/ui/settings@2x.png + icons/ui/sticky-note-solid.svg icons/ui/smile.png icons/ui/smile@2x.png icons/ui/speech-bubbles-comment-option.png @@ -150,8 +151,8 @@ qml/ForwardCompleter.qml qml/TypingIndicator.qml qml/RoomSettings.qml - qml/emoji/EmojiButton.qml qml/emoji/EmojiPicker.qml + qml/emoji/StickerPicker.qml qml/UserProfile.qml qml/delegates/MessageDelegate.qml qml/delegates/TextMessage.qml diff --git a/src/Cache.cpp b/src/Cache.cpp index 7b6a6135..8c3d8c42 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -3382,6 +3382,13 @@ Cache::getChildRoomIds(const std::string &room_id) return roomids; } +std::optional +Cache::getAccountData(mtx::events::EventType type, const std::string &room_id) +{ + auto txn = ro_txn(env_); + return getAccountData(txn, type, room_id); +} + std::optional Cache::getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id) { diff --git a/src/Cache_p.h b/src/Cache_p.h index d1f6307d..3752f5e4 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -88,6 +88,12 @@ public: //! Retrieve if the room is a space bool getRoomIsSpace(lmdb::txn &txn, lmdb::dbi &statesdb); + //! retrieve a specific event from account data + //! pass empty room_id for global account data + std::optional getAccountData( + mtx::events::EventType type, + const std::string &room_id = ""); + //! Get a specific state event template std::optional> getStateEvent(const std::string &room_id, diff --git a/src/ImagePackModel.cpp b/src/ImagePackModel.cpp new file mode 100644 index 00000000..fb2599a5 --- /dev/null +++ b/src/ImagePackModel.cpp @@ -0,0 +1,91 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ImagePackModel.h" + +#include "Cache_p.h" +#include "CompletionModelRoles.h" + +ImagePackModel::ImagePackModel(const std::string &roomId, bool stickers, QObject *parent) + : QAbstractListModel(parent) + , room_id(roomId) +{ + auto accountpackV = + cache::client()->getAccountData(mtx::events::EventType::ImagePackInAccountData); + auto enabledRoomPacksV = + cache::client()->getAccountData(mtx::events::EventType::ImagePackRooms); + + std::optional accountPack; + if (accountpackV) { + auto tmp = + std::get_if>( + &*accountpackV); + if (tmp) + accountPack = tmp->content; + } + // mtx::events::msc2545::ImagePackRooms *enabledRoomPacks = nullptr; + // if (enabledRoomPacksV) + // enabledRoomPacks = + // std::get_if(&*enabledRoomPacksV); + + if (accountPack && (!accountPack->pack || (stickers ? accountPack->pack->is_sticker() + : accountPack->pack->is_emoji()))) { + QString packname; + if (accountPack->pack) + packname = QString::fromStdString(accountPack->pack->display_name); + + for (const auto &img : accountPack->images) { + if (img.second.overrides_usage() && + (stickers ? !img.second.is_sticker() : !img.second.is_emoji())) + continue; + + ImageDesc i{}; + i.shortcode = QString::fromStdString(img.first); + i.packname = packname; + i.image = img.second; + images.push_back(std::move(i)); + } + } +} + +QHash +ImagePackModel::roleNames() const +{ + return { + {CompletionModel::CompletionRole, "completionRole"}, + {CompletionModel::SearchRole, "searchRole"}, + {CompletionModel::SearchRole2, "searchRole2"}, + {Roles::Url, "url"}, + {Roles::ShortCode, "shortcode"}, + {Roles::Body, "body"}, + {Roles::PackName, "packname"}, + {Roles::OriginalRow, "originalRow"}, + }; +} + +QVariant +ImagePackModel::data(const QModelIndex &index, int role) const +{ + if (hasIndex(index.row(), index.column(), index.parent())) { + switch (role) { + case CompletionModel::CompletionRole: + return QString::fromStdString(images[index.row()].image.url); + case Roles::Url: + return QString::fromStdString(images[index.row()].image.url); + case CompletionModel::SearchRole: + case Roles::ShortCode: + return images[index.row()].shortcode; + case CompletionModel::SearchRole2: + case Roles::Body: + return QString::fromStdString(images[index.row()].image.body); + case Roles::PackName: + return images[index.row()].packname; + case Roles::OriginalRow: + return index.row(); + default: + return {}; + } + } + return {}; +} diff --git a/src/ImagePackModel.h b/src/ImagePackModel.h new file mode 100644 index 00000000..10e71b8f --- /dev/null +++ b/src/ImagePackModel.h @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include + +#include + +class ImagePackModel : public QAbstractListModel +{ + Q_OBJECT +public: + enum Roles + { + Url = Qt::UserRole, + ShortCode, + Body, + PackName, + OriginalRow, + }; + + ImagePackModel(const std::string &roomId, bool stickers, QObject *parent = nullptr); + QHash roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + (void)parent; + return (int)images.size(); + } + QVariant data(const QModelIndex &index, int role) const override; + + mtx::events::msc2545::PackImage imageAt(int row) + { + if (row < 0 || static_cast(row) >= images.size()) + return {}; + return images.at(static_cast(row)).image; + } + +private: + std::string room_id; + + struct ImageDesc + { + QString shortcode; + QString packname; + + mtx::events::msc2545::PackImage image; + }; + + std::vector images; +}; diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp index b0747a7c..0f210722 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp @@ -21,6 +21,7 @@ #include "ChatPage.h" #include "CompletionProxyModel.h" #include "Config.h" +#include "ImagePackModel.h" #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" @@ -501,6 +502,22 @@ InputBar::video(const QString &filename, room->sendMessageEvent(video, mtx::events::EventType::RoomMessage); } +void +InputBar::sticker(ImagePackModel *model, int row) +{ + if (!model || row < 0) + return; + + auto img = model->imageAt(row); + + mtx::events::msg::StickerImage sticker{}; + sticker.info = img.info.value_or(mtx::common::ImageInfo{}); + sticker.url = img.url; + sticker.body = img.body; + + room->sendMessageEvent(sticker, mtx::events::EventType::Sticker); +} + void InputBar::command(QString command, QString args) { diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h index c9728379..acedceb7 100644 --- a/src/timeline/InputBar.h +++ b/src/timeline/InputBar.h @@ -12,6 +12,7 @@ #include class TimelineModel; +class ImagePackModel; class QMimeData; class QDropEvent; class QStringList; @@ -57,6 +58,7 @@ public slots: MarkdownOverride useMarkdown = MarkdownOverride::NOT_SPECIFIED, bool rainbowify = false); void reaction(const QString &reactedEvent, const QString &reactionKey); + void sticker(ImagePackModel *model, int row); private slots: void startTyping(); diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 5832f56e..abfe28a9 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -1300,6 +1300,14 @@ struct SendMessageVisitor sendRoomEvent(msg); } + void operator()(mtx::events::Sticker msg) + { + msg.type = mtx::events::EventType::Sticker; + if (cache::isRoomEncrypted(model_->room_id_.toStdString())) { + model_->sendEncryptedMessage(msg, mtx::events::EventType::Sticker); + } else + emit model_->addPendingMessageToStore(msg); + } TimelineModel *model_; }; @@ -1309,6 +1317,7 @@ TimelineModel::addPendingMessage(mtx::events::collections::TimelineEvents event) { std::visit( [](auto &msg) { + // gets overwritten for reactions and stickers in SendMessageVisitor msg.type = mtx::events::EventType::RoomMessage; msg.event_id = "m" + http::client()->generate_txn_id(); msg.sender = http::client()->user_id().to_string(); diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index b67234f2..0e2895d4 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -410,10 +410,17 @@ template void TimelineModel::sendMessageEvent(const T &content, mtx::events::EventType eventType) { - mtx::events::RoomEvent msgCopy = {}; - msgCopy.content = content; - msgCopy.type = eventType; - emit newMessageToSend(msgCopy); + if constexpr (std::is_same_v) { + mtx::events::Sticker msgCopy = {}; + msgCopy.content = content; + msgCopy.type = eventType; + emit newMessageToSend(msgCopy); + } else { + mtx::events::RoomEvent msgCopy = {}; + msgCopy.content = content; + msgCopy.type = eventType; + emit newMessageToSend(msgCopy); + } resetReply(); resetEdit(); } diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index b39ef615..ec1b3573 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -19,6 +19,7 @@ #include "DelegateChooser.h" #include "DeviceVerificationFlow.h" #include "EventAccessors.h" +#include "ImagePackModel.h" #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" @@ -144,6 +145,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject, "im.nheko", @@ -593,6 +595,11 @@ TimelineViewManager::completerFor(QString completerName, QString roomId) auto proxy = new CompletionProxyModel(roomModel); roomModel->setParent(proxy); return proxy; + } else if (completerName == "stickers") { + auto stickerModel = new ImagePackModel(roomId.toStdString(), true); + auto proxy = new CompletionProxyModel(stickerModel); + stickerModel->setParent(proxy); + return proxy; } return nullptr; } -- cgit 1.4.1 From 9d5ba4f681901a0ee241e542fa9be5e2b73f58db Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 19 Jul 2021 03:02:30 +0200 Subject: Move sticker parsing and enable room stickers --- resources/qml/emoji/StickerPicker.qml | 2 -- src/Cache.cpp | 68 +++++++++++++++++++++++++++++++++-- src/CacheStructs.h | 7 ++++ src/Cache_p.h | 8 ++--- src/ImagePackModel.cpp | 31 +++------------- 5 files changed, 78 insertions(+), 38 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/emoji/StickerPicker.qml b/resources/qml/emoji/StickerPicker.qml index 3fe17ef2..ae1695df 100644 --- a/resources/qml/emoji/StickerPicker.qml +++ b/resources/qml/emoji/StickerPicker.qml @@ -38,8 +38,6 @@ Menu { modal: true focus: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - //height: columnView.implicitHeight + 4 - //width: columnView.implicitWidth width: stickersPerRow * stickerDimPad + 20 Rectangle { diff --git a/src/Cache.cpp b/src/Cache.cpp index 8c3d8c42..4321393c 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -3382,11 +3382,73 @@ Cache::getChildRoomIds(const std::string &room_id) return roomids; } -std::optional -Cache::getAccountData(mtx::events::EventType type, const std::string &room_id) +std::vector +Cache::getImagePacks(const std::string &room_id, bool stickers) { auto txn = ro_txn(env_); - return getAccountData(txn, type, room_id); + std::vector infos; + + auto addPack = [&infos, stickers](const mtx::events::msc2545::ImagePack &pack) { + if (!pack.pack || (stickers ? pack.pack->is_sticker() : pack.pack->is_emoji())) { + ImagePackInfo info; + if (pack.pack) + info.packname = pack.pack->display_name; + + for (const auto &img : pack.images) { + if (img.second.overrides_usage() && + (stickers ? !img.second.is_sticker() : !img.second.is_emoji())) + continue; + + info.images.insert(img); + } + + if (!info.images.empty()) + infos.push_back(std::move(info)); + } + }; + + // packs from account data + if (auto accountpack = + getAccountData(txn, mtx::events::EventType::ImagePackInAccountData, "")) { + auto tmp = + std::get_if>( + &*accountpack); + if (tmp) + addPack(tmp->content); + } + + // packs from rooms, that were enabled globally + if (auto roomPacks = getAccountData(txn, mtx::events::EventType::ImagePackRooms, "")) { + auto tmp = + std::get_if>( + &*roomPacks); + if (tmp) { + for (const auto &[room_id2, state_to_d] : tmp->content.rooms) { + // don't add stickers from this room twice + if (room_id2 == room_id) + continue; + + for (const auto &[state_id, d] : state_to_d) { + (void)d; + if (auto pack = + getStateEvent( + txn, room_id2)) + addPack(pack->content); + } + } + } + } + + // packs from current room + if (auto pack = getStateEvent(txn, room_id)) { + addPack(pack->content); + } + for (const auto &pack : + getStateEventsWithType(txn, room_id)) { + addPack(pack.content); + } + + return infos; } std::optional diff --git a/src/CacheStructs.h b/src/CacheStructs.h index 28c70055..f274d70f 100644 --- a/src/CacheStructs.h +++ b/src/CacheStructs.h @@ -11,6 +11,7 @@ #include #include +#include namespace cache { enum class CacheVersion : int @@ -109,3 +110,9 @@ struct RoomSearchResult std::string room_id; RoomInfo info; }; + +struct ImagePackInfo +{ + std::string packname; + std::map images; +}; diff --git a/src/Cache_p.h b/src/Cache_p.h index 3752f5e4..13fbc371 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -88,12 +88,6 @@ public: //! Retrieve if the room is a space bool getRoomIsSpace(lmdb::txn &txn, lmdb::dbi &statesdb); - //! retrieve a specific event from account data - //! pass empty room_id for global account data - std::optional getAccountData( - mtx::events::EventType type, - const std::string &room_id = ""); - //! Get a specific state event template std::optional> getStateEvent(const std::string &room_id, @@ -231,6 +225,8 @@ public: std::vector getParentRoomIds(const std::string &room_id); std::vector getChildRoomIds(const std::string &room_id); + std::vector getImagePacks(const std::string &room_id, bool stickers); + //! Mark a room that uses e2e encryption. void setEncryptedRoom(lmdb::txn &txn, const std::string &room_id); bool isRoomEncrypted(const std::string &room_id); diff --git a/src/ImagePackModel.cpp b/src/ImagePackModel.cpp index fb2599a5..4345e383 100644 --- a/src/ImagePackModel.cpp +++ b/src/ImagePackModel.cpp @@ -11,35 +11,12 @@ ImagePackModel::ImagePackModel(const std::string &roomId, bool stickers, QObject : QAbstractListModel(parent) , room_id(roomId) { - auto accountpackV = - cache::client()->getAccountData(mtx::events::EventType::ImagePackInAccountData); - auto enabledRoomPacksV = - cache::client()->getAccountData(mtx::events::EventType::ImagePackRooms); + auto packs = cache::client()->getImagePacks(room_id, stickers); - std::optional accountPack; - if (accountpackV) { - auto tmp = - std::get_if>( - &*accountpackV); - if (tmp) - accountPack = tmp->content; - } - // mtx::events::msc2545::ImagePackRooms *enabledRoomPacks = nullptr; - // if (enabledRoomPacksV) - // enabledRoomPacks = - // std::get_if(&*enabledRoomPacksV); - - if (accountPack && (!accountPack->pack || (stickers ? accountPack->pack->is_sticker() - : accountPack->pack->is_emoji()))) { - QString packname; - if (accountPack->pack) - packname = QString::fromStdString(accountPack->pack->display_name); - - for (const auto &img : accountPack->images) { - if (img.second.overrides_usage() && - (stickers ? !img.second.is_sticker() : !img.second.is_emoji())) - continue; + for (const auto &pack : packs) { + QString packname = QString::fromStdString(pack.packname); + for (const auto &img : pack.images) { ImageDesc i{}; i.shortcode = QString::fromStdString(img.first); i.packname = packname; -- cgit 1.4.1 From 60be0e8c09ab671cb50dfb8adeb48b15389aba3a Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 19 Jul 2021 14:57:10 +0200 Subject: Make scrolling sticker picker bearable --- resources/qml/emoji/StickerPicker.qml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'resources/qml') diff --git a/resources/qml/emoji/StickerPicker.qml b/resources/qml/emoji/StickerPicker.qml index ae1695df..eca302eb 100644 --- a/resources/qml/emoji/StickerPicker.qml +++ b/resources/qml/emoji/StickerPicker.qml @@ -130,6 +130,12 @@ Menu { currentIndex: -1 // prevent sorting from stealing focus cacheBuffer: 500 + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + // Individual emoji delegate: AbstractButton { width: stickerDim -- cgit 1.4.1 From 11c96664089e1437be1eb0ae8bca6c051da5e950 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 19 Jul 2021 17:45:55 +0200 Subject: Cache sticker picker --- resources/qml/MessageInput.qml | 2 +- resources/qml/emoji/StickerPicker.qml | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index d4f7ca62..415d67a7 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml @@ -331,7 +331,7 @@ Rectangle { image: ":/icons/icons/ui/sticky-note-solid.svg" ToolTip.visible: hovered ToolTip.text: qsTr("Stickers") - onClicked: stickerPopup.visible ? stickerPopup.close() : stickerPopup.show(stickerButton, TimelineManager.completerFor("stickers", room.roomId()), function(row) { + onClicked: stickerPopup.visible ? stickerPopup.close() : stickerPopup.show(stickerButton, room.roomId(), function(row) { room.input.sticker(stickerPopup.model.sourceModel, row); TimelineManager.focusMessageInput(); }) diff --git a/resources/qml/emoji/StickerPicker.qml b/resources/qml/emoji/StickerPicker.qml index eca302eb..a3d01d7a 100644 --- a/resources/qml/emoji/StickerPicker.qml +++ b/resources/qml/emoji/StickerPicker.qml @@ -15,7 +15,7 @@ Menu { property var callback property var colors - property alias model: gridView.model + property string roomid property var textArea property real highlightHue: Nheko.colors.highlight.hslHue property real highlightSat: Nheko.colors.highlight.hslSaturation @@ -24,9 +24,9 @@ Menu { readonly property int stickerDimPad: 128 + Nheko.paddingSmall readonly property int stickersPerRow: 3 - function show(showAt, model_, callback) { + function show(showAt, roomid_, callback) { console.debug("Showing sticker picker"); - model = model_; + roomid = roomid_; stickerPopup.callback = callback; popup(showAt ? showAt : null); } @@ -120,6 +120,8 @@ Menu { GridView { id: gridView + model: roomid ? TimelineManager.completerFor("stickers", roomid) : null + Layout.preferredHeight: cellHeight * 3.5 Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 Layout.leftMargin: 4 -- cgit 1.4.1 From 752ffa5c5187ae4e55c6cfb77ba90edd7e3848c8 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 19 Jul 2021 17:49:57 +0200 Subject: Model alias is still needed --- resources/qml/emoji/StickerPicker.qml | 1 + 1 file changed, 1 insertion(+) (limited to 'resources/qml') diff --git a/resources/qml/emoji/StickerPicker.qml b/resources/qml/emoji/StickerPicker.qml index a3d01d7a..813c0b12 100644 --- a/resources/qml/emoji/StickerPicker.qml +++ b/resources/qml/emoji/StickerPicker.qml @@ -16,6 +16,7 @@ Menu { property var callback property var colors property string roomid + property alias model: gridView.model property var textArea property real highlightHue: Nheko.colors.highlight.hslHue property real highlightSat: Nheko.colors.highlight.hslSaturation -- cgit 1.4.1 From 6d169cea7dfb4554ef09aceada33ba715b1df09c Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 19 Jul 2021 17:59:38 +0200 Subject: Fix reaction button again --- resources/qml/MessageView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index 4e605ad7..f56af237 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -101,7 +101,7 @@ ScrollView { image: ":/icons/icons/ui/smile.png" ToolTip.visible: hovered ToolTip.text: qsTr("React") - onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(emojiButton, function(emoji) { + onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(reactButton, function(emoji) { var event_id = row.model ? row.model.eventId : ""; room.input.reaction(event_id, emoji); TimelineManager.focusMessageInput(); -- cgit 1.4.1 From 88ed0fade74915e83df3a8e335d7cc49ee068d5c Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 20 Jul 2021 14:09:19 +0200 Subject: Explicitly reload data in delegates, if related events got loaded --- resources/qml/MessageView.qml | 2 ++ resources/qml/TimelineRow.qml | 39 ++++++++++++++++------------- resources/qml/delegates/MessageDelegate.qml | 11 ++++---- resources/qml/delegates/Reply.qml | 2 ++ resources/qml/emoji/StickerPicker.qml | 1 - src/timeline/TimelineModel.cpp | 4 +++ src/timeline/TimelineModel.h | 3 +++ 7 files changed, 38 insertions(+), 24 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index f56af237..564c8dc7 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -341,6 +341,7 @@ ScrollView { required property var timestamp required property int status required property int index + required property int relatedEventCacheBuster required property string previousMessageUserId required property string day required property string previousMessageDay @@ -446,6 +447,7 @@ ScrollView { trustlevel: wrapper.trustlevel timestamp: wrapper.timestamp status: wrapper.status + relatedEventCacheBuster: wrapper.relatedEventCacheBuster y: section.visible && section.active ? section.y + section.height : 0 HoverHandler { diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index 70db08e7..755ab503 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -40,6 +40,7 @@ Item { required property int trustlevel required property var timestamp required property int status + required property int relatedEventCacheBuster anchors.left: parent.left anchors.right: parent.right @@ -90,25 +91,26 @@ Item { } visible: replyTo - userColor: replyTo, TimelineManager.userColor(userId, Nheko.colors.base) - blurhash: replyTo, fromModel(Room.Blurhash) ?? "" - body: replyTo, fromModel(Room.Body) ?? "" - formattedBody: replyTo, fromModel(Room.FormattedBody) ?? "" + userColor: r.relatedEventCacheBuster, TimelineManager.userColor(userId, Nheko.colors.base) + blurhash: r.relatedEventCacheBuster, fromModel(Room.Blurhash) ?? "" + body: r.relatedEventCacheBuster, fromModel(Room.Body) ?? "" + formattedBody: r.relatedEventCacheBuster, fromModel(Room.FormattedBody) ?? "" eventId: fromModel(Room.EventId) ?? "" - filename: replyTo, fromModel(Room.Filename) ?? "" - filesize: replyTo, fromModel(Room.Filesize) ?? "" - proportionalHeight: replyTo, fromModel(Room.ProportionalHeight) ?? 1 - type: replyTo, fromModel(Room.Type) ?? MtxEvent.UnknownMessage - typeString: replyTo, fromModel(Room.TypeString) ?? "" - url: replyTo, fromModel(Room.Url) ?? "" - originalWidth: replyTo, fromModel(Room.OriginalWidth) ?? 0 - isOnlyEmoji: replyTo, fromModel(Room.IsOnlyEmoji) ?? false - userId: replyTo, fromModel(Room.UserId) ?? "" - userName: replyTo, fromModel(Room.UserName) ?? "" - thumbnailUrl: replyTo, fromModel(Room.ThumbnailUrl) ?? "" - roomTopic: replyTo, fromModel(Room.RoomTopic) ?? "" - roomName: replyTo, fromModel(Room.RoomName) ?? "" - callType: replyTo, fromModel(Room.CallType) ?? "" + filename: r.relatedEventCacheBuster, fromModel(Room.Filename) ?? "" + filesize: r.relatedEventCacheBuster, fromModel(Room.Filesize) ?? "" + proportionalHeight: r.relatedEventCacheBuster, fromModel(Room.ProportionalHeight) ?? 1 + type: r.relatedEventCacheBuster, fromModel(Room.Type) ?? MtxEvent.UnknownMessage + typeString: r.relatedEventCacheBuster, fromModel(Room.TypeString) ?? "" + url: r.relatedEventCacheBuster, fromModel(Room.Url) ?? "" + originalWidth: r.relatedEventCacheBuster, fromModel(Room.OriginalWidth) ?? 0 + isOnlyEmoji: r.relatedEventCacheBuster, fromModel(Room.IsOnlyEmoji) ?? false + userId: r.relatedEventCacheBuster, fromModel(Room.UserId) ?? "" + userName: r.relatedEventCacheBuster, fromModel(Room.UserName) ?? "" + thumbnailUrl: r.relatedEventCacheBuster, fromModel(Room.ThumbnailUrl) ?? "" + roomTopic: r.relatedEventCacheBuster, fromModel(Room.RoomTopic) ?? "" + roomName: r.relatedEventCacheBuster, fromModel(Room.RoomName) ?? "" + callType: r.relatedEventCacheBuster, fromModel(Room.CallType) ?? "" + relatedEventCacheBuster: r.relatedEventCacheBuster, fromModel(Room.RelatedEventCacheBuster) ?? 0 } // actual message content @@ -134,6 +136,7 @@ Item { roomTopic: r.roomTopic roomName: r.roomName callType: r.callType + relatedEventCacheBuster: r.relatedEventCacheBuster isReply: false } diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml index 0b060629..c64ae887 100644 --- a/resources/qml/delegates/MessageDelegate.qml +++ b/resources/qml/delegates/MessageDelegate.qml @@ -29,6 +29,7 @@ Item { required property string roomTopic required property string roomName required property string callType + required property int relatedEventCacheBuster height: chooser.childrenRect.height @@ -301,7 +302,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatPowerLevelEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatPowerLevelEvent(d.eventId) } } @@ -313,7 +314,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatJoinRuleEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatJoinRuleEvent(d.eventId) } } @@ -325,7 +326,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatHistoryVisibilityEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatHistoryVisibilityEvent(d.eventId) } } @@ -337,7 +338,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatGuestAccessEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatGuestAccessEvent(d.eventId) } } @@ -349,7 +350,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: room.formatMemberEvent(d.eventId) + formatted: d.relatedEventCacheBuster, room.formatMemberEvent(d.eventId) } } diff --git a/resources/qml/delegates/Reply.qml b/resources/qml/delegates/Reply.qml index 3a188d78..75e3d617 100644 --- a/resources/qml/delegates/Reply.qml +++ b/resources/qml/delegates/Reply.qml @@ -30,6 +30,7 @@ Item { property string roomTopic property string roomName property string callType + property int relatedEventCacheBuster width: parent.width height: replyContainer.height @@ -95,6 +96,7 @@ Item { roomTopic: r.roomTopic roomName: r.roomName callType: r.callType + relatedEventCacheBuster: r.relatedEventCacheBuster enabled: false width: parent.width isReply: true diff --git a/resources/qml/emoji/StickerPicker.qml b/resources/qml/emoji/StickerPicker.qml index 813c0b12..3731a948 100644 --- a/resources/qml/emoji/StickerPicker.qml +++ b/resources/qml/emoji/StickerPicker.qml @@ -122,7 +122,6 @@ Menu { id: gridView model: roomid ? TimelineManager.completerFor("stickers", roomid) : null - Layout.preferredHeight: cellHeight * 3.5 Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 Layout.leftMargin: 4 diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index abfe28a9..7b3f0729 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -344,6 +344,7 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj &EventStore::dataChanged, this, [this](int from, int to) { + relatedEventCacheBuster++; nhlog::ui()->debug( "data changed {} to {}", events.size() - to - 1, events.size() - from - 1); emit dataChanged(index(events.size() - to - 1, 0), @@ -443,6 +444,7 @@ TimelineModel::roleNames() const {RoomTopic, "roomTopic"}, {CallType, "callType"}, {Dump, "dump"}, + {RelatedEventCacheBuster, "relatedEventCacheBuster"}, }; } int @@ -676,6 +678,8 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r return QVariant(m); } + case RelatedEventCacheBuster: + return relatedEventCacheBuster; default: return QVariant(); } diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 0e2895d4..3c80ade8 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -208,6 +208,7 @@ public: RoomTopic, CallType, Dump, + RelatedEventCacheBuster, }; Q_ENUM(Roles); @@ -400,6 +401,8 @@ private: int notification_count = 0, highlight_count = 0; + unsigned int relatedEventCacheBuster = 0; + bool decryptDescription = true; bool m_paginationInProgress = false; bool isSpace_ = false; -- cgit 1.4.1 From 77a0c574bfc962b6c37426fb16a70ca16c08a3f5 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 29 May 2021 21:09:21 -0400 Subject: QML the room member list --- CMakeLists.txt | 4 +- resources/qml/RoomMembers.qml | 111 ++++++++++++++++++++++++++ resources/qml/TopBar.qml | 2 +- resources/res.qrc | 1 + src/MainWindow.cpp | 10 +-- src/MainWindow.h | 1 - src/MemberList.cpp | 91 ++++++++++++++++++++++ src/MemberList.h | 58 ++++++++++++++ src/dialogs/MemberList.cpp | 146 ----------------------------------- src/dialogs/MemberList.h | 57 -------------- src/main.cpp | 3 + src/timeline/TimelineModel.cpp | 12 ++- src/timeline/TimelineModel.h | 5 +- src/timeline/TimelineViewManager.cpp | 7 +- src/timeline/TimelineViewManager.h | 1 - 15 files changed, 284 insertions(+), 225 deletions(-) create mode 100644 resources/qml/RoomMembers.qml create mode 100644 src/MemberList.cpp create mode 100644 src/MemberList.h delete mode 100644 src/dialogs/MemberList.cpp delete mode 100644 src/dialogs/MemberList.h (limited to 'resources/qml') diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b26b2e5..84f52766 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -285,7 +285,6 @@ set(SRC_FILES src/dialogs/JoinRoom.cpp src/dialogs/LeaveRoom.cpp src/dialogs/Logout.cpp - src/dialogs/MemberList.cpp src/dialogs/PreviewUploadOverlay.cpp src/dialogs/ReCaptcha.cpp src/dialogs/ReadReceipts.cpp @@ -351,6 +350,7 @@ set(SRC_FILES src/LoginPage.cpp src/MainWindow.cpp src/MatrixClient.cpp + src/MemberList.cpp src/MxcImageProvider.cpp src/Olm.cpp src/RegisterPage.cpp @@ -496,7 +496,6 @@ qt5_wrap_cpp(MOC_HEADERS src/dialogs/JoinRoom.h src/dialogs/LeaveRoom.h src/dialogs/Logout.h - src/dialogs/MemberList.h src/dialogs/PreviewUploadOverlay.h src/dialogs/RawMessage.h src/dialogs/ReCaptcha.h @@ -557,6 +556,7 @@ qt5_wrap_cpp(MOC_HEADERS src/InviteeItem.h src/LoginPage.h src/MainWindow.h + src/MemberList.h src/MxcImageProvider.h src/RegisterPage.h src/SSOHandler.h diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml new file mode 100644 index 00000000..4406c1b0 --- /dev/null +++ b/resources/qml/RoomMembers.qml @@ -0,0 +1,111 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import QtQuick.Window 2.12 +import im.nheko 1.0 + +ApplicationWindow { + id: roomMembersRoot + + property string roomName: Rooms.currentRoom.roomName + property MemberList members + + title: qsTr("Members of ") + roomName + x: MainWindow.x + (MainWindow.width / 2) - (width / 2) + y: MainWindow.y + (MainWindow.height / 2) - (height / 2) + height: 650 + width: 420 + minimumHeight: 420 + + Shortcut { + sequence: StandardKey.Cancel + onActivated: roomMembersRoot.close() + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: 10 + spacing: 10 + + Avatar { + id: roomAvatar + + width: 130 + height: width + displayName: members.roomName + Layout.alignment: Qt.AlignHCenter + url: members.avatarUrl.replace("mxc://", "image://MxcImage/") + onClicked: TimelineManager.timeline.openRoomSettings(members.roomId) + } + + Label { + font.pixelSize: 24 + text: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + roomName + Layout.alignment: Qt.AlignHCenter + } + + ScrollView { + clip: false + palette: colors + padding: 10 + ScrollBar.horizontal.visible: false + Layout.fillHeight: true + Layout.minimumHeight: 200 + Layout.fillWidth: true + + ListView { + id: memberList + + clip: true + spacing: 8 + boundsBehavior: Flickable.StopAtBounds + model: members + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + + delegate: RowLayout { + spacing: 10 + + Avatar { + width: avatarSize + height: avatarSize + userid: model.mxid + url: model.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: model.displayName + onClicked: TimelineManager.timeline.openUserProfile(model.mxid) + } + + ColumnLayout { + spacing: 5 + + Label { + text: model.displayName + color: TimelineManager.userColor(model ? model.mxid : "", colors.window) + font.pointSize: 12 + } + + Label { + text: model.mxid + color: colors.buttonText + font.pointSize: 10 + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + } + } + } + } + } + } + + footer: DialogButtonBox { + standardButtons: DialogButtonBox.Ok + onAccepted: roomMembersRoot.close() + } +} diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml index 58aba0c7..50c2447c 100644 --- a/resources/qml/TopBar.qml +++ b/resources/qml/TopBar.qml @@ -116,7 +116,7 @@ Rectangle { Platform.MenuItem { text: qsTr("Members") - onTriggered: TimelineManager.openMemberListDialog(room.roomId()) + onTriggered: Rooms.currentRoom.openRoomMembers(room.roomId()) } Platform.MenuItem { diff --git a/resources/res.qrc b/resources/res.qrc index e9479e57..da5288c8 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -185,6 +185,7 @@ qml/components/AdaptiveLayout.qml qml/components/AdaptiveLayoutElement.qml qml/components/FlatButton.qml + qml/RoomMembers.qml media/ring.ogg diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index ed337ca4..36bada83 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -21,6 +21,7 @@ #include "LoginPage.h" #include "MainWindow.h" #include "MatrixClient.h" +#include "MemberList.h" #include "RegisterPage.h" #include "TrayIcon.h" #include "UserSettingsPage.h" @@ -36,7 +37,6 @@ #include "dialogs/JoinRoom.h" #include "dialogs/LeaveRoom.h" #include "dialogs/Logout.h" -#include "dialogs/MemberList.h" #include "dialogs/ReadReceipts.h" MainWindow *MainWindow::instance_ = nullptr; @@ -310,14 +310,6 @@ MainWindow::hasActiveUser() settings.contains(prefix + "auth/user_id"); } -void -MainWindow::openMemberListDialog(const QString &room_id) -{ - auto dialog = new dialogs::MemberList(room_id, this); - - showDialog(dialog); -} - void MainWindow::openLeaveRoomDialog(const QString &room_id) { diff --git a/src/MainWindow.h b/src/MainWindow.h index 3571f079..6d62545c 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -65,7 +65,6 @@ public: std::function callback); void openJoinRoomDialog(std::function callback); void openLogoutDialog(); - void openMemberListDialog(const QString &room_id); void openReadReceiptsDialog(const QString &event_id); void hideOverlay(); diff --git a/src/MemberList.cpp b/src/MemberList.cpp new file mode 100644 index 00000000..62488277 --- /dev/null +++ b/src/MemberList.cpp @@ -0,0 +1,91 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "MemberList.h" + +#include "Cache.h" +#include "ChatPage.h" +#include "Config.h" +#include "Logging.h" +#include "Utils.h" +#include "timeline/TimelineViewManager.h" +#include "ui/Avatar.h" + +MemberList::MemberList(const QString &room_id, QWidget *parent) + : QAbstractListModel{parent} + , room_id_{room_id} +{ + try { + info_ = cache::singleRoomInfo(room_id_.toStdString()); + } catch (const lmdb::error &) { + nhlog::db()->warn("failed to retrieve room info from cache: {}", + room_id_.toStdString()); + } + + try { + addUsers(cache::getMembers(room_id_.toStdString())); + } catch (const lmdb::error &e) { + nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what()); + } +} + +void +MemberList::addUsers(const std::vector &members) +{ + beginInsertRows(QModelIndex{}, m_memberList.count(), m_memberList.count() + members.size() - 1); + + for (const auto &member : members) + m_memberList.push_back( + {member, + ChatPage::instance()->timelineManager()->rooms()->currentRoom()->avatarUrl( + member.user_id)}); + + endInsertRows(); +} + +QHash +MemberList::roleNames() const +{ + return {{Mxid, "mxid"}, {DisplayName, "displayName"}, {AvatarUrl, "avatarUrl"}}; +} + +QVariant +MemberList::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= (int)m_memberList.size() || index.row() < 0) + return {}; + + switch (role) { + case Mxid: + return m_memberList[index.row()].first.user_id; + case DisplayName: + return m_memberList[index.row()].first.display_name; + case AvatarUrl: + return m_memberList[index.row()].second; + default: + return {}; + } +} + +bool MemberList::canFetchMore(const QModelIndex &) const +{ + const size_t numMembers = rowCount(); + return (numMembers > 1 && numMembers < info_.member_count); +} + +void +MemberList::fetchMore(const QModelIndex &) +{ + addUsers(cache::getMembers(room_id_.toStdString(), rowCount())); +} diff --git a/src/MemberList.h b/src/MemberList.h new file mode 100644 index 00000000..dbe69f4b --- /dev/null +++ b/src/MemberList.h @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "CacheStructs.h" +#include + +class MemberList : public QAbstractListModel +{ + Q_OBJECT + + Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) + Q_PROPERTY(size_t memberCount READ memberCount NOTIFY memberCountChanged) + Q_PROPERTY(QString avatarUrl READ avatarUrl NOTIFY avatarUrlChanged) + Q_PROPERTY(QString roomId READ roomId NOTIFY roomIdChanged) + +public: + enum Roles + { + Mxid, + DisplayName, + AvatarUrl, + }; + MemberList(const QString &room_id, QWidget *parent = nullptr); + + QHash roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + Q_UNUSED(parent) + return static_cast(m_memberList.size()); + } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + QString roomName() const { return QString::fromStdString(info_.name); } + size_t memberCount() const { return info_.member_count; } + QString avatarUrl() const { return QString::fromStdString(info_.avatar_url); } + QString roomId() const { return room_id_; } + +signals: + void roomNameChanged(); + void memberCountChanged(); + void avatarUrlChanged(); + void roomIdChanged(); + +public slots: + void addUsers(const std::vector &users); + +protected: + bool canFetchMore(const QModelIndex &) const; + void fetchMore(const QModelIndex &); + +private: + QVector> m_memberList; + QString room_id_; + RoomInfo info_; +}; diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp deleted file mode 100644 index 21eb72b0..00000000 --- a/src/dialogs/MemberList.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialogs/MemberList.h" - -#include "Cache.h" -#include "ChatPage.h" -#include "Config.h" -#include "Logging.h" -#include "Utils.h" -#include "ui/Avatar.h" - -using namespace dialogs; - -MemberItem::MemberItem(const RoomMember &member, QWidget *parent) - : QWidget(parent) -{ - topLayout_ = new QHBoxLayout(this); - topLayout_->setMargin(0); - - textLayout_ = new QVBoxLayout; - textLayout_->setMargin(0); - textLayout_->setSpacing(0); - - avatar_ = new Avatar(this, 44); - avatar_->setLetter(utils::firstChar(member.display_name)); - - avatar_->setImage(ChatPage::instance()->currentRoom(), member.user_id); - - QFont nameFont; - nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1); - - userId_ = new QLabel(member.user_id, this); - userName_ = new QLabel(member.display_name, this); - userName_->setFont(nameFont); - - textLayout_->addWidget(userName_); - textLayout_->addWidget(userId_); - - topLayout_->addWidget(avatar_); - topLayout_->addLayout(textLayout_, 1); -} - -void -MemberItem::paintEvent(QPaintEvent *) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - -MemberList::MemberList(const QString &room_id, QWidget *parent) - : QFrame(parent) - , room_id_{room_id} -{ - setAutoFillBackground(true); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); - setWindowModality(Qt::WindowModal); - setAttribute(Qt::WA_DeleteOnClose, true); - - auto layout = new QVBoxLayout(this); - layout->setSpacing(conf::modals::WIDGET_SPACING); - layout->setMargin(conf::modals::WIDGET_MARGIN); - - list_ = new QListWidget; - list_->setFrameStyle(QFrame::NoFrame); - list_->setSelectionMode(QAbstractItemView::NoSelection); - list_->setSpacing(5); - - QFont largeFont; - largeFont.setPointSizeF(largeFont.pointSizeF() * 1.5); - - setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - setMinimumHeight(list_->sizeHint().height() * 2); - setMinimumWidth(std::max(list_->sizeHint().width() + 4 * conf::modals::WIDGET_MARGIN, - QFontMetrics(largeFont).averageCharWidth() * 30 - - 2 * conf::modals::WIDGET_MARGIN)); - - QFont font; - font.setPointSizeF(font.pointSizeF() * conf::modals::LABEL_MEDIUM_SIZE_RATIO); - - topLabel_ = new QLabel(tr("Room members"), this); - topLabel_->setAlignment(Qt::AlignCenter); - topLabel_->setFont(font); - - auto okBtn = new QPushButton(tr("OK"), this); - - auto buttonLayout = new QHBoxLayout(); - buttonLayout->setSpacing(15); - buttonLayout->addStretch(1); - buttonLayout->addWidget(okBtn); - - layout->addWidget(topLabel_); - layout->addWidget(list_); - layout->addLayout(buttonLayout); - - list_->clear(); - - connect(list_->verticalScrollBar(), &QAbstractSlider::valueChanged, this, [this](int pos) { - if (pos != list_->verticalScrollBar()->maximum()) - return; - - const size_t numMembers = list_->count() - 1; - - if (numMembers > 0) - addUsers(cache::getMembers(room_id_.toStdString(), numMembers)); - }); - - try { - addUsers(cache::getMembers(room_id_.toStdString())); - } catch (const lmdb::error &e) { - nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what()); - } - - auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this); - connect(closeShortcut, &QShortcut::activated, this, &MemberList::close); - connect(okBtn, &QPushButton::clicked, this, &MemberList::close); -} - -void -MemberList::addUsers(const std::vector &members) -{ - for (const auto &member : members) { - auto user = new MemberItem(member, this); - auto item = new QListWidgetItem; - - item->setSizeHint(user->minimumSizeHint()); - item->setFlags(Qt::NoItemFlags); - item->setTextAlignment(Qt::AlignCenter); - - list_->insertItem(list_->count() - 1, item); - list_->setItemWidget(item, user); - } -} diff --git a/src/dialogs/MemberList.h b/src/dialogs/MemberList.h deleted file mode 100644 index b822eec8..00000000 --- a/src/dialogs/MemberList.h +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include -#include - -class Avatar; -class QPushButton; -class QHBoxLayout; -class QLabel; -class QVBoxLayout; - -struct RoomMember; - -template -class QSharedPointer; - -namespace dialogs { - -class MemberItem : public QWidget -{ - Q_OBJECT - -public: - MemberItem(const RoomMember &member, QWidget *parent); - -protected: - void paintEvent(QPaintEvent *) override; - -private: - QHBoxLayout *topLayout_; - QVBoxLayout *textLayout_; - - Avatar *avatar_; - - QLabel *userName_; - QLabel *userId_; -}; - -class MemberList : public QFrame -{ - Q_OBJECT -public: - MemberList(const QString &room_id, QWidget *parent = nullptr); - -public slots: - void addUsers(const std::vector &users); - -private: - QString room_id_; - QLabel *topLabel_; - QListWidget *list_; -}; -} // dialogs diff --git a/src/main.cpp b/src/main.cpp index 29e93d49..376fc4f5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -205,6 +205,9 @@ main(int argc, char *argv[]) parser.process(app); + // make sure that size_t properties will work + qRegisterMetaType("size_t"); + app.setWindowIcon(QIcon::fromTheme("nheko", QIcon{":/logos/nheko.png"})); http::init(); diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 7b3f0729..48d69493 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -25,6 +25,7 @@ #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" +#include "MemberList.h" #include "MxcImageProvider.h" #include "Olm.h" #include "TimelineViewManager.h" @@ -1061,9 +1062,16 @@ TimelineModel::openUserProfile(QString userid) } void -TimelineModel::openRoomSettings() +TimelineModel::openRoomMembers() { - RoomSettings *settings = new RoomSettings(roomId(), this); + MemberList *memberList = new MemberList(roomId()); + emit openRoomMembersDialog(memberList); +} + +void +TimelineModel::openRoomSettings(QString room_id) +{ + RoomSettings *settings = new RoomSettings(room_id == QString() ? roomId() : room_id, this); connect(this, &TimelineModel::roomAvatarUrlChanged, settings, &RoomSettings::avatarChanged); openRoomSettingsDialog(settings); } diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 3c80ade8..feb7b5f5 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -17,6 +17,7 @@ #include "CacheStructs.h" #include "EventStore.h" #include "InputBar.h" +#include "MemberList.h" #include "Permissions.h" #include "ui/RoomSettings.h" #include "ui/UserProfile.h" @@ -235,7 +236,8 @@ public: Q_INVOKABLE void forwardMessage(QString eventId, QString roomId); Q_INVOKABLE void viewDecryptedRawMessage(QString id) const; Q_INVOKABLE void openUserProfile(QString userid); - Q_INVOKABLE void openRoomSettings(); + Q_INVOKABLE void openRoomMembers(); + Q_INVOKABLE void openRoomSettings(QString room_id = QString()); Q_INVOKABLE void editAction(QString id); Q_INVOKABLE void replyAction(QString id); Q_INVOKABLE void readReceiptsAction(QString id) const; @@ -352,6 +354,7 @@ signals: void lastMessageChanged(); void notificationsChanged(); + void openRoomMembersDialog(MemberList *members); void openRoomSettingsDialog(RoomSettings *settings); void newMessageToSend(mtx::events::collections::TimelineEvents event); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 3e69f92b..011ff61c 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -174,6 +174,8 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par 0, "UserProfileModel", "UserProfile needs to be instantiated on the C++ side"); + qmlRegisterUncreatableType( + "im.nheko", 1, 0, "MemberList", "MemberList needs to be instantiated on the C++ side"); qmlRegisterUncreatableType( "im.nheko", 1, @@ -428,11 +430,6 @@ TimelineViewManager::openInviteUsersDialog() [this](const QStringList &invitees) { emit inviteUsers(invitees); }); } void -TimelineViewManager::openMemberListDialog(QString roomid) const -{ - MainWindow::instance()->openMemberListDialog(roomid); -} -void TimelineViewManager::openLeaveRoomDialog(QString roomid) const { MainWindow::instance()->openLeaveRoomDialog(roomid); diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 15b4f523..39d0d31c 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -66,7 +66,6 @@ public: Q_INVOKABLE void focusMessageInput(); Q_INVOKABLE void openInviteUsersDialog(); - Q_INVOKABLE void openMemberListDialog(QString roomid) const; Q_INVOKABLE void openLeaveRoomDialog(QString roomid) const; Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow); -- cgit 1.4.1 From 6c57fa6c5b491e981958e417458edac40e9000b4 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Thu, 10 Jun 2021 20:11:49 -0400 Subject: QML the invite dialog This also adds a property `roomId` to TimelineModel. --- CMakeLists.txt | 4 - resources/qml/InviteDialog.qml | 112 +++++++++++++++++++++++++ resources/qml/TopBar.qml | 14 +++- resources/qml/types/Invitee.qml | 5 ++ resources/res.qrc | 13 +-- src/ChatPage.cpp | 28 +++++++ src/InviteeItem.cpp | 28 ------- src/InviteeItem.h | 31 ------- src/MainWindow.cpp | 13 --- src/dialogs/InviteUsers.cpp | 158 ----------------------------------- src/dialogs/InviteUsers.h | 45 ---------- src/timeline/TimelineModel.h | 1 + src/timeline/TimelineViewManager.cpp | 51 +++++++++++ src/timeline/TimelineViewManager.h | 5 +- 14 files changed, 215 insertions(+), 293 deletions(-) create mode 100644 resources/qml/InviteDialog.qml create mode 100644 resources/qml/types/Invitee.qml delete mode 100644 src/InviteeItem.cpp delete mode 100644 src/InviteeItem.h delete mode 100644 src/dialogs/InviteUsers.cpp delete mode 100644 src/dialogs/InviteUsers.h (limited to 'resources/qml') diff --git a/CMakeLists.txt b/CMakeLists.txt index 84f52766..56592950 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,7 +281,6 @@ set(SRC_FILES src/dialogs/CreateRoom.cpp src/dialogs/FallbackAuth.cpp src/dialogs/ImageOverlay.cpp - src/dialogs/InviteUsers.cpp src/dialogs/JoinRoom.cpp src/dialogs/LeaveRoom.cpp src/dialogs/Logout.cpp @@ -345,7 +344,6 @@ set(SRC_FILES src/CompletionProxyModel.cpp src/DeviceVerificationFlow.cpp src/EventAccessors.cpp - src/InviteeItem.cpp src/Logging.cpp src/LoginPage.cpp src/MainWindow.cpp @@ -492,7 +490,6 @@ qt5_wrap_cpp(MOC_HEADERS src/dialogs/CreateRoom.h src/dialogs/FallbackAuth.h src/dialogs/ImageOverlay.h - src/dialogs/InviteUsers.h src/dialogs/JoinRoom.h src/dialogs/LeaveRoom.h src/dialogs/Logout.h @@ -553,7 +550,6 @@ qt5_wrap_cpp(MOC_HEADERS src/Clipboard.h src/CompletionProxyModel.h src/DeviceVerificationFlow.h - src/InviteeItem.h src/LoginPage.h src/MainWindow.h src/MemberList.h diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml new file mode 100644 index 00000000..5d3a8f1e --- /dev/null +++ b/resources/qml/InviteDialog.qml @@ -0,0 +1,112 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import im.nheko 1.0 +import "./types" + +ApplicationWindow { + id: inviteDialogRoot + + property string roomId + property string roomName + property list invitees + + function addInvite() { + if (inviteeEntry.text.match("@.+?:.{3,}")) + { + invitees.push(inviteeComponent.createObject( + inviteDialogRoot, { + "invitee": inviteeEntry.text + })); + inviteeEntry.clear(); + } + } + + function accept() { + if (inviteeEntry.text !== "") + addInvite(); + + var inviteeStringList = ["temp"]; // the "temp" element exists to declare this as a string array + for (var i = 0; i < invitees.length; ++i) + inviteeStringList.push(invitees[i].invitee); + inviteeStringList.shift(); // remove the first item + + TimelineManager.inviteUsers(inviteDialogRoot.roomId, inviteeStringList); + } + + title: qsTr("Invite users to ") + roomName + x: MainWindow.x + (MainWindow.width / 2) - (width / 2) + y: MainWindow.y + (MainWindow.height / 2) - (height / 2) + height: 380 + width: 340 + + Component { + id: inviteeComponent + + Invitee {} + } + + // TODO: make this work in the TextField + Shortcut { + sequence: "Ctrl+Enter" + onActivated: inviteDialogRoot.accept() + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: 10 + spacing: 10 + + Label { + text: qsTr("User ID to invite") + Layout.fillWidth: true + } + + RowLayout { + spacing: 10 + + TextField { + id: inviteeEntry + + placeholderText: qsTr("@joe:matrix.org", "Example user id. The name 'joe' can be localized however you want.") + Layout.fillWidth: true + onAccepted: if (text !== "") addInvite() + } + + Button { + text: qsTr("Invite") + onClicked: if (inviteeEntry.text !== "") addInvite() + } + } + + ListView { + id: inviteesList + + Layout.fillWidth: true + Layout.fillHeight: true + model: invitees + delegate: Label { + text: model.invitee + } + } + } + + footer: DialogButtonBox { + id: buttons + + Button { + text: qsTr("Invite") + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + onClicked: { + inviteDialogRoot.accept(); + inviteDialogRoot.close(); + } + } + + Button { + text: qsTr("Cancel") + DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole + onClicked: inviteDialogRoot.close(); + } + } +} diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml index 50c2447c..72dbe604 100644 --- a/resources/qml/TopBar.qml +++ b/resources/qml/TopBar.qml @@ -21,6 +21,12 @@ Rectangle { z: 3 color: Nheko.colors.window + Component { + id: inviteDialog + + InviteDialog {} + } + TapHandler { onSingleTapped: { if (room) @@ -111,7 +117,13 @@ Rectangle { Platform.MenuItem { visible: room ? room.permissions.canInvite() : false text: qsTr("Invite users") - onTriggered: TimelineManager.openInviteUsersDialog() + onTriggered: { + var dialog = inviteDialog.createObject(topBar, { + "roomId": room.roomId, + "roomName": room.roomName + }); + dialog.show(); + } } Platform.MenuItem { diff --git a/resources/qml/types/Invitee.qml b/resources/qml/types/Invitee.qml new file mode 100644 index 00000000..fbc0b781 --- /dev/null +++ b/resources/qml/types/Invitee.qml @@ -0,0 +1,5 @@ +import QtQuick 2.12 + +Item { + property string invitee +} diff --git a/resources/res.qrc b/resources/res.qrc index da5288c8..ad7b6665 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -9,7 +9,6 @@ icons/ui/do-not-disturb-rounded-sign@2x.png icons/ui/round-remove-button.png icons/ui/round-remove-button@2x.png - icons/ui/double-tick-indicator.png icons/ui/double-tick-indicator@2x.png icons/ui/lock.png @@ -55,22 +54,17 @@ icons/ui/pause-symbol@2x.png icons/ui/remove-symbol.png icons/ui/remove-symbol@2x.png - icons/ui/world.png icons/ui/world@2x.png - icons/ui/tag.png icons/ui/tag@2x.png icons/ui/star.png icons/ui/star@2x.png icons/ui/lowprio.png icons/ui/lowprio@2x.png - icons/ui/edit.png icons/ui/edit@2x.png - icons/ui/mail-reply.png - icons/ui/place-call.png icons/ui/end-call.png icons/ui/microphone-mute.png @@ -78,7 +72,6 @@ icons/ui/screen-share.png icons/ui/toggle-camera-view.png icons/ui/video-call.png - icons/emoji-categories/people.png icons/emoji-categories/people@2x.png icons/emoji-categories/nature.png @@ -99,16 +92,12 @@ nheko.png nheko.svg - splash.png splash@2x.png - register.png register@2x.png - login.png login@2x.png - nheko-512.png nheko-256.png nheko-128.png @@ -186,6 +175,8 @@ qml/components/AdaptiveLayoutElement.qml qml/components/FlatButton.qml qml/RoomMembers.qml + qml/InviteDialog.qml + qml/types/Invitee.qml media/ring.ogg diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 10a91557..f6ea4539 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -140,6 +140,34 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) } }); + connect( + view_manager_, &TimelineViewManager::showRoomList, splitter, &Splitter::showFullRoomList); + connect( + view_manager_, + &TimelineViewManager::inviteUsers, + this, + [this](QString roomId, QStringList users) { + for (int ii = 0; ii < users.size(); ++ii) { + QTimer::singleShot(ii * 500, this, [this, roomId, ii, users]() { + const auto user = users.at(ii); + + http::client()->invite_user( + roomId.toStdString(), + user.toStdString(), + [this, user](const mtx::responses::RoomInvite &, + mtx::http::RequestErr err) { + if (err) { + emit showNotification( + tr("Failed to invite user: %1").arg(user)); + return; + } + + emit showNotification(tr("Invited user: %1").arg(user)); + }); + }); + } + }); + connect(this, &ChatPage::leftRoom, this, &ChatPage::removeRoom); connect(this, &ChatPage::newRoom, this, &ChatPage::changeRoom, Qt::QueuedConnection); connect(this, &ChatPage::notificationsRetrieved, this, &ChatPage::sendNotifications); diff --git a/src/InviteeItem.cpp b/src/InviteeItem.cpp deleted file mode 100644 index 27f02560..00000000 --- a/src/InviteeItem.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include -#include -#include - -#include "InviteeItem.h" - -constexpr int SidePadding = 10; - -InviteeItem::InviteeItem(mtx::identifiers::User user, QWidget *parent) - : QWidget{parent} - , user_{QString::fromStdString(user.to_string())} -{ - auto topLayout_ = new QHBoxLayout(this); - topLayout_->setSpacing(0); - topLayout_->setContentsMargins(SidePadding, 0, 3 * SidePadding, 0); - - name_ = new QLabel(user_, this); - removeUserBtn_ = new QPushButton(tr("Remove"), this); - - topLayout_->addWidget(name_); - topLayout_->addWidget(removeUserBtn_, 0, Qt::AlignRight); - - connect(removeUserBtn_, &QPushButton::clicked, this, &InviteeItem::removeItem); -} diff --git a/src/InviteeItem.h b/src/InviteeItem.h deleted file mode 100644 index 014541ea..00000000 --- a/src/InviteeItem.h +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include - -#include - -class QPushButton; -class QLabel; - -class InviteeItem : public QWidget -{ - Q_OBJECT - -public: - InviteeItem(mtx::identifiers::User user, QWidget *parent = nullptr); - - QString userID() { return user_; } - -signals: - void removeItem(); - -private: - QString user_; - - QLabel *name_; - QPushButton *removeUserBtn_; -}; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 36bada83..c0486d01 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -33,7 +33,6 @@ #include "ui/SnackBar.h" #include "dialogs/CreateRoom.h" -#include "dialogs/InviteUsers.h" #include "dialogs/JoinRoom.h" #include "dialogs/LeaveRoom.h" #include "dialogs/Logout.h" @@ -333,18 +332,6 @@ MainWindow::showOverlayProgressBar() showSolidOverlayModal(spinner_); } -void -MainWindow::openInviteUsersDialog(std::function callback) -{ - auto dialog = new dialogs::InviteUsers(this); - connect(dialog, &dialogs::InviteUsers::sendInvites, this, [callback](QStringList invitees) { - if (!invitees.isEmpty()) - callback(invitees); - }); - - showDialog(dialog); -} - void MainWindow::openJoinRoomDialog(std::function callback) { diff --git a/src/dialogs/InviteUsers.cpp b/src/dialogs/InviteUsers.cpp deleted file mode 100644 index 9dd6085f..00000000 --- a/src/dialogs/InviteUsers.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialogs/InviteUsers.h" - -#include "Config.h" -#include "InviteeItem.h" -#include "ui/TextField.h" - -#include - -using namespace dialogs; - -InviteUsers::InviteUsers(QWidget *parent) - : QFrame(parent) -{ - setAutoFillBackground(true); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); - setWindowModality(Qt::WindowModal); - setAttribute(Qt::WA_DeleteOnClose, true); - - setMinimumWidth(conf::window::minModalWidth); - setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - - auto layout = new QVBoxLayout(this); - layout->setSpacing(conf::modals::WIDGET_SPACING); - layout->setMargin(conf::modals::WIDGET_MARGIN); - - auto buttonLayout = new QHBoxLayout(); - buttonLayout->setSpacing(0); - buttonLayout->setMargin(0); - - confirmBtn_ = new QPushButton("Invite", this); - confirmBtn_->setDefault(true); - cancelBtn_ = new QPushButton(tr("Cancel"), this); - - buttonLayout->addStretch(1); - buttonLayout->setSpacing(15); - buttonLayout->addWidget(cancelBtn_); - buttonLayout->addWidget(confirmBtn_); - - inviteeInput_ = new TextField(this); - inviteeInput_->setLabel(tr("User ID to invite")); - - inviteeList_ = new QListWidget; - inviteeList_->setFrameStyle(QFrame::NoFrame); - inviteeList_->setSelectionMode(QAbstractItemView::NoSelection); - inviteeList_->setAttribute(Qt::WA_MacShowFocusRect, 0); - inviteeList_->setSpacing(5); - - errorLabel_ = new QLabel(this); - errorLabel_->setAlignment(Qt::AlignCenter); - - layout->addWidget(inviteeInput_); - layout->addWidget(errorLabel_); - layout->addWidget(inviteeList_); - layout->addLayout(buttonLayout); - - connect(inviteeInput_, &TextField::returnPressed, this, &InviteUsers::addUser); - connect(confirmBtn_, &QPushButton::clicked, [this]() { - if (!inviteeInput_->text().trimmed().isEmpty()) { - addUser(); - } - - emit sendInvites(invitedUsers()); - - inviteeInput_->clear(); - inviteeList_->clear(); - errorLabel_->hide(); - - emit close(); - }); - - connect(cancelBtn_, &QPushButton::clicked, [this]() { - inviteeInput_->clear(); - inviteeList_->clear(); - errorLabel_->hide(); - - emit close(); - }); -} - -void -InviteUsers::addUser() -{ - auto user_id = inviteeInput_->text(); - - try { - namespace ids = mtx::identifiers; - auto user = ids::parse(user_id.toStdString()); - - auto item = new QListWidgetItem(inviteeList_); - auto invitee = new InviteeItem(user, this); - - item->setSizeHint(invitee->minimumSizeHint()); - item->setFlags(Qt::NoItemFlags); - item->setTextAlignment(Qt::AlignCenter); - - inviteeList_->setItemWidget(item, invitee); - - connect(invitee, &InviteeItem::removeItem, this, [this, item]() { - emit removeInvitee(item); - }); - - errorLabel_->hide(); - inviteeInput_->clear(); - } catch (std::exception &e) { - errorLabel_->setText(e.what()); - errorLabel_->show(); - } -} - -void -InviteUsers::removeInvitee(QListWidgetItem *item) -{ - int row = inviteeList_->row(item); - auto widget = inviteeList_->takeItem(row); - - inviteeList_->removeItemWidget(widget); -} - -QStringList -InviteUsers::invitedUsers() const -{ - QStringList users; - - for (int ii = 0; ii < inviteeList_->count(); ++ii) { - auto item = inviteeList_->item(ii); - auto widget = inviteeList_->itemWidget(item); - auto invitee = qobject_cast(widget); - - if (invitee) - users << invitee->userID(); - else - qDebug() << "Cast InviteeItem failed"; - } - - return users; -} - -void -InviteUsers::showEvent(QShowEvent *event) -{ - inviteeInput_->setFocus(); - - QFrame::showEvent(event); -} diff --git a/src/dialogs/InviteUsers.h b/src/dialogs/InviteUsers.h deleted file mode 100644 index e40183c1..00000000 --- a/src/dialogs/InviteUsers.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include -#include - -class QPushButton; -class QLabel; -class TextField; -class QListWidget; -class QListWidgetItem; - -namespace dialogs { - -class InviteUsers : public QFrame -{ - Q_OBJECT -public: - explicit InviteUsers(QWidget *parent = nullptr); - -protected: - void showEvent(QShowEvent *event) override; - -signals: - void sendInvites(QStringList invitees); - -private slots: - void removeInvitee(QListWidgetItem *item); - -private: - void addUser(); - QStringList invitedUsers() const; - - QPushButton *confirmBtn_; - QPushButton *cancelBtn_; - - TextField *inviteeInput_; - QLabel *errorLabel_; - - QListWidget *inviteeList_; -}; -} // dialogs diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index feb7b5f5..5730fbab 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -159,6 +159,7 @@ class TimelineModel : public QAbstractListModel Q_PROPERTY(QString edit READ edit WRITE setEdit NOTIFY editChanged RESET resetEdit) Q_PROPERTY( bool paginationInProgress READ paginationInProgress NOTIFY paginationInProgressChanged) + Q_PROPERTY(QString roomId READ roomId CONSTANT) Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 011ff61c..43b9a646 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -429,6 +429,57 @@ TimelineViewManager::openInviteUsersDialog() MainWindow::instance()->openInviteUsersDialog( [this](const QStringList &invitees) { emit inviteUsers(invitees); }); } + +void +TimelineViewManager::openLink(QString link) const +{ + QUrl url(link); + if (url.scheme() == "https" && url.host() == "matrix.to") { + // handle matrix.to links internally + QString p = url.fragment(QUrl::FullyEncoded); + if (p.startsWith("/")) + p.remove(0, 1); + + auto temp = p.split("?"); + QString query; + if (temp.size() >= 2) + query = QUrl::fromPercentEncoding(temp.takeAt(1).toUtf8()); + + temp = temp.first().split("/"); + auto identifier = QUrl::fromPercentEncoding(temp.takeFirst().toUtf8()); + QString eventId = QUrl::fromPercentEncoding(temp.join('/').toUtf8()); + if (!identifier.isEmpty()) { + if (identifier.startsWith("@")) { + QByteArray uri = + "matrix:u/" + QUrl::toPercentEncoding(identifier.remove(0, 1)); + if (!query.isEmpty()) + uri.append("?" + query.toUtf8()); + ChatPage::instance()->handleMatrixUri(QUrl::fromEncoded(uri)); + } else if (identifier.startsWith("#")) { + QByteArray uri = + "matrix:r/" + QUrl::toPercentEncoding(identifier.remove(0, 1)); + if (!eventId.isEmpty()) + uri.append("/e/" + + QUrl::toPercentEncoding(eventId.remove(0, 1))); + if (!query.isEmpty()) + uri.append("?" + query.toUtf8()); + ChatPage::instance()->handleMatrixUri(QUrl::fromEncoded(uri)); + } else if (identifier.startsWith("!")) { + QByteArray uri = "matrix:roomid/" + + QUrl::toPercentEncoding(identifier.remove(0, 1)); + if (!eventId.isEmpty()) + uri.append("/e/" + + QUrl::toPercentEncoding(eventId.remove(0, 1))); + if (!query.isEmpty()) + uri.append("?" + query.toUtf8()); + ChatPage::instance()->handleMatrixUri(QUrl::fromEncoded(uri)); + } + } + } else { + QDesktopServices::openUrl(url); + } +} + void TimelineViewManager::openLeaveRoomDialog(QString roomid) const { diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 39d0d31c..945ba2d5 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -65,7 +65,6 @@ public: Q_INVOKABLE QString userStatus(QString id) const; Q_INVOKABLE void focusMessageInput(); - Q_INVOKABLE void openInviteUsersDialog(); Q_INVOKABLE void openLeaveRoomDialog(QString roomid) const; Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow); @@ -80,7 +79,9 @@ signals: void replyingEventChanged(QString replyingEvent); void replyClosed(); void newDeviceVerificationRequest(DeviceVerificationFlow *flow); - void inviteUsers(QStringList users); + void inviteUsers(QString roomId, QStringList users); + void showRoomList(); + void narrowViewChanged(); void focusChanged(); void focusInput(); void openImageOverlayInternalCb(QString eventId, QImage img); -- cgit 1.4.1 From e1acf5d324615e8c61c469883a6a42933c8f76bc Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Thu, 10 Jun 2021 20:13:12 -0400 Subject: make lint --- CMakeLists.txt | 2 + resources/qml/InviteDialog.qml | 78 +++++++++++++++++++++++------------- resources/qml/RoomMembers.qml | 9 +++++ resources/qml/Root.qml | 38 ++++++++++++++++++ resources/qml/TimelineView.qml | 1 - resources/qml/TopBar.qml | 14 +------ resources/qml/types/Invitee.qml | 5 --- resources/res.qrc | 1 - src/ChatPage.cpp | 49 +++++++++++----------- src/InviteesModel.cpp | 77 +++++++++++++++++++++++++++++++++++ src/InviteesModel.h | 56 ++++++++++++++++++++++++++ src/MemberList.cpp | 10 +++-- src/timeline/TimelineModel.cpp | 10 +++++ src/timeline/TimelineModel.h | 3 ++ src/timeline/TimelineViewManager.cpp | 70 +++++++------------------------- 15 files changed, 290 insertions(+), 133 deletions(-) delete mode 100644 resources/qml/types/Invitee.qml create mode 100644 src/InviteesModel.cpp create mode 100644 src/InviteesModel.h (limited to 'resources/qml') diff --git a/CMakeLists.txt b/CMakeLists.txt index 56592950..f77d9978 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -344,6 +344,7 @@ set(SRC_FILES src/CompletionProxyModel.cpp src/DeviceVerificationFlow.cpp src/EventAccessors.cpp + src/InviteesModel.cpp src/Logging.cpp src/LoginPage.cpp src/MainWindow.cpp @@ -550,6 +551,7 @@ qt5_wrap_cpp(MOC_HEADERS src/Clipboard.h src/CompletionProxyModel.h src/DeviceVerificationFlow.h + src/InviteesModel.h src/LoginPage.h src/MainWindow.h src/MemberList.h diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 5d3a8f1e..d5cc4c6d 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -2,50 +2,28 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import im.nheko 1.0 -import "./types" ApplicationWindow { id: inviteDialogRoot property string roomId property string roomName - property list invitees + property InviteesModel invitees function addInvite() { if (inviteeEntry.text.match("@.+?:.{3,}")) { - invitees.push(inviteeComponent.createObject( - inviteDialogRoot, { - "invitee": inviteeEntry.text - })); + invitees.addUser(inviteeEntry.text); inviteeEntry.clear(); } } - function accept() { - if (inviteeEntry.text !== "") - addInvite(); - - var inviteeStringList = ["temp"]; // the "temp" element exists to declare this as a string array - for (var i = 0; i < invitees.length; ++i) - inviteeStringList.push(invitees[i].invitee); - inviteeStringList.shift(); // remove the first item - - TimelineManager.inviteUsers(inviteDialogRoot.roomId, inviteeStringList); - } - title: qsTr("Invite users to ") + roomName x: MainWindow.x + (MainWindow.width / 2) - (width / 2) y: MainWindow.y + (MainWindow.height / 2) - (height / 2) height: 380 width: 340 - Component { - id: inviteeComponent - - Invitee {} - } - // TODO: make this work in the TextField Shortcut { sequence: "Ctrl+Enter" @@ -74,7 +52,7 @@ ApplicationWindow { } Button { - text: qsTr("Invite") + text: qsTr("Add") onClicked: if (inviteeEntry.text !== "") addInvite() } } @@ -85,9 +63,53 @@ ApplicationWindow { Layout.fillWidth: true Layout.fillHeight: true model: invitees - delegate: Label { - text: model.invitee + + delegate: RowLayout { + spacing: 10 + + Avatar { + width: avatarSize + height: avatarSize + userid: model.mxid + url: model.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: model.displayName + onClicked: TimelineManager.timeline.openUserProfile(model.mxid) + } + + ColumnLayout { + spacing: 5 + + Label { + text: model.displayName + color: TimelineManager.userColor(model ? model.mxid : "", colors.window) + font.pointSize: 12 + } + + Label { + text: model.mxid + color: colors.buttonText + font.pointSize: 10 + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + } + } } +// delegate: RowLayout { +// spacing: 10 + +// Avatar { +// url: model.avatarUrl +// width: 20 +// height: width +// } + +// Label { +// text: model.displayName + " (" + model.mxid + ")" +// } +// } } } @@ -98,7 +120,7 @@ ApplicationWindow { text: qsTr("Invite") DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole onClicked: { - inviteDialogRoot.accept(); + invitees.accept(); inviteDialogRoot.close(); } } diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 4406c1b0..d31fe319 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -44,6 +44,15 @@ ApplicationWindow { Layout.alignment: Qt.AlignHCenter } + ImageButton { + Layout.alignment: Qt.AlignHCenter + image: ":/icons/icons/ui/add-square-button.png" + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Invite more people") + onClicked: TimelineManager.timeline.openInviteUsersDialog() + } + ScrollView { clip: false palette: colors diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index 5316e20d..ecd0bdb7 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -89,6 +89,12 @@ Page { } } + Component { + id: inviteDialog + + InviteDialog { + } + } Connections { target: TimelineManager @@ -116,6 +122,38 @@ Page { } } + Connections { + target: TimelineManager.timeline + onOpenRoomMembersDialog: { + var membersDialog = roomMembersComponent.createObject(timelineRoot, { + "members": members, + "roomName": TimelineManager.timeline.roomName + }); + membersDialog.show(); + } + } + + Connections { + target: TimelineManager.timeline + onOpenRoomSettingsDialog: { + var roomSettings = roomSettingsComponent.createObject(timelineRoot, { + "roomSettings": settings + }); + roomSettings.show(); + } + } + + Connections { + target: TimelineManager.timeline + onOpenInviteUsersDialog: { + var dialog = inviteDialog.createObject(timelineRoot, { + "roomId": TimelineManager.timeline.roomId, + "roomName": TimelineManager.timeline.roomName + }); + dialog.show(); + } + } + ChatPage { anchors.fill: parent } diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 148a5817..d515b9b4 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -157,7 +157,6 @@ Item { Layout.alignment: Qt.AlignHCenter enabled: false } - MatrixText { text: parent.roomName font.pixelSize: 24 diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml index 72dbe604..6cf747c5 100644 --- a/resources/qml/TopBar.qml +++ b/resources/qml/TopBar.qml @@ -21,12 +21,6 @@ Rectangle { z: 3 color: Nheko.colors.window - Component { - id: inviteDialog - - InviteDialog {} - } - TapHandler { onSingleTapped: { if (room) @@ -117,13 +111,7 @@ Rectangle { Platform.MenuItem { visible: room ? room.permissions.canInvite() : false text: qsTr("Invite users") - onTriggered: { - var dialog = inviteDialog.createObject(topBar, { - "roomId": room.roomId, - "roomName": room.roomName - }); - dialog.show(); - } + onTriggered: TimelineManager.timeline.openInviteUsers() } Platform.MenuItem { diff --git a/resources/qml/types/Invitee.qml b/resources/qml/types/Invitee.qml deleted file mode 100644 index fbc0b781..00000000 --- a/resources/qml/types/Invitee.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.12 - -Item { - property string invitee -} diff --git a/resources/res.qrc b/resources/res.qrc index ad7b6665..f8c040e4 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -176,7 +176,6 @@ qml/components/FlatButton.qml qml/RoomMembers.qml qml/InviteDialog.qml - qml/types/Invitee.qml media/ring.ogg diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index f6ea4539..8b4cfeef 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -116,32 +116,31 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(this, &ChatPage::loggedOut, this, &ChatPage::logout); - connect(view_manager_, &TimelineViewManager::inviteUsers, this, [this](QStringList users) { - const auto room_id = currentRoom().toStdString(); - - for (int ii = 0; ii < users.size(); ++ii) { - QTimer::singleShot(ii * 500, this, [this, room_id, ii, users]() { - const auto user = users.at(ii); - - http::client()->invite_user( - room_id, - user.toStdString(), - [this, user](const mtx::responses::RoomInvite &, - mtx::http::RequestErr err) { - if (err) { - emit showNotification( - tr("Failed to invite user: %1").arg(user)); - return; - } + // TODO: once this signal is moved, reenable this +// connect(view_manager_, &TimelineViewManager::inviteUsers, this, [this](QStringList users) { +// const auto room_id = currentRoom().toStdString(); + +// for (int ii = 0; ii < users.size(); ++ii) { +// QTimer::singleShot(ii * 500, this, [this, room_id, ii, users]() { +// const auto user = users.at(ii); + +// http::client()->invite_user( +// room_id, +// user.toStdString(), +// [this, user](const mtx::responses::RoomInvite &, +// mtx::http::RequestErr err) { +// if (err) { +// emit showNotification( +// tr("Failed to invite user: %1").arg(user)); +// return; +// } + +// emit showNotification(tr("Invited user: %1").arg(user)); +// }); +// }); +// } +// }); - emit showNotification(tr("Invited user: %1").arg(user)); - }); - }); - } - }); - - connect( - view_manager_, &TimelineViewManager::showRoomList, splitter, &Splitter::showFullRoomList); connect( view_manager_, &TimelineViewManager::inviteUsers, diff --git a/src/InviteesModel.cpp b/src/InviteesModel.cpp new file mode 100644 index 00000000..849c5281 --- /dev/null +++ b/src/InviteesModel.cpp @@ -0,0 +1,77 @@ +#include "InviteesModel.h" + +#include "Cache.h" +#include "Logging.h" +#include "MatrixClient.h" +#include "mtx/responses/profile.hpp" + +InviteesModel::InviteesModel(QObject *parent) + : QAbstractListModel{parent} +{} + +void +InviteesModel::addUser(QString mxid) +{ + beginInsertRows(QModelIndex(), invitees_.count(), invitees_.count()); + + auto invitee = new Invitee{mxid, this}; + connect(invitee, &Invitee::userInfoLoaded, this, [this]() { + emit dataChanged(QModelIndex{}, QModelIndex{}); + }); + + invitees_.push_back(invitee); + + endInsertRows(); +} + +QHash +InviteesModel::roleNames() const +{ + return {{Mxid, "mxid"}, {DisplayName, "displayName"}, {AvatarUrl, "avatarUrl"}}; +} + +QVariant +InviteesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= (int)invitees_.size() || index.row() < 0) + return {}; + + switch (role) { + case Mxid: + return invitees_[index.row()]->mxid_; + case DisplayName: + return invitees_[index.row()]->displayName_; + case AvatarUrl: + return invitees_[index.row()]->avatarUrl_; + default: + return {}; + } +} + +QStringList +InviteesModel::mxids() +{ + QStringList mxidList; + for (int i = 0; i < invitees_.length(); ++i) + mxidList.push_back(invitees_[i]->mxid_); + return mxidList; +} + +Invitee::Invitee(const QString &mxid, QObject *parent) + : QObject{parent} + , mxid_{mxid} +{ + http::client()->get_profile( + mxid_.toStdString(), + [this](const mtx::responses::Profile &res, mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to retrieve own profile info"); + return; + } + + displayName_ = QString::fromStdString(res.display_name); + avatarUrl_ = QString::fromStdString(res.avatar_url); + + emit userInfoLoaded(); + }); +} diff --git a/src/InviteesModel.h b/src/InviteesModel.h new file mode 100644 index 00000000..4bcc4e9d --- /dev/null +++ b/src/InviteesModel.h @@ -0,0 +1,56 @@ +#ifndef INVITEESMODEL_H +#define INVITEESMODEL_H + +#include +#include + +class Invitee : public QObject +{ + Q_OBJECT + +public: + Invitee(const QString &mxid, QObject *parent = nullptr); + +signals: + void userInfoLoaded(); + +private: + const QString mxid_; + QString displayName_; + QString avatarUrl_; + + friend class InviteesModel; +}; + +class InviteesModel : public QAbstractListModel +{ + Q_OBJECT + +public: + enum Roles + { + Mxid, + DisplayName, + AvatarUrl, + }; + + InviteesModel(QObject *parent = nullptr); + + Q_INVOKABLE void addUser(QString mxid); + + QHash roleNames() const override; + int rowCount(const QModelIndex & = QModelIndex()) const override + { + return (int)invitees_.size(); + } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QStringList mxids(); + +signals: + void accept(); + +private: + QVector invitees_; +}; + +#endif // INVITEESMODEL_H diff --git a/src/MemberList.cpp b/src/MemberList.cpp index 62488277..2a9c3fbc 100644 --- a/src/MemberList.cpp +++ b/src/MemberList.cpp @@ -43,7 +43,8 @@ MemberList::MemberList(const QString &room_id, QWidget *parent) void MemberList::addUsers(const std::vector &members) { - beginInsertRows(QModelIndex{}, m_memberList.count(), m_memberList.count() + members.size() - 1); + beginInsertRows( + QModelIndex{}, m_memberList.count(), m_memberList.count() + members.size() - 1); for (const auto &member : members) m_memberList.push_back( @@ -78,10 +79,11 @@ MemberList::data(const QModelIndex &index, int role) const } } -bool MemberList::canFetchMore(const QModelIndex &) const +bool +MemberList::canFetchMore(const QModelIndex &) const { - const size_t numMembers = rowCount(); - return (numMembers > 1 && numMembers < info_.member_count); + const size_t numMembers = rowCount(); + return (numMembers > 1 && numMembers < info_.member_count); } void diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 48d69493..2127801c 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -1076,6 +1076,16 @@ TimelineModel::openRoomSettings(QString room_id) openRoomSettingsDialog(settings); } +void +TimelineModel::openInviteUsers(QString room_id) +{ + InviteesModel *model = new InviteesModel{this}; + connect(model, &InviteesModel::accept, this, [this, model, room_id]() { + manager_->inviteUsers(room_id, model->mxids()); + }); + openInviteUsersDialog(model); +} + void TimelineModel::replyAction(QString id) { diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 5730fbab..e5189e61 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -17,6 +17,7 @@ #include "CacheStructs.h" #include "EventStore.h" #include "InputBar.h" +#include "InviteesModel.h" #include "MemberList.h" #include "Permissions.h" #include "ui/RoomSettings.h" @@ -239,6 +240,7 @@ public: Q_INVOKABLE void openUserProfile(QString userid); Q_INVOKABLE void openRoomMembers(); Q_INVOKABLE void openRoomSettings(QString room_id = QString()); + Q_INVOKABLE void openInviteUsers(QString room_id = QString()); Q_INVOKABLE void editAction(QString id); Q_INVOKABLE void replyAction(QString id); Q_INVOKABLE void readReceiptsAction(QString id) const; @@ -357,6 +359,7 @@ signals: void openRoomMembersDialog(MemberList *members); void openRoomSettingsDialog(RoomSettings *settings); + void openInviteUsersDialog(InviteesModel *invitees); void newMessageToSend(mtx::events::collections::TimelineEvents event); void addPendingMessageToStore(mtx::events::collections::TimelineEvents event); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 43b9a646..08b88efd 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -20,6 +20,7 @@ #include "DeviceVerificationFlow.h" #include "EventAccessors.h" #include "ImagePackModel.h" +#include "InviteesModel.h" #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" @@ -184,6 +185,12 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "Room Settings needs to be instantiated on the C++ side"); qmlRegisterUncreatableType( "im.nheko", 1, 0, "Room", "Room needs to be instantiated on the C++ side"); + qmlRegisterUncreatableType( + "im.nheko", + 1, + 0, + "InviteesModel", + "InviteesModel needs to be instantiated on the C++ side"); static auto self = this; qmlRegisterSingletonType( @@ -423,62 +430,13 @@ TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img) }); } -void -TimelineViewManager::openInviteUsersDialog() -{ - MainWindow::instance()->openInviteUsersDialog( - [this](const QStringList &invitees) { emit inviteUsers(invitees); }); -} - -void -TimelineViewManager::openLink(QString link) const -{ - QUrl url(link); - if (url.scheme() == "https" && url.host() == "matrix.to") { - // handle matrix.to links internally - QString p = url.fragment(QUrl::FullyEncoded); - if (p.startsWith("/")) - p.remove(0, 1); - - auto temp = p.split("?"); - QString query; - if (temp.size() >= 2) - query = QUrl::fromPercentEncoding(temp.takeAt(1).toUtf8()); - - temp = temp.first().split("/"); - auto identifier = QUrl::fromPercentEncoding(temp.takeFirst().toUtf8()); - QString eventId = QUrl::fromPercentEncoding(temp.join('/').toUtf8()); - if (!identifier.isEmpty()) { - if (identifier.startsWith("@")) { - QByteArray uri = - "matrix:u/" + QUrl::toPercentEncoding(identifier.remove(0, 1)); - if (!query.isEmpty()) - uri.append("?" + query.toUtf8()); - ChatPage::instance()->handleMatrixUri(QUrl::fromEncoded(uri)); - } else if (identifier.startsWith("#")) { - QByteArray uri = - "matrix:r/" + QUrl::toPercentEncoding(identifier.remove(0, 1)); - if (!eventId.isEmpty()) - uri.append("/e/" + - QUrl::toPercentEncoding(eventId.remove(0, 1))); - if (!query.isEmpty()) - uri.append("?" + query.toUtf8()); - ChatPage::instance()->handleMatrixUri(QUrl::fromEncoded(uri)); - } else if (identifier.startsWith("!")) { - QByteArray uri = "matrix:roomid/" + - QUrl::toPercentEncoding(identifier.remove(0, 1)); - if (!eventId.isEmpty()) - uri.append("/e/" + - QUrl::toPercentEncoding(eventId.remove(0, 1))); - if (!query.isEmpty()) - uri.append("?" + query.toUtf8()); - ChatPage::instance()->handleMatrixUri(QUrl::fromEncoded(uri)); - } - } - } else { - QDesktopServices::openUrl(url); - } -} +//void +//TimelineViewManager::openInviteUsersDialog() +//{ + // TODO: move this somewhere where it will actually work (probably Rooms) +// MainWindow::instance()->openInviteUsersDialog( +// [this](const QStringList &invitees) { emit inviteUsers(invitees); }); +//} void TimelineViewManager::openLeaveRoomDialog(QString roomid) const -- cgit 1.4.1 From a76fc7d20058fa10e1345e0de0a1431a7161cd57 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Fri, 11 Jun 2021 18:53:32 -0400 Subject: Add a fancy loading spinner to the member list --- resources/qml/RoomMembers.qml | 7 +++++++ src/MemberList.cpp | 15 ++++++++++++--- src/MemberList.h | 4 ++++ 3 files changed, 23 insertions(+), 3 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index d31fe319..8060a6cc 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -109,6 +109,13 @@ ApplicationWindow { } } } + + footer: BusyIndicator { + // This is not a wonderful solution, but it is the best way to calculate whether + // all users are loaded while keeping canFetchMore() const + running: members.numUsersLoaded < members.memberCount + anchors.centerIn: parent + } } } } diff --git a/src/MemberList.cpp b/src/MemberList.cpp index 2a9c3fbc..da4412d2 100644 --- a/src/MemberList.cpp +++ b/src/MemberList.cpp @@ -34,7 +34,10 @@ MemberList::MemberList(const QString &room_id, QWidget *parent) } try { - addUsers(cache::getMembers(room_id_.toStdString())); + auto members = cache::getMembers(room_id_.toStdString()); + addUsers(members); + numUsersLoaded_ = members.size(); + emit numUsersLoadedChanged(); } catch (const lmdb::error &e) { nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what()); } @@ -83,11 +86,17 @@ bool MemberList::canFetchMore(const QModelIndex &) const { const size_t numMembers = rowCount(); - return (numMembers > 1 && numMembers < info_.member_count); + if (numMembers > 1 && numMembers < info_.member_count) + return true; + else + return false; } void MemberList::fetchMore(const QModelIndex &) { - addUsers(cache::getMembers(room_id_.toStdString(), rowCount())); + auto members = cache::getMembers(room_id_.toStdString(), rowCount()); + addUsers(members); + numUsersLoaded_ = members.size(); + emit numUsersLoadedChanged(); } diff --git a/src/MemberList.h b/src/MemberList.h index dbe69f4b..afc1a6e5 100644 --- a/src/MemberList.h +++ b/src/MemberList.h @@ -15,6 +15,7 @@ class MemberList : public QAbstractListModel Q_PROPERTY(size_t memberCount READ memberCount NOTIFY memberCountChanged) Q_PROPERTY(QString avatarUrl READ avatarUrl NOTIFY avatarUrlChanged) Q_PROPERTY(QString roomId READ roomId NOTIFY roomIdChanged) + Q_PROPERTY(int numUsersLoaded READ numUsersLoaded NOTIFY numUsersLoadedChanged) public: enum Roles @@ -37,12 +38,14 @@ public: size_t memberCount() const { return info_.member_count; } QString avatarUrl() const { return QString::fromStdString(info_.avatar_url); } QString roomId() const { return room_id_; } + int numUsersLoaded() const { return numUsersLoaded_; } signals: void roomNameChanged(); void memberCountChanged(); void avatarUrlChanged(); void roomIdChanged(); + void numUsersLoadedChanged(); public slots: void addUsers(const std::vector &users); @@ -55,4 +58,5 @@ private: QVector> m_memberList; QString room_id_; RoomInfo info_; + int numUsersLoaded_; }; -- cgit 1.4.1 From a176de5f11f11bb3dad6cb8ea71a3b5edd6f27f4 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Fri, 11 Jun 2021 20:46:57 -0400 Subject: Make sure to use the default room id if none is specified --- resources/qml/InviteDialog.qml | 3 ++- src/timeline/TimelineModel.cpp | 6 +++--- src/timeline/TimelineModel.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index d5cc4c6d..278f772f 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -43,10 +43,11 @@ ApplicationWindow { RowLayout { spacing: 10 - TextField { + MatrixTextField { id: inviteeEntry placeholderText: qsTr("@joe:matrix.org", "Example user id. The name 'joe' can be localized however you want.") + backgroundColor: colors.window Layout.fillWidth: true onAccepted: if (text !== "") addInvite() } diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 2127801c..ebbca6f4 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -1077,11 +1077,11 @@ TimelineModel::openRoomSettings(QString room_id) } void -TimelineModel::openInviteUsers(QString room_id) +TimelineModel::openInviteUsers(QString roomId) { InviteesModel *model = new InviteesModel{this}; - connect(model, &InviteesModel::accept, this, [this, model, room_id]() { - manager_->inviteUsers(room_id, model->mxids()); + connect(model, &InviteesModel::accept, this, [this, model, roomId]() { + manager_->inviteUsers(roomId == QString() ? room_id_ : roomId, model->mxids()); }); openInviteUsersDialog(model); } diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index e5189e61..b5144308 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -240,7 +240,7 @@ public: Q_INVOKABLE void openUserProfile(QString userid); Q_INVOKABLE void openRoomMembers(); Q_INVOKABLE void openRoomSettings(QString room_id = QString()); - Q_INVOKABLE void openInviteUsers(QString room_id = QString()); + Q_INVOKABLE void openInviteUsers(QString roomId = QString()); Q_INVOKABLE void editAction(QString id); Q_INVOKABLE void replyAction(QString id); Q_INVOKABLE void readReceiptsAction(QString id) const; -- cgit 1.4.1 From 3c999ade95785987d2213036067110bc1bb4fcb1 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Fri, 11 Jun 2021 20:47:43 -0400 Subject: Focus the input bar automatically --- resources/qml/InviteDialog.qml | 1 + 1 file changed, 1 insertion(+) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 278f772f..002a35c2 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -50,6 +50,7 @@ ApplicationWindow { backgroundColor: colors.window Layout.fillWidth: true onAccepted: if (text !== "") addInvite() + Component.onCompleted: forceActiveFocus() } Button { -- cgit 1.4.1 From 4746fcd16f458c9b88e5e50074c33254da7e1141 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Fri, 11 Jun 2021 20:48:20 -0400 Subject: Add fancy label if you enter a bad mxid --- resources/qml/InviteDialog.qml | 73 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 002a35c2..9ace3246 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -16,6 +16,10 @@ ApplicationWindow { invitees.addUser(inviteeEntry.text); inviteeEntry.clear(); } + else + { + warningLabel.show() + } } title: qsTr("Invite users to ") + roomName @@ -51,6 +55,11 @@ ApplicationWindow { Layout.fillWidth: true onAccepted: if (text !== "") addInvite() Component.onCompleted: forceActiveFocus() + + Shortcut { + sequence: "Ctrl+Enter" + onActivated: inviteDialogRoot.accept() + } } Button { @@ -59,6 +68,70 @@ ApplicationWindow { } } + Label { + id: warningLabel + + function show() { + state = "shown"; + warningLabelTimer.start(); + } + + text: qsTr("Please enter a valid username (e.g. @joe:matrix.org).") + color: "red" + visible: false + opacity: 0 + state: "hidden" + + states: [ + State { + name: "shown" + PropertyChanges { + target: warningLabel + opacity: 1 + visible: true + } + }, + State { + name: "hidden" + PropertyChanges { + target: warningLabel + opacity: 0 + visible: false + } + } + ] + + transitions: [ + Transition { + from: "shown" + to: "hidden" + reversible: true + + SequentialAnimation { + NumberAnimation { + target: warningLabel + property: "opacity" + duration: 500 + } + + PropertyAction { + target: warningLabel + property: "visible" + } + } + } + ] + + Timer { + id: warningLabelTimer + + interval: 2000 + repeat: false + running: false + onTriggered: warningLabel.state = "hidden" + } + } + ListView { id: inviteesList -- cgit 1.4.1 From c566a6254138037d8916bedf9660a66f2d65187f Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Fri, 11 Jun 2021 20:48:28 -0400 Subject: Clean up code --- resources/qml/InviteDialog.qml | 13 ------------- src/InviteesModel.cpp | 4 +--- 2 files changed, 1 insertion(+), 16 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 9ace3246..d8e176e6 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -172,19 +172,6 @@ ApplicationWindow { } } } -// delegate: RowLayout { -// spacing: 10 - -// Avatar { -// url: model.avatarUrl -// width: 20 -// height: width -// } - -// Label { -// text: model.displayName + " (" + model.mxid + ")" -// } -// } } } diff --git a/src/InviteesModel.cpp b/src/InviteesModel.cpp index 0081c7df..1da7baf4 100644 --- a/src/InviteesModel.cpp +++ b/src/InviteesModel.cpp @@ -15,9 +15,7 @@ InviteesModel::addUser(QString mxid) beginInsertRows(QModelIndex(), invitees_.count(), invitees_.count()); auto invitee = new Invitee{mxid, this}; - connect(invitee, &Invitee::userInfoLoaded, this, [this]() { - endInsertRows(); - }); + connect(invitee, &Invitee::userInfoLoaded, this, [this]() { endInsertRows(); }); invitees_.push_back(invitee); } -- cgit 1.4.1 From 03acced6d6c5b95c2272f8d3036a6295d048a4f5 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Fri, 11 Jun 2021 21:04:35 -0400 Subject: Add close on Escape shortcut --- resources/qml/InviteDialog.qml | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index d8e176e6..3470a7f1 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -34,6 +34,11 @@ ApplicationWindow { onActivated: inviteDialogRoot.accept() } + Shortcut { + sequence: StandardKey.Cancel + onActivated: inviteDialogRoot.close() + } + ColumnLayout { anchors.fill: parent anchors.margins: 10 -- cgit 1.4.1 From 908629bec0ff490b42aa1f0b1c8fade160606e96 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Fri, 11 Jun 2021 21:05:18 -0400 Subject: Fix item that accept() is called on --- resources/qml/InviteDialog.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 3470a7f1..8ba0f262 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -31,7 +31,7 @@ ApplicationWindow { // TODO: make this work in the TextField Shortcut { sequence: "Ctrl+Enter" - onActivated: inviteDialogRoot.accept() + onActivated: invitees.accept() } Shortcut { @@ -63,7 +63,7 @@ ApplicationWindow { Shortcut { sequence: "Ctrl+Enter" - onActivated: inviteDialogRoot.accept() + onActivated: invitees.accept() } } -- cgit 1.4.1 From 59a2630be74898c5d8c13dbf0489e5caa94063fd Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 12 Jun 2021 12:00:59 -0400 Subject: Simplify room details access This removes the redundant room name property --- resources/qml/InviteDialog.qml | 1 - resources/qml/RoomMembers.qml | 5 ++--- resources/qml/TopBar.qml | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 8ba0f262..2932e398 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -56,7 +56,6 @@ ApplicationWindow { id: inviteeEntry placeholderText: qsTr("@joe:matrix.org", "Example user id. The name 'joe' can be localized however you want.") - backgroundColor: colors.window Layout.fillWidth: true onAccepted: if (text !== "") addInvite() Component.onCompleted: forceActiveFocus() diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 8060a6cc..8addd704 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -7,10 +7,9 @@ import im.nheko 1.0 ApplicationWindow { id: roomMembersRoot - property string roomName: Rooms.currentRoom.roomName property MemberList members - title: qsTr("Members of ") + roomName + title: qsTr("Members of ") + members.roomName x: MainWindow.x + (MainWindow.width / 2) - (width / 2) y: MainWindow.y + (MainWindow.height / 2) - (height / 2) height: 650 @@ -40,7 +39,7 @@ ApplicationWindow { Label { font.pixelSize: 24 - text: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + roomName + text: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + members.roomName Layout.alignment: Qt.AlignHCenter } diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml index 6cf747c5..aa5c5d18 100644 --- a/resources/qml/TopBar.qml +++ b/resources/qml/TopBar.qml @@ -111,12 +111,12 @@ Rectangle { Platform.MenuItem { visible: room ? room.permissions.canInvite() : false text: qsTr("Invite users") - onTriggered: TimelineManager.timeline.openInviteUsers() + onTriggered: Rooms.currentRoom.openInviteUsers() } Platform.MenuItem { text: qsTr("Members") - onTriggered: Rooms.currentRoom.openRoomMembers(room.roomId()) + onTriggered: Rooms.currentRoom.openRoomMembers() } Platform.MenuItem { -- cgit 1.4.1 From 182de32380d192a6dcf71b656e5e5cd3bab30a6e Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 15 Jun 2021 12:32:00 -0400 Subject: Use standard buttons for OK button --- resources/qml/RoomSettings.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomSettings.qml b/resources/qml/RoomSettings.qml index c852b837..a27be13e 100644 --- a/resources/qml/RoomSettings.qml +++ b/resources/qml/RoomSettings.qml @@ -280,10 +280,10 @@ ApplicationWindow { } - Button { - Layout.alignment: Qt.AlignRight - text: qsTr("OK") - onClicked: close() + DialogButtonBox { + Layout.fillWidth: true + standardButtons: DialogButtonBox.Ok + onAccepted: close() } } -- cgit 1.4.1 From d2d5229ede5124ba6cf9e85790dcd564faad00db Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 13:31:38 -0400 Subject: make lint --- resources/qml/InviteDialog.qml | 44 ++++++++++++++++++++++++-------- resources/qml/RoomMembers.qml | 4 +++ resources/qml/TimelineView.qml | 1 + src/ChatPage.cpp | 49 +++++++++++++++++++----------------- src/InviteesModel.cpp | 4 +++ src/InviteesModel.h | 4 +++ src/timeline/TimelineViewManager.cpp | 6 ++--- 7 files changed, 75 insertions(+), 37 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 2932e398..ae74d3da 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 @@ -11,14 +15,11 @@ ApplicationWindow { property InviteesModel invitees function addInvite() { - if (inviteeEntry.text.match("@.+?:.{3,}")) - { + if (inviteeEntry.text.match("@.+?:.{3,}")) { invitees.addUser(inviteeEntry.text); inviteeEntry.clear(); - } - else - { - warningLabel.show() + } else { + warningLabel.show(); } } @@ -57,19 +58,29 @@ ApplicationWindow { placeholderText: qsTr("@joe:matrix.org", "Example user id. The name 'joe' can be localized however you want.") Layout.fillWidth: true - onAccepted: if (text !== "") addInvite() + onAccepted: { + if (text !== "") { + addInvite(); + } + } Component.onCompleted: forceActiveFocus() Shortcut { sequence: "Ctrl+Enter" onActivated: invitees.accept() } + } Button { text: qsTr("Add") - onClicked: if (inviteeEntry.text !== "") addInvite() + onClicked: { + if (inviteeEntry.text !== "") { + addInvite(); + } + } } + } Label { @@ -85,26 +96,28 @@ ApplicationWindow { visible: false opacity: 0 state: "hidden" - states: [ State { name: "shown" + PropertyChanges { target: warningLabel opacity: 1 visible: true } + }, State { name: "hidden" + PropertyChanges { target: warningLabel opacity: 0 visible: false } + } ] - transitions: [ Transition { from: "shown" @@ -122,7 +135,9 @@ ApplicationWindow { target: warningLabel property: "visible" } + } + } ] @@ -134,6 +149,7 @@ ApplicationWindow { running: false onTriggered: warningLabel.state = "hidden" } + } ListView { @@ -174,9 +190,13 @@ ApplicationWindow { Layout.fillHeight: true Layout.fillWidth: true } + } + } + } + } footer: DialogButtonBox { @@ -194,7 +214,9 @@ ApplicationWindow { Button { text: qsTr("Cancel") DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole - onClicked: inviteDialogRoot.close(); + onClicked: inviteDialogRoot.close() } + } + } diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 8addd704..44b917b1 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index d515b9b4..148a5817 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -157,6 +157,7 @@ Item { Layout.alignment: Qt.AlignHCenter enabled: false } + MatrixText { text: parent.roomName font.pixelSize: 24 diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 8b4cfeef..70fd32fd 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -117,29 +117,32 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(this, &ChatPage::loggedOut, this, &ChatPage::logout); // TODO: once this signal is moved, reenable this -// connect(view_manager_, &TimelineViewManager::inviteUsers, this, [this](QStringList users) { -// const auto room_id = currentRoom().toStdString(); - -// for (int ii = 0; ii < users.size(); ++ii) { -// QTimer::singleShot(ii * 500, this, [this, room_id, ii, users]() { -// const auto user = users.at(ii); - -// http::client()->invite_user( -// room_id, -// user.toStdString(), -// [this, user](const mtx::responses::RoomInvite &, -// mtx::http::RequestErr err) { -// if (err) { -// emit showNotification( -// tr("Failed to invite user: %1").arg(user)); -// return; -// } - -// emit showNotification(tr("Invited user: %1").arg(user)); -// }); -// }); -// } -// }); + // connect(view_manager_, &TimelineViewManager::inviteUsers, this, [this](QStringList + // users) { + // const auto room_id = currentRoom().toStdString(); + + // for (int ii = 0; ii < users.size(); ++ii) { + // QTimer::singleShot(ii * 500, this, [this, room_id, ii, users]() { + // const auto user = users.at(ii); + + // http::client()->invite_user( + // room_id, + // user.toStdString(), + // [this, user](const mtx::responses::RoomInvite &, + // mtx::http::RequestErr err) { + // if (err) { + // emit showNotification( + // tr("Failed to invite user: + // %1").arg(user)); + // return; + // } + + // emit showNotification(tr("Invited user: + // %1").arg(user)); + // }); + // }); + // } + // }); connect( view_manager_, diff --git a/src/InviteesModel.cpp b/src/InviteesModel.cpp index 1da7baf4..59054690 100644 --- a/src/InviteesModel.cpp +++ b/src/InviteesModel.cpp @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + #include "InviteesModel.h" #include "Cache.h" diff --git a/src/InviteesModel.h b/src/InviteesModel.h index 4bcc4e9d..ac9208a0 100644 --- a/src/InviteesModel.h +++ b/src/InviteesModel.h @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + #ifndef INVITEESMODEL_H #define INVITEESMODEL_H diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 08b88efd..8daa2124 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -430,10 +430,10 @@ TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img) }); } -//void -//TimelineViewManager::openInviteUsersDialog() +// void +// TimelineViewManager::openInviteUsersDialog() //{ - // TODO: move this somewhere where it will actually work (probably Rooms) +// TODO: move this somewhere where it will actually work (probably Rooms) // MainWindow::instance()->openInviteUsersDialog( // [this](const QStringList &invitees) { emit inviteUsers(invitees); }); //} -- cgit 1.4.1 From 4ddcff2300ba37c88d8170f063ba1f0ae546efc8 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 16:16:02 -0400 Subject: Fix borked property stuff --- resources/qml/RoomList.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index a1ce8d7e..7c03673f 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -133,7 +133,7 @@ Page { states: [ State { name: "highlight" - when: hovered.hovered && !((Rooms.currentRoom && roomId == Rooms.currentRoom.roomId()) || Rooms.currentRoomPreview.roomid == roomId) + when: hovered.hovered && !((Rooms.currentRoom && roomId == Rooms.currentRoom.roomId) || Rooms.currentRoomPreview.roomid == roomId) PropertyChanges { target: roomItem @@ -147,7 +147,7 @@ Page { }, State { name: "selected" - when: (Rooms.currentRoom && roomId == Rooms.currentRoom.roomId()) || Rooms.currentRoomPreview.roomid == roomId + when: (Rooms.currentRoom && roomId == Rooms.currentRoom.roomId) || Rooms.currentRoomPreview.roomid == roomId PropertyChanges { target: roomItem -- cgit 1.4.1 From 5d9556722f409c9202c0b506dd789b7d2d722b01 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 16:16:18 -0400 Subject: Fix up components --- resources/qml/Root.qml | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index ecd0bdb7..3825fb89 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -47,6 +47,13 @@ Page { } + Component { + id: roomMembersComponent + + RoomMembers { + } + } + Component { id: mobileCallInviteDialog @@ -63,6 +70,20 @@ Page { } + Component { + id: deviceVerificationDialog + + DeviceVerification { + } + + } + Component { + id: inviteDialog + + InviteDialog { + } + } + Shortcut { sequence: "Ctrl+K" onActivated: { @@ -82,20 +103,6 @@ Page { onActivated: Rooms.previousRoom() } - Component { - id: deviceVerificationDialog - - DeviceVerification { - } - - } - Component { - id: inviteDialog - - InviteDialog { - } - } - Connections { target: TimelineManager onNewDeviceVerificationRequest: { @@ -123,18 +130,18 @@ Page { } Connections { - target: TimelineManager.timeline + target: Rooms.currentRoom onOpenRoomMembersDialog: { var membersDialog = roomMembersComponent.createObject(timelineRoot, { "members": members, - "roomName": TimelineManager.timeline.roomName + "roomName": Rooms.currentRoom.roomName }); membersDialog.show(); } } Connections { - target: TimelineManager.timeline + target: Rooms.currentRoom onOpenRoomSettingsDialog: { var roomSettings = roomSettingsComponent.createObject(timelineRoot, { "roomSettings": settings @@ -144,12 +151,12 @@ Page { } Connections { - target: TimelineManager.timeline + target: Rooms.currentRoom onOpenInviteUsersDialog: { var dialog = inviteDialog.createObject(timelineRoot, { - "roomId": TimelineManager.timeline.roomId, - "roomName": TimelineManager.timeline.roomName - }); + "roomId": Rooms.currentRoom.roomId, + "roomName": Rooms.currentRoom.roomName + }); dialog.show(); } } -- cgit 1.4.1 From 02326fce70372e2dc8753ba51286b24f93882559 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 16:17:05 -0400 Subject: Fix background color on text input --- resources/qml/InviteDialog.qml | 1 + resources/qml/MatrixTextField.qml | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index ae74d3da..e171808e 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -56,6 +56,7 @@ ApplicationWindow { MatrixTextField { id: inviteeEntry + backgroundColor: Nheko.colors.window placeholderText: qsTr("@joe:matrix.org", "Example user id. The name 'joe' can be localized however you want.") Layout.fillWidth: true onAccepted: { diff --git a/resources/qml/MatrixTextField.qml b/resources/qml/MatrixTextField.qml index 3c660bac..80732b27 100644 --- a/resources/qml/MatrixTextField.qml +++ b/resources/qml/MatrixTextField.qml @@ -10,6 +10,8 @@ import im.nheko 1.0 TextField { id: input + property alias backgroundColor: backgroundRect.color + palette: Nheko.colors color: Nheko.colors.text @@ -62,6 +64,8 @@ TextField { } background: Rectangle { + id: backgroundRect + color: Nheko.colors.base } -- cgit 1.4.1 From cb8d1401234b2a0f94a2e778100e0b2f757c45a2 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 16:48:06 -0400 Subject: Fix properties --- resources/qml/RoomMembers.qml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 44b917b1..9b920f2b 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -7,6 +7,7 @@ import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import QtQuick.Window 2.12 import im.nheko 1.0 +import "./ui" ApplicationWindow { id: roomMembersRoot @@ -38,7 +39,7 @@ ApplicationWindow { displayName: members.roomName Layout.alignment: Qt.AlignHCenter url: members.avatarUrl.replace("mxc://", "image://MxcImage/") - onClicked: TimelineManager.timeline.openRoomSettings(members.roomId) + onClicked: Rooms.currentRoom.openRoomSettings(members.roomId) } Label { @@ -53,12 +54,12 @@ ApplicationWindow { hoverEnabled: true ToolTip.visible: hovered ToolTip.text: qsTr("Invite more people") - onClicked: TimelineManager.timeline.openInviteUsersDialog() + onClicked: Rooms.currentRoom.openInviteUsersDialog() } ScrollView { clip: false - palette: colors + palette: Nheko.colors padding: 10 ScrollBar.horizontal.visible: false Layout.fillHeight: true @@ -83,12 +84,12 @@ ApplicationWindow { spacing: 10 Avatar { - width: avatarSize - height: avatarSize + width: Nheko.avatarSize + height: Nheko.avatarSize userid: model.mxid url: model.avatarUrl.replace("mxc://", "image://MxcImage/") displayName: model.displayName - onClicked: TimelineManager.timeline.openUserProfile(model.mxid) + onClicked: Rooms.currentRoom.openUserProfile(model.mxid) } ColumnLayout { @@ -96,13 +97,13 @@ ApplicationWindow { Label { text: model.displayName - color: TimelineManager.userColor(model ? model.mxid : "", colors.window) + color: TimelineManager.userColor(model ? model.mxid : "", Nheko.colors.window) font.pointSize: 12 } Label { text: model.mxid - color: colors.buttonText + color: Nheko.colors.buttonText font.pointSize: 10 } -- cgit 1.4.1 From 3c5b395171ae526c4564fad5182c174ff2352b65 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 16:48:19 -0400 Subject: Use fancy spinner (courtesy of redsky) --- resources/qml/RoomMembers.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 9b920f2b..d1d60a16 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -114,7 +114,7 @@ ApplicationWindow { } } - footer: BusyIndicator { + footer: Spinner { // This is not a wonderful solution, but it is the best way to calculate whether // all users are loaded while keeping canFetchMore() const running: members.numUsersLoaded < members.memberCount -- cgit 1.4.1 From 81a3faee7b7035501325a44a04eba2fbfde8a7e6 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 16:56:56 -0400 Subject: Finish converting function to property --- resources/qml/Completer.qml | 2 +- resources/qml/RoomList.qml | 4 ++-- resources/qml/TimelineView.qml | 2 +- resources/qml/TopBar.qml | 2 +- resources/qml/delegates/MessageDelegate.qml | 2 +- resources/qml/voip/PlaceCall.qml | 4 ++-- resources/qml/voip/ScreenShare.qml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml index 333fb11d..00fc3216 100644 --- a/resources/qml/Completer.qml +++ b/resources/qml/Completer.qml @@ -70,7 +70,7 @@ Popup { onCompleterNameChanged: { if (completerName) { if (completerName == "user") - completer = TimelineManager.completerFor(completerName, room.roomId()); + completer = TimelineManager.completerFor(completerName, room.roomId); else completer = TimelineManager.completerFor(completerName); completer.setSearchString(""); diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index 7c03673f..9dac5830 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -33,8 +33,8 @@ Page { Connections { onActiveTimelineChanged: { - roomlist.positionViewAtIndex(Rooms.roomidToIndex(Rooms.currentRoom.roomId()), ListView.Contain); - console.log("Test" + Rooms.currentRoom.roomId() + " " + Rooms.roomidToIndex(Rooms.currentRoom.roomId())); + roomlist.positionViewAtIndex(Rooms.roomidToIndex(Rooms.currentRoom.roomId), ListView.Contain); + console.log("Test" + Rooms.currentRoom.roomId + " " + Rooms.roomidToIndex(Rooms.currentRoom.roomId)); } target: TimelineManager } diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 148a5817..f5979e14 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -246,7 +246,7 @@ Item { NhekoDropArea { anchors.fill: parent - roomid: room ? room.roomId() : "" + roomid: room ? room.roomId : "" } Connections { diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml index aa5c5d18..48491f84 100644 --- a/resources/qml/TopBar.qml +++ b/resources/qml/TopBar.qml @@ -121,7 +121,7 @@ Rectangle { Platform.MenuItem { text: qsTr("Leave room") - onTriggered: TimelineManager.openLeaveRoomDialog(room.roomId()) + onTriggered: TimelineManager.openLeaveRoomDialog(room.roomId) } Platform.MenuItem { diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml index c64ae887..a98c2a8b 100644 --- a/resources/qml/delegates/MessageDelegate.qml +++ b/resources/qml/delegates/MessageDelegate.qml @@ -232,7 +232,7 @@ Item { body: formatted isOnlyEmoji: false isReply: d.isReply - formatted: qsTr("%1 created and configured room: %2").arg(d.userName).arg(room.roomId()) + formatted: qsTr("%1 created and configured room: %2").arg(d.userName).arg(room.roomId) } } diff --git a/resources/qml/voip/PlaceCall.qml b/resources/qml/voip/PlaceCall.qml index 5f564853..97932cc9 100644 --- a/resources/qml/voip/PlaceCall.qml +++ b/resources/qml/voip/PlaceCall.qml @@ -88,7 +88,7 @@ Popup { onClicked: { if (buttonLayout.validateMic()) { Settings.microphone = micCombo.currentText; - CallManager.sendInvite(room.roomId(), CallType.VOICE); + CallManager.sendInvite(room.roomId, CallType.VOICE); close(); } } @@ -102,7 +102,7 @@ Popup { if (buttonLayout.validateMic()) { Settings.microphone = micCombo.currentText; Settings.camera = cameraCombo.currentText; - CallManager.sendInvite(room.roomId(), CallType.VIDEO); + CallManager.sendInvite(room.roomId, CallType.VIDEO); close(); } } diff --git a/resources/qml/voip/ScreenShare.qml b/resources/qml/voip/ScreenShare.qml index a10057b2..8cd43b1c 100644 --- a/resources/qml/voip/ScreenShare.qml +++ b/resources/qml/voip/ScreenShare.qml @@ -136,7 +136,7 @@ Popup { Settings.screenSharePiP = pipCheckBox.checked; Settings.screenShareRemoteVideo = remoteVideoCheckBox.checked; Settings.screenShareHideCursor = hideCursorCheckBox.checked; - CallManager.sendInvite(room.roomId(), CallType.SCREEN, windowCombo.currentIndex); + CallManager.sendInvite(room.roomId, CallType.SCREEN, windowCombo.currentIndex); close(); } } -- cgit 1.4.1 From 462204f3f462a5f348227379b5743405df38ff23 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 18:23:03 -0400 Subject: Fix properties --- resources/qml/InviteDialog.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index e171808e..83471658 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -164,8 +164,8 @@ ApplicationWindow { spacing: 10 Avatar { - width: avatarSize - height: avatarSize + width: Nheko.avatarsize + height: Nheko.avatarsize userid: model.mxid url: model.avatarUrl.replace("mxc://", "image://MxcImage/") displayName: model.displayName @@ -177,13 +177,13 @@ ApplicationWindow { Label { text: model.displayName - color: TimelineManager.userColor(model ? model.mxid : "", colors.window) + color: TimelineManager.userColor(model ? model.mxid : "", Nheko.colors.window) font.pointSize: 12 } Label { text: model.mxid - color: colors.buttonText + color: Nheko.colors.buttonText font.pointSize: 10 } -- cgit 1.4.1 From 73d902611d583e6b57319bfbbf5071e7967a4ff0 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 18:23:21 -0400 Subject: Actually set invitees property --- resources/qml/Root.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index 3825fb89..31d00585 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -155,7 +155,8 @@ Page { onOpenInviteUsersDialog: { var dialog = inviteDialog.createObject(timelineRoot, { "roomId": Rooms.currentRoom.roomId, - "roomName": Rooms.currentRoom.roomName + "roomName": Rooms.currentRoom.roomName, + "invitees": invitees }); dialog.show(); } -- cgit 1.4.1 From 155315ecbb84cf517d1daa98c76ea7eb41741086 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 18:24:38 -0400 Subject: Fix Ctrl-Enter shortcut --- resources/qml/InviteDialog.qml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 83471658..3415a93e 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -29,11 +29,9 @@ ApplicationWindow { height: 380 width: 340 - // TODO: make this work in the TextField - Shortcut { - sequence: "Ctrl+Enter" - onActivated: invitees.accept() - } + Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && event.modifiers & Qt.ControlModifier) + Keys.onEnterPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() + Keys.onReturnPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() Shortcut { sequence: StandardKey.Cancel @@ -66,10 +64,14 @@ ApplicationWindow { } Component.onCompleted: forceActiveFocus() - Shortcut { - sequence: "Ctrl+Enter" - onActivated: invitees.accept() - } +// Shortcut { +// sequence: "Ctrl+Enter" +// onActivated: invitees.accept() +// } + + Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && event.modifiers & Qt.ControlModifier) + Keys.onEnterPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() + Keys.onReturnPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() } -- cgit 1.4.1 From d2c62529117e878cb92b59039aa367909e4c3871 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 19:24:45 -0400 Subject: More shortcut stuff --- resources/qml/InviteDialog.qml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 3415a93e..23420fa2 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -29,10 +29,6 @@ ApplicationWindow { height: 380 width: 340 - Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && event.modifiers & Qt.ControlModifier) - Keys.onEnterPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() - Keys.onReturnPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() - Shortcut { sequence: StandardKey.Cancel onActivated: inviteDialogRoot.close() @@ -43,6 +39,10 @@ ApplicationWindow { anchors.margins: 10 spacing: 10 + Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers & Qt.ControlModifier)) + Keys.onEnterPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() + Keys.onReturnPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() + Label { text: qsTr("User ID to invite") Layout.fillWidth: true @@ -69,7 +69,7 @@ ApplicationWindow { // onActivated: invitees.accept() // } - Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && event.modifiers & Qt.ControlModifier) + Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers & Qt.ControlModifier)) Keys.onEnterPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() Keys.onReturnPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() -- cgit 1.4.1 From 4d5950b6a7a38327ce1be88a910a474caead68b5 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 19:25:09 -0400 Subject: Document bad behavior with footer and spinner --- resources/qml/RoomMembers.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index d1d60a16..da650859 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -117,7 +117,10 @@ ApplicationWindow { footer: Spinner { // This is not a wonderful solution, but it is the best way to calculate whether // all users are loaded while keeping canFetchMore() const - running: members.numUsersLoaded < members.memberCount + + // TODO: just toggling the visiblity leaves some large empty space at the bottom + // of the list. This should be fixed. + visible: members.numUsersLoaded < members.memberCount anchors.centerIn: parent } } -- cgit 1.4.1 From 67fff656b3bc13d4264dc144582699931953ffb3 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 19:43:07 -0400 Subject: Fix bad property name --- resources/qml/InviteDialog.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 23420fa2..8bdbb767 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -166,8 +166,8 @@ ApplicationWindow { spacing: 10 Avatar { - width: Nheko.avatarsize - height: Nheko.avatarsize + width: Nheko.avatarSize + height: Nheko.avatarSize userid: model.mxid url: model.avatarUrl.replace("mxc://", "image://MxcImage/") displayName: model.displayName -- cgit 1.4.1 From f1f5796fb8ba5b504043310dba17acd3ef2860bd Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 17 Jul 2021 19:43:35 -0400 Subject: Get Ctrl+Enter working and fix cleaning up and closing --- resources/qml/InviteDialog.qml | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 8bdbb767..417de049 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -23,12 +23,24 @@ ApplicationWindow { } } + function cleanUpAndClose() { + if (inviteeEntry.text !== "") + addInvite(); + invitees.accept(); + close(); + } + title: qsTr("Invite users to ") + roomName x: MainWindow.x + (MainWindow.width / 2) - (width / 2) y: MainWindow.y + (MainWindow.height / 2) - (height / 2) height: 380 width: 340 + Shortcut { + sequence: "Ctrl+Enter" + onActivated: cleanUpAndClose() + } + Shortcut { sequence: StandardKey.Cancel onActivated: inviteDialogRoot.close() @@ -39,10 +51,6 @@ ApplicationWindow { anchors.margins: 10 spacing: 10 - Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers & Qt.ControlModifier)) - Keys.onEnterPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() - Keys.onReturnPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() - Label { text: qsTr("User ID to invite") Layout.fillWidth: true @@ -64,14 +72,8 @@ ApplicationWindow { } Component.onCompleted: forceActiveFocus() -// Shortcut { -// sequence: "Ctrl+Enter" -// onActivated: invitees.accept() -// } - Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers & Qt.ControlModifier)) - Keys.onEnterPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() - Keys.onReturnPressed: if (event.modifiers & Qt.ControlModifier) invitees.accept() + Keys.onPressed: if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers === Qt.ControlModifier)) cleanUpAndClose() } @@ -208,10 +210,7 @@ ApplicationWindow { Button { text: qsTr("Invite") DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole - onClicked: { - invitees.accept(); - inviteDialogRoot.close(); - } + onClicked: cleanUpAndClose() } Button { -- cgit 1.4.1 From 74d493ff1672eb9f8cf333bb5c11f80eb178eeb5 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 19 Jul 2021 10:07:54 -0400 Subject: Use standardized padding --- resources/qml/InviteDialog.qml | 6 +++--- resources/qml/RoomMembers.qml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 417de049..02cb5e07 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -49,7 +49,7 @@ ApplicationWindow { ColumnLayout { anchors.fill: parent anchors.margins: 10 - spacing: 10 + spacing: Nheko.paddingMedium Label { text: qsTr("User ID to invite") @@ -57,7 +57,7 @@ ApplicationWindow { } RowLayout { - spacing: 10 + spacing: Nheko.paddingMedium MatrixTextField { id: inviteeEntry @@ -165,7 +165,7 @@ ApplicationWindow { model: invitees delegate: RowLayout { - spacing: 10 + spacing: Nheko.paddingMedium Avatar { width: Nheko.avatarSize diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index da650859..f9be95a1 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -29,7 +29,7 @@ ApplicationWindow { ColumnLayout { anchors.fill: parent anchors.margins: 10 - spacing: 10 + spacing: Nheko.paddingMedium Avatar { id: roomAvatar @@ -81,7 +81,7 @@ ApplicationWindow { } delegate: RowLayout { - spacing: 10 + spacing: Nheko.paddingMedium Avatar { width: Nheko.avatarSize -- cgit 1.4.1 From 4384554587c3e9327382f2f9cbc36e893fbe4dab Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 19 Jul 2021 12:31:20 -0400 Subject: Only invite if there is something/someone to invite --- resources/qml/InviteDialog.qml | 81 +++--------------------------------------- src/InviteesModel.cpp | 2 ++ src/InviteesModel.h | 3 ++ 3 files changed, 9 insertions(+), 77 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 02cb5e07..94a95861 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -18,13 +18,11 @@ ApplicationWindow { if (inviteeEntry.text.match("@.+?:.{3,}")) { invitees.addUser(inviteeEntry.text); inviteeEntry.clear(); - } else { - warningLabel.show(); } } function cleanUpAndClose() { - if (inviteeEntry.text !== "") + if (inviteeEntry.text.match("@.+?:.{3,}")) addInvite(); invitees.accept(); close(); @@ -79,80 +77,8 @@ ApplicationWindow { Button { text: qsTr("Add") - onClicked: { - if (inviteeEntry.text !== "") { - addInvite(); - } - } - } - - } - - Label { - id: warningLabel - - function show() { - state = "shown"; - warningLabelTimer.start(); - } - - text: qsTr("Please enter a valid username (e.g. @joe:matrix.org).") - color: "red" - visible: false - opacity: 0 - state: "hidden" - states: [ - State { - name: "shown" - - PropertyChanges { - target: warningLabel - opacity: 1 - visible: true - } - - }, - State { - name: "hidden" - - PropertyChanges { - target: warningLabel - opacity: 0 - visible: false - } - - } - ] - transitions: [ - Transition { - from: "shown" - to: "hidden" - reversible: true - - SequentialAnimation { - NumberAnimation { - target: warningLabel - property: "opacity" - duration: 500 - } - - PropertyAction { - target: warningLabel - property: "visible" - } - - } - - } - ] - - Timer { - id: warningLabelTimer - - interval: 2000 - repeat: false - running: false - onTriggered: warningLabel.state = "hidden" + enabled: inviteeEntry.text.match("@.+?:.{3,}") + onClicked: addInvite() } } @@ -210,6 +136,7 @@ ApplicationWindow { Button { text: qsTr("Invite") DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + enabled: invitees.count > 0 onClicked: cleanUpAndClose() } diff --git a/src/InviteesModel.cpp b/src/InviteesModel.cpp index 59054690..9b64f57c 100644 --- a/src/InviteesModel.cpp +++ b/src/InviteesModel.cpp @@ -22,6 +22,8 @@ InviteesModel::addUser(QString mxid) connect(invitee, &Invitee::userInfoLoaded, this, [this]() { endInsertRows(); }); invitees_.push_back(invitee); + + emit countChanged(); } QHash diff --git a/src/InviteesModel.h b/src/InviteesModel.h index ac9208a0..a4e19ebb 100644 --- a/src/InviteesModel.h +++ b/src/InviteesModel.h @@ -30,6 +30,8 @@ class InviteesModel : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) + public: enum Roles { @@ -52,6 +54,7 @@ public: signals: void accept(); + void countChanged(); private: QVector invitees_; -- cgit 1.4.1 From b6d4e6b20a5635b4acdee6e417dce0f55eaaaaa9 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 19 Jul 2021 12:31:57 -0400 Subject: Drop unnecessary code --- resources/qml/RoomMembers.qml | 1 - 1 file changed, 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index f9be95a1..28e999db 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -58,7 +58,6 @@ ApplicationWindow { } ScrollView { - clip: false palette: Nheko.colors padding: 10 ScrollBar.horizontal.visible: false -- cgit 1.4.1 From e91b3067a168f9729a9d4a353ff3e2ba83a473db Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 19 Jul 2021 12:32:09 -0400 Subject: Fix visibility of spinner --- resources/qml/RoomMembers.qml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 28e999db..0d957165 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -114,12 +114,9 @@ ApplicationWindow { } footer: Spinner { - // This is not a wonderful solution, but it is the best way to calculate whether - // all users are loaded while keeping canFetchMore() const - - // TODO: just toggling the visiblity leaves some large empty space at the bottom - // of the list. This should be fixed. visible: members.numUsersLoaded < members.memberCount + // use the default height if it's visible, otherwise no height at all + height: visible ? undefined : 0 anchors.centerIn: parent } } -- cgit 1.4.1 From 48669302ece255010f31150543d8e0ef4830fb74 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 19 Jul 2021 14:31:08 -0400 Subject: make lint --- resources/qml/InviteDialog.qml | 13 ++++++++----- resources/qml/RoomMembers.qml | 8 +++++++- resources/qml/Root.qml | 3 +++ src/MemberList.cpp | 6 +++++- 4 files changed, 23 insertions(+), 7 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 94a95861..b1b1bb39 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -24,6 +24,7 @@ ApplicationWindow { function cleanUpAndClose() { if (inviteeEntry.text.match("@.+?:.{3,}")) addInvite(); + invitees.accept(); close(); } @@ -64,15 +65,17 @@ ApplicationWindow { placeholderText: qsTr("@joe:matrix.org", "Example user id. The name 'joe' can be localized however you want.") Layout.fillWidth: true onAccepted: { - if (text !== "") { + if (text !== "") addInvite(); - } + } Component.onCompleted: forceActiveFocus() - Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers & Qt.ControlModifier)) - Keys.onPressed: if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers === Qt.ControlModifier)) cleanUpAndClose() - + Keys.onPressed: { + if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers === Qt.ControlModifier)) { + cleanUpAndClose(); + } + } } Button { diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 0d957165..57353132 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -2,12 +2,12 @@ // // SPDX-License-Identifier: GPL-3.0-or-later +import "./ui" import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import QtQuick.Window 2.12 import im.nheko 1.0 -import "./ui" ApplicationWindow { id: roomMembersRoot @@ -110,7 +110,9 @@ ApplicationWindow { Layout.fillHeight: true Layout.fillWidth: true } + } + } footer: Spinner { @@ -119,12 +121,16 @@ ApplicationWindow { height: visible ? undefined : 0 anchors.centerIn: parent } + } + } + } footer: DialogButtonBox { standardButtons: DialogButtonBox.Ok onAccepted: roomMembersRoot.close() } + } diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index 31d00585..102d0411 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -52,6 +52,7 @@ Page { RoomMembers { } + } Component { @@ -77,11 +78,13 @@ Page { } } + Component { id: inviteDialog InviteDialog { } + } Shortcut { diff --git a/src/MemberList.cpp b/src/MemberList.cpp index dd5997f5..04377a0f 100644 --- a/src/MemberList.cpp +++ b/src/MemberList.cpp @@ -60,7 +60,11 @@ MemberList::addUsers(const std::vector &members) QHash MemberList::roleNames() const { - return {{Mxid, "mxid"}, {DisplayName, "displayName"}, {AvatarUrl, "avatarUrl"},}; + return { + {Mxid, "mxid"}, + {DisplayName, "displayName"}, + {AvatarUrl, "avatarUrl"}, + }; } QVariant -- cgit 1.4.1 From a7bdbc2af26bc3c6af0e1061d63a479a2bacdd2e Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 19 Jul 2021 14:37:16 -0400 Subject: Consolidate connections --- resources/qml/Root.qml | 6 ------ resources/qml/TimelineView.qml | 10 ---------- 2 files changed, 16 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index 102d0411..0a0f90cf 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -141,20 +141,14 @@ Page { }); membersDialog.show(); } - } - Connections { - target: Rooms.currentRoom onOpenRoomSettingsDialog: { var roomSettings = roomSettingsComponent.createObject(timelineRoot, { "roomSettings": settings }); roomSettings.show(); } - } - Connections { - target: Rooms.currentRoom onOpenInviteUsersDialog: { var dialog = inviteDialog.createObject(timelineRoot, { "roomId": Rooms.currentRoom.roomId, diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index f5979e14..c5cc69a6 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -249,14 +249,4 @@ Item { roomid: room ? room.roomId : "" } - Connections { - target: room - onOpenRoomSettingsDialog: { - var roomSettings = roomSettingsComponent.createObject(timelineRoot, { - "roomSettings": settings - }); - roomSettings.show(); - } - } - } -- cgit 1.4.1 From 21eb312f69111b8141e2ac9da5bb3871287045bd Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 19 Jul 2021 14:49:57 -0400 Subject: Only run spinner while loading members --- resources/qml/RoomMembers.qml | 2 +- src/MemberList.cpp | 6 ++++++ src/MemberList.h | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 57353132..b190be07 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -116,7 +116,7 @@ ApplicationWindow { } footer: Spinner { - visible: members.numUsersLoaded < members.memberCount + visible: members.numUsersLoaded < members.memberCount && members.loadingMoreMembers // use the default height if it's visible, otherwise no height at all height: visible ? undefined : 0 anchors.centerIn: parent diff --git a/src/MemberList.cpp b/src/MemberList.cpp index 04377a0f..415e3b57 100644 --- a/src/MemberList.cpp +++ b/src/MemberList.cpp @@ -98,8 +98,14 @@ MemberList::canFetchMore(const QModelIndex &) const void MemberList::fetchMore(const QModelIndex &) { + loadingMoreMembers_ = true; + emit loadingMoreMembersChanged(); + auto members = cache::getMembers(room_id_.toStdString(), rowCount()); addUsers(members); numUsersLoaded_ += members.size(); emit numUsersLoadedChanged(); + + loadingMoreMembers_ = false; + emit loadingMoreMembersChanged(); } diff --git a/src/MemberList.h b/src/MemberList.h index cc3b75f7..070666a2 100644 --- a/src/MemberList.h +++ b/src/MemberList.h @@ -16,6 +16,7 @@ class MemberList : public QAbstractListModel Q_PROPERTY(QString avatarUrl READ avatarUrl NOTIFY avatarUrlChanged) Q_PROPERTY(QString roomId READ roomId NOTIFY roomIdChanged) Q_PROPERTY(int numUsersLoaded READ numUsersLoaded NOTIFY numUsersLoadedChanged) + Q_PROPERTY(bool loadingMoreMembers READ loadingMoreMembers NOTIFY loadingMoreMembersChanged) public: enum Roles @@ -39,6 +40,7 @@ public: QString avatarUrl() const { return QString::fromStdString(info_.avatar_url); } QString roomId() const { return room_id_; } int numUsersLoaded() const { return numUsersLoaded_; } + bool loadingMoreMembers() const { return loadingMoreMembers_; } signals: void roomNameChanged(); @@ -46,6 +48,7 @@ signals: void avatarUrlChanged(); void roomIdChanged(); void numUsersLoadedChanged(); + void loadingMoreMembersChanged(); public slots: void addUsers(const std::vector &users); @@ -59,4 +62,5 @@ private: QString room_id_; RoomInfo info_; int numUsersLoaded_{0}; + bool loadingMoreMembers_{false}; }; -- cgit 1.4.1 From 7cd4e6f1c6fd73edcdeb3cc6918f009d100d2fa1 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 19 Jul 2021 15:05:36 -0400 Subject: make lint --- resources/qml/InviteDialog.qml | 4 ++-- resources/qml/Root.qml | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index b1b1bb39..1eaaef8f 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -72,9 +72,9 @@ ApplicationWindow { Component.onCompleted: forceActiveFocus() Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers & Qt.ControlModifier)) Keys.onPressed: { - if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers === Qt.ControlModifier)) { + if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers === Qt.ControlModifier)) cleanUpAndClose(); - } + } } diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index 0a0f90cf..b5395232 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -141,14 +141,12 @@ Page { }); membersDialog.show(); } - onOpenRoomSettingsDialog: { var roomSettings = roomSettingsComponent.createObject(timelineRoot, { "roomSettings": settings }); roomSettings.show(); } - onOpenInviteUsersDialog: { var dialog = inviteDialog.createObject(timelineRoot, { "roomId": Rooms.currentRoom.roomId, -- cgit 1.4.1 From 6c9ac76260ebdd078c1c4b8d2fdc1eb7caef73c4 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 19 Jul 2021 17:41:47 -0400 Subject: Fix roomId property --- resources/qml/MessageInput.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index 415d67a7..c135aff9 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml @@ -331,7 +331,7 @@ Rectangle { image: ":/icons/icons/ui/sticky-note-solid.svg" ToolTip.visible: hovered ToolTip.text: qsTr("Stickers") - onClicked: stickerPopup.visible ? stickerPopup.close() : stickerPopup.show(stickerButton, room.roomId(), function(row) { + onClicked: stickerPopup.visible ? stickerPopup.close() : stickerPopup.show(stickerButton, room.roomId, function(row) { room.input.sticker(stickerPopup.model.sourceModel, row); TimelineManager.focusMessageInput(); }) -- cgit 1.4.1 From 152acdc4a5eb3604515d1b6b7645446c332de1eb Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 10:10:43 -0400 Subject: Fix hardcoded spacing/padding Another padding fix --- resources/qml/InviteDialog.qml | 4 ++-- resources/qml/RoomMembers.qml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 1eaaef8f..e80087fc 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -47,7 +47,7 @@ ApplicationWindow { ColumnLayout { anchors.fill: parent - anchors.margins: 10 + anchors.margins: Nheko.paddingMedium spacing: Nheko.paddingMedium Label { @@ -106,7 +106,7 @@ ApplicationWindow { } ColumnLayout { - spacing: 5 + spacing: Nheko.paddingSmall Label { text: model.displayName diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index b190be07..11bd486c 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -28,7 +28,7 @@ ApplicationWindow { ColumnLayout { anchors.fill: parent - anchors.margins: 10 + anchors.margins: Nheko.paddingMedium spacing: Nheko.paddingMedium Avatar { @@ -59,7 +59,7 @@ ApplicationWindow { ScrollView { palette: Nheko.colors - padding: 10 + padding: Nheko.paddingMedium ScrollBar.horizontal.visible: false Layout.fillHeight: true Layout.minimumHeight: 200 @@ -69,7 +69,7 @@ ApplicationWindow { id: memberList clip: true - spacing: 8 + spacing: Nheko.paddingMedium boundsBehavior: Flickable.StopAtBounds model: members @@ -92,7 +92,7 @@ ApplicationWindow { } ColumnLayout { - spacing: 5 + spacing: Nheko.paddingSmall Label { text: model.displayName -- cgit 1.4.1 From fa06881c49a48c69223ceac7ad3d06105db9ed50 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 12:53:16 -0400 Subject: Don't hardcode fonts Fix hardcoded fonts (again) --- resources/qml/InviteDialog.qml | 4 ++-- resources/qml/RoomMembers.qml | 6 +++--- resources/qml/RoomSettings.qml | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index e80087fc..d0e6a645 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -111,13 +111,13 @@ ApplicationWindow { Label { text: model.displayName color: TimelineManager.userColor(model ? model.mxid : "", Nheko.colors.window) - font.pointSize: 12 + font.pointSize: fontMetrics.font.pointSize } Label { text: model.mxid color: Nheko.colors.buttonText - font.pointSize: 10 + font.pointSize: fontMetrics.font.pointSize * 0.9 } Item { diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 11bd486c..b9b800c5 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -43,7 +43,7 @@ ApplicationWindow { } Label { - font.pixelSize: 24 + font.pixelSize: fontMetrics.font.pixelSize * 2 text: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + members.roomName Layout.alignment: Qt.AlignHCenter } @@ -97,13 +97,13 @@ ApplicationWindow { Label { text: model.displayName color: TimelineManager.userColor(model ? model.mxid : "", Nheko.colors.window) - font.pointSize: 12 + font.pointSize: fontMetrics.font.pointSize } Label { text: model.mxid color: Nheko.colors.buttonText - font.pointSize: 10 + font.pointSize: fontMetrics.font.pointSize * 0.9 } Item { diff --git a/resources/qml/RoomSettings.qml b/resources/qml/RoomSettings.qml index a27be13e..2701edf9 100644 --- a/resources/qml/RoomSettings.qml +++ b/resources/qml/RoomSettings.qml @@ -98,7 +98,7 @@ ApplicationWindow { MatrixText { text: roomSettings.roomName - font.pixelSize: 24 + font.pixelSize: fontMetrics.font.pixelSize * 2 Layout.alignment: Qt.AlignHCenter } @@ -264,7 +264,7 @@ ApplicationWindow { MatrixText { text: roomSettings.roomId - font.pixelSize: 14 + font.pixelSize: fontMetrics.font.pixelSize * 1.2 Layout.alignment: Qt.AlignRight } @@ -274,7 +274,7 @@ ApplicationWindow { MatrixText { text: roomSettings.roomVersion - font.pixelSize: 14 + font.pixelSize: fontMetrics.font.pixelSize * 1.2 Layout.alignment: Qt.AlignRight } -- cgit 1.4.1 From 75920925dc455157fd4a58f3a1e53b1fc6b86ad7 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 18:04:19 -0400 Subject: Use correct colors --- resources/qml/InviteDialog.qml | 2 ++ resources/qml/RoomMembers.qml | 2 ++ 2 files changed, 4 insertions(+) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index d0e6a645..1be2e06c 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -34,6 +34,8 @@ ApplicationWindow { y: MainWindow.y + (MainWindow.height / 2) - (height / 2) height: 380 width: 340 + palette: Nheko.colors + color: Nheko.colors.window Shortcut { sequence: "Ctrl+Enter" diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index b9b800c5..1cf41e13 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -20,6 +20,8 @@ ApplicationWindow { height: 650 width: 420 minimumHeight: 420 + palette: Nheko.colors + color: Nheko.colors.window Shortcut { sequence: StandardKey.Cancel -- cgit 1.4.1 From 92fdda84236153b31f3c0dcd393c9db146b97b96 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 18:27:16 -0400 Subject: Use elided label --- resources/qml/RoomMembers.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 1cf41e13..09c7391e 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -44,9 +44,9 @@ ApplicationWindow { onClicked: Rooms.currentRoom.openRoomSettings(members.roomId) } - Label { + ElidedLabel { font.pixelSize: fontMetrics.font.pixelSize * 2 - text: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + members.roomName + fullText: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + members.roomName Layout.alignment: Qt.AlignHCenter } -- cgit 1.4.1 From 823e74039698daac8bd45bf13c71b193c60ea226 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 18:27:29 -0400 Subject: Check with regex everywhere --- resources/qml/InviteDialog.qml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 1be2e06c..026e3297 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -15,14 +15,14 @@ ApplicationWindow { property InviteesModel invitees function addInvite() { - if (inviteeEntry.text.match("@.+?:.{3,}")) { + if (inviteeEntry.isValidMxid) { invitees.addUser(inviteeEntry.text); inviteeEntry.clear(); } } function cleanUpAndClose() { - if (inviteeEntry.text.match("@.+?:.{3,}")) + if (inviteeEntry.isValidMxid) addInvite(); invitees.accept(); @@ -63,11 +63,13 @@ ApplicationWindow { MatrixTextField { id: inviteeEntry + property bool isValidMxid: text.match("@.+?:.{3,}") + backgroundColor: Nheko.colors.window placeholderText: qsTr("@joe:matrix.org", "Example user id. The name 'joe' can be localized however you want.") Layout.fillWidth: true onAccepted: { - if (text !== "") + if (isValidMxid) addInvite(); } @@ -82,7 +84,7 @@ ApplicationWindow { Button { text: qsTr("Add") - enabled: inviteeEntry.text.match("@.+?:.{3,}") + enabled: inviteeEntry.isValidMxid onClicked: addInvite() } -- cgit 1.4.1 From 44d2818e0cb2bceb25e29edf7ef32d02ede42432 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 19:17:20 -0400 Subject: Add property for plain room name --- resources/qml/InviteDialog.qml | 4 ++-- resources/qml/Root.qml | 2 +- src/timeline/TimelineModel.cpp | 3 +++ src/timeline/TimelineModel.h | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 026e3297..e9ff475d 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -11,7 +11,7 @@ ApplicationWindow { id: inviteDialogRoot property string roomId - property string roomName + property string plainRoomName property InviteesModel invitees function addInvite() { @@ -29,7 +29,7 @@ ApplicationWindow { close(); } - title: qsTr("Invite users to ") + roomName + title: qsTr("Invite users to ") + plainRoomName x: MainWindow.x + (MainWindow.width / 2) - (width / 2) y: MainWindow.y + (MainWindow.height / 2) - (height / 2) height: 380 diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index b5395232..f71c18e2 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -150,7 +150,7 @@ Page { onOpenInviteUsersDialog: { var dialog = inviteDialog.createObject(timelineRoot, { "roomId": Rooms.currentRoom.roomId, - "roomName": Rooms.currentRoom.roomName, + "plainRoomName": Rooms.currentRoom.plainRoomName, "invitees": invitees }); dialog.show(); diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 7ce0e98a..e431e1ac 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -327,6 +327,9 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj this->isSpace_ = create->content.type == mtx::events::state::room_type::space; this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString()); + // this connection will simplify adding the plainRoomNameChanged() signal everywhere that it needs to be + connect(this, &TimelineModel::roomNameChanged, this, &TimelineModel::plainRoomNameChanged); + connect( this, &TimelineModel::redactionFailed, diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index ebf24bec..0d1eb1f9 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -162,6 +162,7 @@ class TimelineModel : public QAbstractListModel bool paginationInProgress READ paginationInProgress NOTIFY paginationInProgressChanged) Q_PROPERTY(QString roomId READ roomId CONSTANT) Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) + Q_PROPERTY(QString plainRoomName READ plainRoomName NOTIFY plainRoomNameChanged) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) Q_PROPERTY(int roomMemberCount READ roomMemberCount NOTIFY roomMemberCountChanged) @@ -367,6 +368,7 @@ signals: void encryptionChanged(); void roomNameChanged(); + void plainRoomNameChanged(); void roomTopicChanged(); void roomAvatarUrlChanged(); void roomMemberCountChanged(); -- cgit 1.4.1 From 705c283dcb3b5eb1002c699a53f609d1b5c71a9e Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 19:17:31 -0400 Subject: Fix bad connection --- resources/qml/InviteDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index e9ff475d..dbe8bb07 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -106,7 +106,7 @@ ApplicationWindow { userid: model.mxid url: model.avatarUrl.replace("mxc://", "image://MxcImage/") displayName: model.displayName - onClicked: TimelineManager.timeline.openUserProfile(model.mxid) + onClicked: Rooms.currentRoom.openUserProfile(model.mxid) } ColumnLayout { -- cgit 1.4.1 From c78c2848988cd7d0c0bb51209359f6b925d2da34 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 19:17:49 -0400 Subject: Call the correct function --- resources/qml/RoomMembers.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 09c7391e..8431dc99 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -56,7 +56,7 @@ ApplicationWindow { hoverEnabled: true ToolTip.visible: hovered ToolTip.text: qsTr("Invite more people") - onClicked: Rooms.currentRoom.openInviteUsersDialog() + onClicked: Rooms.currentRoom.openInviteUsers() } ScrollView { -- cgit 1.4.1 From 38c6aa65fa3e4230a4e1de9cc8e7e2204d3896ed Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 19:45:28 -0400 Subject: Fix elided width --- resources/qml/RoomMembers.qml | 1 + 1 file changed, 1 insertion(+) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 8431dc99..6f847ccc 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -48,6 +48,7 @@ ApplicationWindow { font.pixelSize: fontMetrics.font.pixelSize * 2 fullText: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + members.roomName Layout.alignment: Qt.AlignHCenter + elideWidth: parent.width - Nheko.paddingMedium } ImageButton { -- cgit 1.4.1 From d33538316c81b548e9b6724afc3486c17ad925f2 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 20 Jul 2021 19:57:36 -0400 Subject: Fix the loading spinner setup This fixes binding loops and gives it a (in my opinion) sane size. --- resources/qml/RoomMembers.qml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 6f847ccc..3758cb0b 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -118,11 +118,21 @@ ApplicationWindow { } - footer: Spinner { - visible: members.numUsersLoaded < members.memberCount && members.loadingMoreMembers + footer: Item { + width: parent.width + visible: (members.numUsersLoaded < members.memberCount) && members.loadingMoreMembers + // use the default height if it's visible, otherwise no height at all - height: visible ? undefined : 0 - anchors.centerIn: parent + height: membersLoadingSpinner.height + anchors.margins: Nheko.paddingMedium + + Spinner { + id: membersLoadingSpinner + + anchors.centerIn: parent + height: visible ? 35 : 0 + } + } } -- cgit 1.4.1 From 5e85fa606ea800dd524547dd1eb9019498b3929e Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 21 Jul 2021 13:55:29 +0200 Subject: Fix color of invite label --- resources/qml/InviteDialog.qml | 1 + 1 file changed, 1 insertion(+) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index dbe8bb07..c6b42d29 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -55,6 +55,7 @@ ApplicationWindow { Label { text: qsTr("User ID to invite") Layout.fillWidth: true + color: Nheko.colors.text } RowLayout { -- cgit 1.4.1 From b17002929c2e968835b510bd47c02d9df2461bc3 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Wed, 21 Jul 2021 10:08:04 -0400 Subject: Open room members when member info label clicked --- resources/qml/RoomSettings.qml | 12 +++++++++++- src/MemberList.cpp | 2 +- src/MemberList.h | 2 +- src/timeline/TimelineModel.cpp | 4 ++-- src/timeline/TimelineModel.h | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomSettings.qml b/resources/qml/RoomSettings.qml index 2701edf9..8746d4d3 100644 --- a/resources/qml/RoomSettings.qml +++ b/resources/qml/RoomSettings.qml @@ -4,7 +4,7 @@ import "./ui" import Qt.labs.platform 1.1 as Platform -import QtQuick 2.9 +import QtQuick 2.15 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 import QtQuick.Window 2.3 @@ -105,6 +105,16 @@ ApplicationWindow { MatrixText { text: qsTr("%1 member(s)").arg(roomSettings.memberCount) Layout.alignment: Qt.AlignHCenter + + TapHandler { + onTapped: Rooms.currentRoom.openRoomMembers(roomSettings.roomId) + } + + CursorShape { + cursorShape: Qt.PointingHandCursor + anchors.fill: parent + } + } } diff --git a/src/MemberList.cpp b/src/MemberList.cpp index 415e3b57..0ef3b696 100644 --- a/src/MemberList.cpp +++ b/src/MemberList.cpp @@ -22,7 +22,7 @@ #include "timeline/TimelineViewManager.h" #include "ui/Avatar.h" -MemberList::MemberList(const QString &room_id, QWidget *parent) +MemberList::MemberList(const QString &room_id, QObject *parent) : QAbstractListModel{parent} , room_id_{room_id} { diff --git a/src/MemberList.h b/src/MemberList.h index 070666a2..9932f6a4 100644 --- a/src/MemberList.h +++ b/src/MemberList.h @@ -25,7 +25,7 @@ public: DisplayName, AvatarUrl, }; - MemberList(const QString &room_id, QWidget *parent = nullptr); + MemberList(const QString &room_id, QObject *parent = nullptr); QHash roleNames() const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 66d931fd..e9fa4a05 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -1067,9 +1067,9 @@ TimelineModel::openUserProfile(QString userid) } void -TimelineModel::openRoomMembers() +TimelineModel::openRoomMembers(QString room_id) { - MemberList *memberList = new MemberList(roomId()); + MemberList *memberList = new MemberList(room_id == QString() ? roomId() : room_id, this); emit openRoomMembersDialog(memberList); } diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 0d1eb1f9..077245cb 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -239,7 +239,7 @@ public: Q_INVOKABLE void forwardMessage(QString eventId, QString roomId); Q_INVOKABLE void viewDecryptedRawMessage(QString id) const; Q_INVOKABLE void openUserProfile(QString userid); - Q_INVOKABLE void openRoomMembers(); + Q_INVOKABLE void openRoomMembers(QString room_id = QString()); Q_INVOKABLE void openRoomSettings(QString room_id = QString()); Q_INVOKABLE void openInviteUsers(QString roomId = QString()); Q_INVOKABLE void editAction(QString id); -- cgit 1.4.1 From d6ccb6e307aaacdab073f0fa6eb3fa6e269a7644 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 21 Jul 2021 19:13:34 +0200 Subject: Update translations --- resources/langs/nheko_cs.ts | 251 ++++++++++++++++++++++++---------------- resources/langs/nheko_de.ts | 250 ++++++++++++++++++++++++---------------- resources/langs/nheko_el.ts | 248 ++++++++++++++++++++++++---------------- resources/langs/nheko_en.ts | 252 +++++++++++++++++++++++++---------------- resources/langs/nheko_eo.ts | 250 ++++++++++++++++++++++++---------------- resources/langs/nheko_es.ts | 250 ++++++++++++++++++++++++---------------- resources/langs/nheko_et.ts | 252 +++++++++++++++++++++++++---------------- resources/langs/nheko_fi.ts | 250 ++++++++++++++++++++++++---------------- resources/langs/nheko_fr.ts | 250 ++++++++++++++++++++++++---------------- resources/langs/nheko_hu.ts | 251 ++++++++++++++++++++++++---------------- resources/langs/nheko_it.ts | 250 ++++++++++++++++++++++++---------------- resources/langs/nheko_ja.ts | 249 ++++++++++++++++++++++++---------------- resources/langs/nheko_ml.ts | 252 +++++++++++++++++++++++++---------------- resources/langs/nheko_nl.ts | 248 ++++++++++++++++++++++++---------------- resources/langs/nheko_pl.ts | 251 ++++++++++++++++++++++++---------------- resources/langs/nheko_pt_BR.ts | 250 ++++++++++++++++++++++++---------------- resources/langs/nheko_pt_PT.ts | 250 ++++++++++++++++++++++++---------------- resources/langs/nheko_ro.ts | 251 ++++++++++++++++++++++++---------------- resources/langs/nheko_ru.ts | 251 ++++++++++++++++++++++++---------------- resources/langs/nheko_si.ts | 248 ++++++++++++++++++++++++---------------- resources/langs/nheko_sv.ts | 252 +++++++++++++++++++++++++---------------- resources/langs/nheko_zh_CN.ts | 249 ++++++++++++++++++++++++---------------- resources/qml/InviteDialog.qml | 2 +- resources/qml/RoomMembers.qml | 4 +- 24 files changed, 3328 insertions(+), 2183 deletions(-) (limited to 'resources/qml') diff --git a/resources/langs/nheko_cs.ts b/resources/langs/nheko_cs.ts index c544bf6d..7c1134aa 100644 --- a/resources/langs/nheko_cs.ts +++ b/resources/langs/nheko_cs.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation @@ -48,7 +48,7 @@ - + Cancel @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file @@ -617,16 +617,42 @@ - + Failed to upload media. Please try again. - InviteeItem + InviteDialog - - Remove + + Invite users to %1 + + + + + User ID to invite + + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + + + + Cancel @@ -740,28 +766,15 @@ Example: https://server.my:8787 - - MemberList - - - Room members - - - - - OK - - - MessageDelegate - + Encryption enabled - + room name changed to: %1 @@ -771,7 +784,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -781,17 +794,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -806,23 +819,23 @@ Example: https://server.my:8787 - + Negotiating call... - + %1 answered the call. - + removed - + %1 ended the call. @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -888,7 +906,7 @@ Example: https://server.my:8787 - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - - - - - Decline - - - - + Status Message @@ -1337,20 +1345,43 @@ Example: https://server.my:8787 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1463,6 @@ Example: https://server.my:8787 Room Version - - - OK - - Failed to enable encryption: %1 @@ -1469,6 +1495,24 @@ Example: https://server.my:8787 + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1570,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1590,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + + + Success @@ -1567,7 +1619,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1578,7 +1630,7 @@ Example: https://server.my:8787 - + Save image @@ -1713,12 +1765,12 @@ Example: https://server.my:8787 - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1747,7 +1799,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1755,17 +1807,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1773,7 +1840,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1781,18 +1848,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1833,7 +1899,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1843,7 +1909,7 @@ Example: https://server.my:8787 - + Verify @@ -1892,7 +1958,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1901,7 +1967,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2347,7 +2413,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2398,7 +2464,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2469,19 +2535,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - - - - - User ID to invite - - - dialogs::JoinRoom diff --git a/resources/langs/nheko_de.ts b/resources/langs/nheko_de.ts index 58c209a2..3cd35781 100644 --- a/resources/langs/nheko_de.ts +++ b/resources/langs/nheko_de.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Auf Bestätigung warten @@ -48,7 +48,7 @@ Wartet darauf, dass die andere Seite die Verifizierung abschließt. - + Cancel Abbrechen @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Nutzer konnte nicht eingeladen werden: %1 @@ -157,12 +157,12 @@ - + Confirm invite Einladung bestätigen - + Do you really want to invite %1 (%2)? Nutzer %1 (%2) wirklich einladen? @@ -227,12 +227,12 @@ Verbannung aufgehoben: %1 - + Do you really want to start a private chat with %1? Möchtest du wirklich eine private Konversation mit %1 beginnen? - + Cache migration failed! Migration des Caches fehlgeschlagen! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets Geheimnisse entschlüsseln @@ -426,12 +426,12 @@ EmojiPicker - + Search Suche - + People Leute @@ -607,7 +607,7 @@ InputBar - + Select a file Datei auswählen @@ -617,17 +617,43 @@ Alle Dateien (*) - + Failed to upload media. Please try again. Medienupload fehlgeschlagen. Bitte versuche es erneut. - InviteeItem + InviteDialog + + + Invite users to %1 + Lade Benutzer in %1 ein + + + + User ID to invite + Benutzer-ID, die eingeladen werden soll + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + @joe:matrix.org + + + + Add + Hinzufügen + - - Remove - Löschen + + Invite + Einladen + + + + Cancel + Abbrechen @@ -744,23 +770,10 @@ Beispiel: https://mein.server:8787 SSO Anmeldung fehlgeschlagen - - MemberList - - - Room members - Teilnehmerliste - - - - OK - OK - - MessageDelegate - + removed entfernt @@ -771,7 +784,7 @@ Beispiel: https://mein.server:8787 Verschlüsselung aktiviert - + room name changed to: %1 Raumname wurde gändert auf: %1 @@ -781,7 +794,7 @@ Beispiel: https://mein.server:8787 Raumname wurde entfernt - + topic changed to: %1 Raumthema wurde geändert auf: %1 @@ -791,17 +804,17 @@ Beispiel: https://mein.server:8787 Thema wurde entfernt - + %1 changed the room avatar %1 hat dem Raumavatar geändert - + %1 created and configured room: %2 %1 hat den Raum erstellt: %2 - + %1 placed a voice call. %1 hat einen Sprachanruf gestartet. @@ -816,17 +829,17 @@ Beispiel: https://mein.server:8787 %1 hat angerufen. - + %1 answered the call. %1 hat den Anruf angenommen. - + %1 ended the call. %1 hat den Anruf beendet. - + Negotiating call... Wählt… @@ -834,7 +847,7 @@ Beispiel: https://mein.server:8787 MessageInput - + Hang up Auflegen @@ -855,6 +868,11 @@ Beispiel: https://mein.server:8787 + Stickers + Sticker + + + Emoji Emoji @@ -872,17 +890,17 @@ Beispiel: https://mein.server:8787 MessageView - + Edit Bearbeiten - + React Reaktion senden - + Reply Antworten @@ -892,7 +910,7 @@ Beispiel: https://mein.server:8787 Optionen - + &Copy &Kopieren @@ -1100,7 +1118,7 @@ Beispiel: https://mein.server:8787 Placeholder - + unimplemented event: Unimplementiertes Event: @@ -1220,7 +1238,7 @@ Beispiel: https://mein.server:8787 ReplyPopup - + Close Schließen @@ -1233,7 +1251,7 @@ Beispiel: https://mein.server:8787 RoomInfo - + no version stored keine Version gespeichert @@ -1241,7 +1259,7 @@ Beispiel: https://mein.server:8787 RoomList - + New tag Neuer Tag @@ -1281,17 +1299,7 @@ Beispiel: https://mein.server:8787 Neuen Tag erstellen... - - Accept - Akzeptieren - - - - Decline - Ablehnen - - - + Status Message Statusnachricht @@ -1341,20 +1349,42 @@ Beispiel: https://mein.server:8787 Benutzereinstellungen + + RoomMembers + + + Members of %1 + Teilnehmer in %1 + + + + %n people in %1 + Summary above list of members + + %n Person in %1 + %n Personen in %1 + + + + + Invite more people + Lade mehr Leute ein + + RoomSettings - + Room Settings Raumeinstellungen - + %1 member(s) %1 Teilnehmer - + SETTINGS EINSTELLUNGEN @@ -1436,11 +1466,6 @@ Beispiel: https://mein.server:8787 Room Version Raumversion - - - OK - OK - Failed to enable encryption: %1 @@ -1473,6 +1498,24 @@ Beispiel: https://mein.server:8787 Hochladen des Bildes fehlgeschlagen: %s + + RoomlistModel + + + Pending invite. + Offene Einladung. + + + + Previewing this room + Vorschau dieses Raums + + + + No preview available + Keine Vorschau verfügbar + + ScreenShare @@ -1530,7 +1573,7 @@ Beispiel: https://mein.server:8787 StatusIndicator - + Failed Fehlgeschlagen @@ -1550,6 +1593,14 @@ Beispiel: https://mein.server:8787 Gelesen + + StickerPicker + + + Search + Suche + + Success @@ -1571,7 +1622,7 @@ Beispiel: https://mein.server:8787 TimelineModel - + Message redaction failed: %1 Nachricht zurückziehen fehlgeschlagen: %1 @@ -1582,7 +1633,7 @@ Beispiel: https://mein.server:8787 Event konnte nicht verschlüsselt werden, senden wurde abgebrochen! - + Save image Bild speichern @@ -1716,12 +1767,12 @@ Beispiel: https://mein.server:8787 %1 hat das Anklopfen zurückgezogen. - + You joined this room. Du bist dem Raum beigetreten. - + %1 has changed their avatar and changed their display name to %2. %1 hat den eigenen Avatar und Namen geändert zu %2. @@ -1750,7 +1801,7 @@ Beispiel: https://mein.server:8787 TimelineRow - + Edited Bearbeitet @@ -1758,17 +1809,32 @@ Beispiel: https://mein.server:8787 TimelineView - + No room open Kein Raum geöffnet - + %1 member(s) %1 Teilnehmer - + + join the conversation + An der Unterhaltung teilnehmen + + + + accept invite + Einladung annehmen + + + + decline invite + Einladung ablehnen + + + Back to room list Zurück zur Raumliste @@ -1776,7 +1842,7 @@ Beispiel: https://mein.server:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Keinen verschlüsselten Chat mit diesem User gefunden. Erstelle einen verschlüsselten 1:1 Chat mit diesem Nutzer und versuche es erneut. @@ -1784,18 +1850,17 @@ Beispiel: https://mein.server:8787 TopBar - + Back to room list Zurück zur Raumliste - - + No room selected Kein Raum ausgewählt - + Room options Raumoptionen @@ -1836,7 +1901,7 @@ Beispiel: https://mein.server:8787 UserProfile - + Global User Profile Globales Nutzerprofil @@ -1846,7 +1911,7 @@ Beispiel: https://mein.server:8787 Raumspezifisches Nutzerprofil - + Verify Verifizieren @@ -1895,7 +1960,7 @@ Beispiel: https://mein.server:8787 UserSettings - + Default Standard @@ -1904,7 +1969,7 @@ Beispiel: https://mein.server:8787 UserSettingsPage - + Minimize to tray Ins Benachrichtigungsfeld minimieren @@ -2360,7 +2425,7 @@ Normalerweise animiert das den Taskbaricon oder färbt das Fenster orange ein. Waiting - + Waiting for other party… Auf Gegenseite warten… @@ -2411,7 +2476,7 @@ Normalerweise animiert das den Taskbaricon oder färbt das Fenster orange ein. descriptiveTime - + Yesterday Gestern @@ -2482,19 +2547,6 @@ Normalerweise animiert das den Taskbaricon oder färbt das Fenster orange ein.Öffne das Fallback, folge den Anweisungen und bestätige nach Abschluss via "Bestätigen". - - dialogs::InviteUsers - - - Cancel - Abbrechen - - - - User ID to invite - Benutzer-ID, die eingeladen werden soll - - dialogs::JoinRoom diff --git a/resources/langs/nheko_el.ts b/resources/langs/nheko_el.ts index d5d5f323..6df73f73 100644 --- a/resources/langs/nheko_el.ts +++ b/resources/langs/nheko_el.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation @@ -48,7 +48,7 @@ - + Cancel Άκυρο @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file Διάλεξε ένα αρχείο @@ -617,18 +617,44 @@ Όλα τα αρχεία (*) - + Failed to upload media. Please try again. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + Όνομα χρήστη + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + - - Remove + + Invite + + + Cancel + Άκυρο + LoginPage @@ -740,23 +766,10 @@ Example: https://server.my:8787 - - MemberList - - - Room members - Μέλη - - - - OK - - - MessageDelegate - + removed @@ -767,7 +780,7 @@ Example: https://server.my:8787 - + room name changed to: %1 @@ -777,7 +790,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -787,17 +800,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -812,17 +825,17 @@ Example: https://server.my:8787 - + %1 answered the call. - + %1 ended the call. - + Negotiating call... @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -888,7 +906,7 @@ Example: https://server.my:8787 - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - Αποδοχή - - - - Decline - Απόρριψη - - - + Status Message @@ -1337,20 +1345,42 @@ Example: https://server.my:8787 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1462,6 @@ Example: https://server.my:8787 Room Version - - - OK - - Failed to enable encryption: %1 @@ -1469,6 +1494,24 @@ Example: https://server.my:8787 + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1569,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1589,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + + + Success @@ -1567,7 +1618,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1578,7 +1629,7 @@ Example: https://server.my:8787 - + Save image Αποθήκευση Εικόνας @@ -1712,12 +1763,12 @@ Example: https://server.my:8787 - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1746,7 +1797,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1754,17 +1805,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1772,7 +1838,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1780,18 +1846,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1832,7 +1897,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1842,7 +1907,7 @@ Example: https://server.my:8787 - + Verify @@ -1891,7 +1956,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1900,7 +1965,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Ελαχιστοποίηση @@ -2346,7 +2411,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2397,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2468,19 +2533,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - Άκυρο - - - - User ID to invite - Όνομα χρήστη - - dialogs::JoinRoom diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts index 7d3f8276..97a67b06 100644 --- a/resources/langs/nheko_en.ts +++ b/resources/langs/nheko_en.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Awaiting Confirmation @@ -48,7 +48,7 @@ Waiting for other side to complete verification. - + Cancel Cancel @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Failed to invite user: %1 @@ -157,12 +157,12 @@ - + Confirm invite Confirm invite - + Do you really want to invite %1 (%2)? Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ Unbanned user: %1 - + Do you really want to start a private chat with %1? Do you really want to start a private chat with %1? - + Cache migration failed! Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search Search - + People People @@ -607,7 +607,7 @@ InputBar - + Select a file Select a file @@ -617,17 +617,43 @@ All Files (*) - + Failed to upload media. Please try again. Failed to upload media. Please try again. - InviteeItem + InviteDialog + + + Invite users to %1 + Invite users to %1 + + + + User ID to invite + User ID to invite + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + @joe:matrix.org + + + + Add + Add + - - Remove - Remove + + Invite + Invite + + + + Cancel + Cancel @@ -744,28 +770,15 @@ Example: https://server.my:8787 SSO login failed - - MemberList - - - Room members - Room members - - - - OK - OK - - MessageDelegate - + Encryption enabled Encryption enabled - + room name changed to: %1 room name changed to: %1 @@ -775,7 +788,7 @@ Example: https://server.my:8787 removed room name - + topic changed to: %1 topic changed to: %1 @@ -785,17 +798,17 @@ Example: https://server.my:8787 removed topic - + %1 changed the room avatar %1 changed the room avatar - + %1 created and configured room: %2 %1 created and configured room: %2 - + %1 placed a voice call. %1 placed a voice call. @@ -810,23 +823,23 @@ Example: https://server.my:8787 %1 placed a call. - + Negotiating call... Negotiating call… - + %1 answered the call. %1 answered the call. - + removed removed - + %1 ended the call. %1 ended the call. @@ -834,7 +847,7 @@ Example: https://server.my:8787 MessageInput - + Hang up Hang up @@ -855,6 +868,11 @@ Example: https://server.my:8787 + Stickers + Stickers + + + Emoji Emoji @@ -872,17 +890,17 @@ Example: https://server.my:8787 MessageView - + Edit Edit - + React React - + Reply Reply @@ -892,7 +910,7 @@ Example: https://server.my:8787 Options - + &Copy &Copy @@ -1100,7 +1118,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: unimplemented event: @@ -1220,7 +1238,7 @@ Example: https://server.my:8787 ReplyPopup - + Close Close @@ -1233,7 +1251,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored no version stored @@ -1241,7 +1259,7 @@ Example: https://server.my:8787 RoomList - + New tag New tag @@ -1281,17 +1299,7 @@ Example: https://server.my:8787 Create new tag... - - Accept - Accept - - - - Decline - Decline - - - + Status Message Status Message @@ -1341,20 +1349,42 @@ Example: https://server.my:8787 User settings + + RoomMembers + + + Members of %1 + Members of %1 + + + + %n people in %1 + Summary above list of members + + %n person in %1 + %n people in %1 + + + + + Invite more people + Invite more people + + RoomSettings - + Room Settings Room Settings - + %1 member(s) %1 member(s) - + SETTINGS SETTINGS @@ -1438,11 +1468,6 @@ E2E implementation until device verification is completed. Room Version Room Version - - - OK - OK - Failed to enable encryption: %1 @@ -1475,6 +1500,24 @@ E2E implementation until device verification is completed. Failed to upload image: %s + + RoomlistModel + + + Pending invite. + Pending invite. + + + + Previewing this room + Previewing this room + + + + No preview available + No preview available + + ScreenShare @@ -1532,7 +1575,7 @@ E2E implementation until device verification is completed. StatusIndicator - + Failed Failed @@ -1552,6 +1595,14 @@ E2E implementation until device verification is completed. Read + + StickerPicker + + + Search + Search + + Success @@ -1573,7 +1624,7 @@ E2E implementation until device verification is completed. TimelineModel - + Message redaction failed: %1 Message redaction failed: %1 @@ -1584,7 +1635,7 @@ E2E implementation until device verification is completed. Failed to encrypt event, sending aborted! - + Save image Save image @@ -1718,12 +1769,12 @@ E2E implementation until device verification is completed. %1 redacted their knock. - + You joined this room. You joined this room. - + %1 has changed their avatar and changed their display name to %2. %1 has changed their avatar and changed their display name to %2. @@ -1752,7 +1803,7 @@ E2E implementation until device verification is completed. TimelineRow - + Edited Edited @@ -1760,17 +1811,32 @@ E2E implementation until device verification is completed. TimelineView - + No room open No room open - + %1 member(s) %1 member(s) - + + join the conversation + join the conversation + + + + accept invite + accept invite + + + + decline invite + decline invite + + + Back to room list Back to room list @@ -1778,7 +1844,7 @@ E2E implementation until device verification is completed. TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1786,18 +1852,17 @@ E2E implementation until device verification is completed. TopBar - + Back to room list Back to room list - - + No room selected No room selected - + Room options Room options @@ -1838,7 +1903,7 @@ E2E implementation until device verification is completed. UserProfile - + Global User Profile Global User Profile @@ -1848,7 +1913,7 @@ E2E implementation until device verification is completed. Room User Profile - + Verify Verify @@ -1897,7 +1962,7 @@ E2E implementation until device verification is completed. UserSettings - + Default Default @@ -1906,7 +1971,7 @@ E2E implementation until device verification is completed. UserSettingsPage - + Minimize to tray Minimize to tray @@ -2363,7 +2428,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… Waiting for other party… @@ -2414,7 +2479,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Yesterday @@ -2485,19 +2550,6 @@ This usually causes the application icon in the task bar to animate in some fash Open the fallback, follow the steps and confirm after completing them. - - dialogs::InviteUsers - - - Cancel - Cancel - - - - User ID to invite - User ID to invite - - dialogs::JoinRoom diff --git a/resources/langs/nheko_eo.ts b/resources/langs/nheko_eo.ts index 26a67d49..f3529f28 100644 --- a/resources/langs/nheko_eo.ts +++ b/resources/langs/nheko_eo.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Atendante konfirmon @@ -48,7 +48,7 @@ Atendante kontrolon venontan de la alia flanko. - + Cancel Nuligi @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Malsukcesis inviti uzanton: %1 @@ -158,12 +158,12 @@ - + Confirm invite Konfirmu inviton - + Do you really want to invite %1 (%2)? Ĉu vi certe volas inviti uzanton %1 (%2)? @@ -228,12 +228,12 @@ Malforbaris uzanton: %1 - + Do you really want to start a private chat with %1? Ĉu vi certe volas komenci privatan babilon kun %1? - + Cache migration failed! Malsukcesis migrado de kaŝmemoro! @@ -353,7 +353,7 @@ CrossSigningSecrets - + Decrypt secrets Malĉifri sekretojn @@ -427,12 +427,12 @@ EmojiPicker - + Search Serĉu - + People Homoj @@ -608,7 +608,7 @@ InputBar - + Select a file Elektu dosieron @@ -618,17 +618,43 @@ Ĉiuj dosieroj (*) - + Failed to upload media. Please try again. Malsukcesis alŝuti vidaŭdaĵojn. Bonvolu reprovi. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + - - Remove - Forigi + + Cancel + Nuligi @@ -747,23 +773,10 @@ Ekzemplo: https://servilo.mia:8787 Malsukcesis ununura saluto - - MemberList - - - Room members - Membroj de la ĉambro - - - - OK - Bone - - MessageDelegate - + removed forigita @@ -774,7 +787,7 @@ Ekzemplo: https://servilo.mia:8787 - + room name changed to: %1 Nomo da ĉambro ŝanĝiĝis al: %1 @@ -784,7 +797,7 @@ Ekzemplo: https://servilo.mia:8787 - + topic changed to: %1 @@ -794,17 +807,17 @@ Ekzemplo: https://servilo.mia:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. %1 metis voĉvokon. @@ -819,17 +832,17 @@ Ekzemplo: https://servilo.mia:8787 %1 metis vokon. - + %1 answered the call. %1 respondis la vokon. - + %1 ended the call. %1 finis la vokon. - + Negotiating call... Traktante vokon… @@ -837,7 +850,7 @@ Ekzemplo: https://servilo.mia:8787 MessageInput - + Hang up @@ -858,6 +871,11 @@ Ekzemplo: https://servilo.mia:8787 + Stickers + + + + Emoji Bildosignoj @@ -875,17 +893,17 @@ Ekzemplo: https://servilo.mia:8787 MessageView - + Edit Redakti - + React Reagi - + Reply Respondi @@ -895,7 +913,7 @@ Ekzemplo: https://servilo.mia:8787 Elektebloj - + &Copy @@ -1103,7 +1121,7 @@ Ekzemplo: https://servilo.mia:8787 Placeholder - + unimplemented event: neprogramita okazo: @@ -1223,7 +1241,7 @@ Ekzemplo: https://servilo.mia:8787 ReplyPopup - + Close Fermi @@ -1236,7 +1254,7 @@ Ekzemplo: https://servilo.mia:8787 RoomInfo - + no version stored @@ -1244,7 +1262,7 @@ Ekzemplo: https://servilo.mia:8787 RoomList - + New tag @@ -1284,17 +1302,7 @@ Ekzemplo: https://servilo.mia:8787 - - Accept - Akcepti - - - - Decline - Rifuzi - - - + Status Message @@ -1344,20 +1352,42 @@ Ekzemplo: https://servilo.mia:8787 Agordoj de uzanto + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings Agordoj de ĉambro - + %1 member(s) %1 ĉambrano(j) - + SETTINGS AGORDOJ @@ -1439,11 +1469,6 @@ Ekzemplo: https://servilo.mia:8787 Room Version Versio de ĉambro - - - OK - Bone - Failed to enable encryption: %1 @@ -1476,6 +1501,24 @@ Ekzemplo: https://servilo.mia:8787 Malsukcesis alŝuti bildon: %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1533,7 +1576,7 @@ Ekzemplo: https://servilo.mia:8787 StatusIndicator - + Failed Estas malsukcesa @@ -1554,6 +1597,14 @@ Ekzemplo: https://servilo.mia:8787 Estas legita + + StickerPicker + + + Search + Serĉu + + Success @@ -1575,7 +1626,7 @@ Ekzemplo: https://servilo.mia:8787 TimelineModel - + Message redaction failed: %1 @@ -1586,7 +1637,7 @@ Ekzemplo: https://servilo.mia:8787 - + Save image Konservi bildon @@ -1722,12 +1773,12 @@ Ekzemplo: https://servilo.mia:8787 - + You joined this room. Vi aliĝis ĉi tiun ĉambron. - + %1 has changed their avatar and changed their display name to %2. @@ -1756,7 +1807,7 @@ Ekzemplo: https://servilo.mia:8787 TimelineRow - + Edited Redaktita @@ -1764,17 +1815,32 @@ Ekzemplo: https://servilo.mia:8787 TimelineView - + No room open - + %1 member(s) %1 ĉambrano(j) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1782,7 +1848,7 @@ Ekzemplo: https://servilo.mia:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1790,18 +1856,17 @@ Ekzemplo: https://servilo.mia:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1842,7 +1907,7 @@ Ekzemplo: https://servilo.mia:8787 UserProfile - + Global User Profile @@ -1852,7 +1917,7 @@ Ekzemplo: https://servilo.mia:8787 - + Verify @@ -1901,7 +1966,7 @@ Ekzemplo: https://servilo.mia:8787 UserSettings - + Default @@ -1910,7 +1975,7 @@ Ekzemplo: https://servilo.mia:8787 UserSettingsPage - + Minimize to tray @@ -2373,7 +2438,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2425,7 +2490,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Hieraŭ @@ -2496,19 +2561,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - Nuligi - - - - User ID to invite - - - dialogs::JoinRoom diff --git a/resources/langs/nheko_es.ts b/resources/langs/nheko_es.ts index 6318b9c4..8eb4675a 100644 --- a/resources/langs/nheko_es.ts +++ b/resources/langs/nheko_es.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Esperando confirmación @@ -48,7 +48,7 @@ Esperando a que la otra parte complete la verificación. - + Cancel Cancelar @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 No se pudo invitar al usuario: %1 @@ -157,12 +157,12 @@ - + Confirm invite Confirmar invitación - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file @@ -617,18 +617,44 @@ - + Failed to upload media. Please try again. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + - - Remove + + Invite + + + Cancel + Cancelar + LoginPage @@ -740,28 +766,15 @@ Example: https://server.my:8787 - - MemberList - - - Room members - - - - - OK - - - MessageDelegate - + Encryption enabled - + room name changed to: %1 @@ -771,7 +784,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -781,17 +794,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -806,23 +819,23 @@ Example: https://server.my:8787 - + Negotiating call... - + %1 answered the call. - + removed - + %1 ended the call. @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -888,7 +906,7 @@ Example: https://server.my:8787 - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - Aceptar - - - - Decline - Rechazar - - - + Status Message @@ -1337,20 +1345,42 @@ Example: https://server.my:8787 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1462,6 @@ Example: https://server.my:8787 Room Version - - - OK - - Failed to enable encryption: %1 @@ -1469,6 +1494,24 @@ Example: https://server.my:8787 + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1569,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1589,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + + + Success @@ -1567,7 +1618,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1578,7 +1629,7 @@ Example: https://server.my:8787 - + Save image @@ -1722,12 +1773,12 @@ Example: https://server.my:8787 - + You joined this room. Te has unido a esta sala. - + Rejected the knock from %1. @@ -1746,7 +1797,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1754,17 +1805,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1772,7 +1838,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1780,18 +1846,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1832,7 +1897,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1842,7 +1907,7 @@ Example: https://server.my:8787 - + Verify @@ -1891,7 +1956,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1900,7 +1965,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2346,7 +2411,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2397,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2468,19 +2533,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - Cancelar - - - - User ID to invite - - - dialogs::JoinRoom diff --git a/resources/langs/nheko_et.ts b/resources/langs/nheko_et.ts index 198ec332..20261395 100644 --- a/resources/langs/nheko_et.ts +++ b/resources/langs/nheko_et.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Ootan kinnitust @@ -48,7 +48,7 @@ Ootan et teine osapool lõpetaks verifitseerimise. - + Cancel Katkesta @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Kutse saatmine kasutajale ei õnnestunud: %1 @@ -157,12 +157,12 @@ - + Confirm invite Kinnita kutse - + Do you really want to invite %1 (%2)? Kas sa tõesti soovid saata kutset kasutajale %1 (%2)? @@ -227,12 +227,12 @@ Suhtluskeeld eemaldatud: %1 - + Do you really want to start a private chat with %1? Kas sa kindlasti soovid alustada otsevestlust kasutajaga %1? - + Cache migration failed! Puhvri versiooniuuendus ebaõnnestus! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets Dekrüpti andmed @@ -426,12 +426,12 @@ EmojiPicker - + Search Otsi - + People Inimesed @@ -607,7 +607,7 @@ InputBar - + Select a file Vali fail @@ -617,17 +617,43 @@ Kõik failid (*) - + Failed to upload media. Please try again. Meediafailide üleslaadimine ei õnnestunud. Palun proovi uuesti. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + Kasutajatunnus, kellele soovid kutset saata + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + - - Remove - Eemalda + + Invite + + + + + Cancel + @@ -744,28 +770,15 @@ Näiteks: https://server.minu:8787 Ühekordne sisselogimine ei õnnestunud - - MemberList - - - Room members - Jututoa liikmed - - - - OK - Sobib - - MessageDelegate - + Encryption enabled Krüptimine on kasutusel - + room name changed to: %1 jututoa uus nimi on: %1 @@ -775,7 +788,7 @@ Näiteks: https://server.minu:8787 eemaldas jututoa nime - + topic changed to: %1 jututoa uus teema on: %1 @@ -785,17 +798,17 @@ Näiteks: https://server.minu:8787 teema on eemaldatud - + %1 changed the room avatar %1 muutis jututoa tunnuspilti - + %1 created and configured room: %2 %1 lõi ja seadistas jututoa: %2 - + %1 placed a voice call. %1 helistas. @@ -810,23 +823,23 @@ Näiteks: https://server.minu:8787 %1 helistas. - + Negotiating call... Ühendan kõnet… - + %1 answered the call. %1 vastas kõnele. - + removed eemaldatud - + %1 ended the call. %1 lõpetas kõne. @@ -834,7 +847,7 @@ Näiteks: https://server.minu:8787 MessageInput - + Hang up Lõpeta kõne @@ -855,6 +868,11 @@ Näiteks: https://server.minu:8787 + Stickers + + + + Emoji Emoji @@ -872,17 +890,17 @@ Näiteks: https://server.minu:8787 MessageView - + Edit Muuda - + React Reageeri - + Reply Vasta @@ -892,7 +910,7 @@ Näiteks: https://server.minu:8787 Valikud - + &Copy &Kopeeri @@ -1100,7 +1118,7 @@ Näiteks: https://server.minu:8787 Placeholder - + unimplemented event: implementeerimata sündmus: @@ -1220,7 +1238,7 @@ Näiteks: https://server.minu:8787 ReplyPopup - + Close Sulge @@ -1233,7 +1251,7 @@ Näiteks: https://server.minu:8787 RoomInfo - + no version stored salvestatud versiooni ei leidu @@ -1241,7 +1259,7 @@ Näiteks: https://server.minu:8787 RoomList - + New tag Uus silt @@ -1281,17 +1299,7 @@ Näiteks: https://server.minu:8787 Loo uus silt... - - Accept - Nõustu - - - - Decline - Keeldu - - - + Status Message Olekuteade @@ -1341,20 +1349,42 @@ Näiteks: https://server.minu:8787 Kasutaja seadistused + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings Jututoa seadistused - + %1 member(s) %1 liige(t) - + SETTINGS SEADISTUSED @@ -1438,11 +1468,6 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Room Version Jututoa versioon - - - OK - Sobib - Failed to enable encryption: %1 @@ -1475,6 +1500,24 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Viga faili üleslaadimisel: %1 + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1532,7 +1575,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< StatusIndicator - + Failed Ebaõnnestus @@ -1552,6 +1595,14 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Loetud + + StickerPicker + + + Search + Otsi + + Success @@ -1573,7 +1624,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< TimelineModel - + Message redaction failed: %1 Sõnumi ümbersõnastamine ebaõnnestus: %1 @@ -1584,7 +1635,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Sündmuse krüptimine ei õnnestunud, katkestame saatmise! - + Save image Salvesta pilt @@ -1718,12 +1769,12 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< %1 muutis oma koputust jututoa uksele. - + You joined this room. Sa liitusid jututoaga. - + %1 has changed their avatar and changed their display name to %2. %1 muutis oma tunnuspilti ja seadistas uueks kuvatavaks nimeks %2. @@ -1752,7 +1803,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< TimelineRow - + Edited Muudetud @@ -1760,17 +1811,32 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< TimelineView - + No room open Ühtegi jututuba pole avatud - + %1 member(s) %1 liige(t) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list Tagasi jututubade loendisse @@ -1778,7 +1844,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Ühtegi krüptitud vestlust selle kasutajaga ei leidunud. Palun loo temaga krüptitud vestlus ja proovi uuesti. @@ -1786,18 +1852,17 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< TopBar - + Back to room list Tagasi jututubade loendisse - - + No room selected Jututuba on valimata - + Room options Jututoa valikud @@ -1838,7 +1903,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< UserProfile - + Global User Profile Üldine kasutajaprofiil @@ -1848,7 +1913,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Kasutajaprofiil jututoas - + Verify Verifitseeri @@ -1897,7 +1962,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< UserSettings - + Default Vaikimisi @@ -1906,7 +1971,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< UserSettingsPage - + Minimize to tray Vähenda tegumiribale @@ -2363,7 +2428,7 @@ See tavaliselt tähendab, et rakenduse ikoon tegumiribal annab mingit sorti anim Waiting - + Waiting for other party… Ootan teise osapoole tegevust… @@ -2414,7 +2479,7 @@ See tavaliselt tähendab, et rakenduse ikoon tegumiribal annab mingit sorti anim descriptiveTime - + Yesterday Eile @@ -2485,19 +2550,6 @@ See tavaliselt tähendab, et rakenduse ikoon tegumiribal annab mingit sorti anim Ava kasutaja registreerimise tagavaravariant, läbi kõik sammud ja kinnita seda, kui kõik valmis on. - - dialogs::InviteUsers - - - Cancel - Tühista - - - - User ID to invite - Kasutajatunnus, kellele soovid kutset saata - - dialogs::JoinRoom diff --git a/resources/langs/nheko_fi.ts b/resources/langs/nheko_fi.ts index 9c48e98f..e884e0ac 100644 --- a/resources/langs/nheko_fi.ts +++ b/resources/langs/nheko_fi.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Odotetaan vahvistusta @@ -48,7 +48,7 @@ - + Cancel Peruuta @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search Hae - + People Ihmiset @@ -607,7 +607,7 @@ InputBar - + Select a file Valitse tiedosto @@ -617,17 +617,43 @@ Kaikki Tiedostot (*) - + Failed to upload media. Please try again. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + Käyttäjätunnus kutsuttavaksi + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + - - Remove - Poista + + Add + + + + + Invite + + + + + Cancel + Peruuta @@ -740,23 +766,10 @@ Example: https://server.my:8787 - - MemberList - - - Room members - Huoneen jäsenet - - - - OK - OK - - MessageDelegate - + removed @@ -767,7 +780,7 @@ Example: https://server.my:8787 Salaus on käytössä - + room name changed to: %1 huoneen nimi muutettu: %1 @@ -777,7 +790,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -787,17 +800,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -812,17 +825,17 @@ Example: https://server.my:8787 %1 soitti puhelun. - + %1 answered the call. %1 vastasi puheluun. - + %1 ended the call. - + Negotiating call... @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji Emoji @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit Muokkaa - + React Reagoi - + Reply Vastaa @@ -888,7 +906,7 @@ Example: https://server.my:8787 Asetukset - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close Sulje @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored ei tallennettua versiota @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - Hyväksy - - - - Decline - Hylkää - - - + Status Message @@ -1337,20 +1345,42 @@ Example: https://server.my:8787 Käyttäjäasetukset + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1462,6 @@ Example: https://server.my:8787 Room Version Huoneen versio - - - OK - OK - Failed to enable encryption: %1 @@ -1469,6 +1494,24 @@ Example: https://server.my:8787 Kuvan lähetys epäonnistui: %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1569,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1589,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + Hae + + Success @@ -1567,7 +1618,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 Viestin muokkaus epäonnistui: %1 @@ -1578,7 +1629,7 @@ Example: https://server.my:8787 - + Save image Tallenna kuva @@ -1712,12 +1763,12 @@ Example: https://server.my:8787 - + You joined this room. Sinä liityit tähän huoneeseen. - + %1 has changed their avatar and changed their display name to %2. @@ -1746,7 +1797,7 @@ Example: https://server.my:8787 TimelineRow - + Edited Muokattu @@ -1754,17 +1805,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1772,7 +1838,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1780,18 +1846,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options Huoneen asetukset @@ -1832,7 +1897,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1842,7 +1907,7 @@ Example: https://server.my:8787 - + Verify @@ -1891,7 +1956,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1900,7 +1965,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Pienennä ilmoitusalueelle @@ -2346,7 +2411,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2397,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Eilen @@ -2468,19 +2533,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - Peruuta - - - - User ID to invite - Käyttäjätunnus kutsuttavaksi - - dialogs::JoinRoom diff --git a/resources/langs/nheko_fr.ts b/resources/langs/nheko_fr.ts index b6345d62..fb3c0e11 100644 --- a/resources/langs/nheko_fr.ts +++ b/resources/langs/nheko_fr.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Attente de confirmation @@ -48,7 +48,7 @@ Attente de la vérification par le correspondant. - + Cancel Annuler @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Échec lors de l'invitation de %1 @@ -157,12 +157,12 @@ - + Confirm invite Confirmer l'invitation - + Do you really want to invite %1 (%2)? Voulez-vous vraiment inviter %1 (%2) ? @@ -227,12 +227,12 @@ %1 n'est plus banni(e) - + Do you really want to start a private chat with %1? Voulez-vous vraimer commencer une discussion privée avec %1 ? - + Cache migration failed! Échec de la migration du cache ! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets Déchiffrer les secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search Chercher - + People Personnes @@ -607,7 +607,7 @@ InputBar - + Select a file Sélectionnez un fichier @@ -617,17 +617,43 @@ Tous les types de fichiers (*) - + Failed to upload media. Please try again. Échec de l'envoi du média. Veuillez réessayer. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + Identifiant d'utilisateur à inviter + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + - - Remove - Retirer + + Cancel + Annuler @@ -744,23 +770,10 @@ Exemple : https ://monserveur.example.com :8787 Échec de la connexion SSO - - MemberList - - - Room members - Membres du salon - - - - OK - OK - - MessageDelegate - + removed retiré @@ -771,7 +784,7 @@ Exemple : https ://monserveur.example.com :8787 Chiffrement activé - + room name changed to: %1 nom du salon changé en : %1 @@ -781,7 +794,7 @@ Exemple : https ://monserveur.example.com :8787 nom du salon retiré - + topic changed to: %1 sujet changé pour : %1 @@ -791,17 +804,17 @@ Exemple : https ://monserveur.example.com :8787 sujet retiré - + %1 changed the room avatar - + %1 created and configured room: %2 %1 a créé et configuré le salon : %2 - + %1 placed a voice call. %1 a effectué un appel vocal. @@ -816,17 +829,17 @@ Exemple : https ://monserveur.example.com :8787 %1 a appelé. - + %1 answered the call. %1 a répondu à l'appel. - + %1 ended the call. %1 a terminé l'appel. - + Negotiating call... Négociation de l'appel… @@ -834,7 +847,7 @@ Exemple : https ://monserveur.example.com :8787 MessageInput - + Hang up Raccrocher @@ -855,6 +868,11 @@ Exemple : https ://monserveur.example.com :8787 + Stickers + + + + Emoji Émoji @@ -872,17 +890,17 @@ Exemple : https ://monserveur.example.com :8787 MessageView - + Edit Modifier - + React Réagir - + Reply Répondre @@ -892,7 +910,7 @@ Exemple : https ://monserveur.example.com :8787 Options - + &Copy @@ -1100,7 +1118,7 @@ Exemple : https ://monserveur.example.com :8787 Placeholder - + unimplemented event: Évènement non implémenté : @@ -1220,7 +1238,7 @@ Exemple : https ://monserveur.example.com :8787 ReplyPopup - + Close Fermer @@ -1233,7 +1251,7 @@ Exemple : https ://monserveur.example.com :8787 RoomInfo - + no version stored pas de version enregistrée @@ -1241,7 +1259,7 @@ Exemple : https ://monserveur.example.com :8787 RoomList - + New tag @@ -1281,17 +1299,7 @@ Exemple : https ://monserveur.example.com :8787 - - Accept - - - - - Decline - - - - + Status Message @@ -1341,20 +1349,42 @@ Exemple : https ://monserveur.example.com :8787 Paramètres utilisateur + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings Configuration du salon - + %1 member(s) %1 membre(s) - + SETTINGS CONFIGURATION @@ -1438,11 +1468,6 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& Room Version Version du salon - - - OK - OK - Failed to enable encryption: %1 @@ -1475,6 +1500,24 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& Échec de l'envoi de l'image  : %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1532,7 +1575,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& StatusIndicator - + Failed Échec @@ -1552,6 +1595,14 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& Lu + + StickerPicker + + + Search + Chercher + + Success @@ -1573,7 +1624,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& TimelineModel - + Message redaction failed: %1 Échec de la suppression du message : %1 @@ -1584,7 +1635,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& Échec du chiffrement de l'évènement, envoi abandonné ! - + Save image Enregistrer l'image @@ -1718,12 +1769,12 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& %1 ne frappe plus au salon. - + You joined this room. Vous avez rejoint ce salon. - + %1 has changed their avatar and changed their display name to %2. @@ -1752,7 +1803,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& TimelineRow - + Edited Modifié @@ -1760,17 +1811,32 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& TimelineView - + No room open Aucun salon ouvert - + %1 member(s) %1 membre(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list Revenir à la liste des salons @@ -1778,7 +1844,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Pas de discussion privée et chiffrée trouvée avec cet utilisateur. Créez-en une et réessayez. @@ -1786,18 +1852,17 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& TopBar - + Back to room list Revenir à la liste des salons - - + No room selected Pas de salon sélectionné - + Room options Options du salon @@ -1838,7 +1903,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& UserProfile - + Global User Profile Profil général de l'utilisateur @@ -1848,7 +1913,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& Profil utilisateur spécifique au salon - + Verify Vérifier @@ -1897,7 +1962,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& UserSettings - + Default Défaut @@ -1906,7 +1971,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& UserSettingsPage - + Minimize to tray Réduire à la barre des tâches @@ -2365,7 +2430,7 @@ Cela met l'application en évidence dans la barre des tâches. Waiting - + Waiting for other party… Attente du correspondant… @@ -2416,7 +2481,7 @@ Cela met l'application en évidence dans la barre des tâches. descriptiveTime - + Yesterday Hier @@ -2487,19 +2552,6 @@ Cela met l'application en évidence dans la barre des tâches.Ouvrez la solution de repli, suivez les étapes et confirmez après les avoir terminées. - - dialogs::InviteUsers - - - Cancel - Annuler - - - - User ID to invite - Identifiant d'utilisateur à inviter - - dialogs::JoinRoom diff --git a/resources/langs/nheko_hu.ts b/resources/langs/nheko_hu.ts index e989a6ce..a85f9ff3 100644 --- a/resources/langs/nheko_hu.ts +++ b/resources/langs/nheko_hu.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Várakozás megerősítésre @@ -48,7 +48,7 @@ Várakozás a másik oldalra a hitelesítés befejezéséhez. - + Cancel Mégse @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Nem sikerült meghívni a felhasználót: %1 @@ -157,12 +157,12 @@ - + Confirm invite Meghívás megerősítése - + Do you really want to invite %1 (%2)? Biztos, hogy meg akarod hívni a következő felhasználót: %1 (%2)? @@ -227,12 +227,12 @@ Kitiltás feloldva a felhasználónak: %1 - + Do you really want to start a private chat with %1? Biztosan privát csevegést akarsz indítani %1 felhasználóval? - + Cache migration failed! Gyorsítótár migráció nem sikerült! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets Titkos tároló feloldása @@ -426,12 +426,12 @@ EmojiPicker - + Search Keresés - + People Emberek @@ -607,7 +607,7 @@ InputBar - + Select a file Fájl kiválasztása @@ -617,17 +617,43 @@ Minden fájl (*) - + Failed to upload media. Please try again. Nem sikerült feltölteni a médiafájlt. Kérlek, próbáld újra! - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + Meghívandó felhasználó azonosítója + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + - - Remove - Eltávolítás + + Cancel + Mégse @@ -744,28 +770,15 @@ Példa: https://szerver.em:8787 SSO bejelentkezés nem sikerült - - MemberList - - - Room members - Szobatagok - - - - OK - OK - - MessageDelegate - + Encryption enabled Titkosítás bekapcsolva - + room name changed to: %1 a szoba neve megváltoztatva erre: %1 @@ -775,7 +788,7 @@ Példa: https://szerver.em:8787 szobanév eltávolítva - + topic changed to: %1 a téma megváltoztatva erre: %1 @@ -785,17 +798,17 @@ Példa: https://szerver.em:8787 téma eltávolítva - + %1 changed the room avatar - + %1 created and configured room: %2 %1 létrehozta és beállította a következő szobát: %2 - + %1 placed a voice call. %1 hanghívást kezdeményezett. @@ -810,23 +823,23 @@ Példa: https://szerver.em:8787 %1 hívást kezdeményezett. - + Negotiating call... Hívás előkészítése… - + %1 answered the call. %1 fogadta a hívást. - + removed eltávolítva - + %1 ended the call. %1 befejezte a hívást. @@ -834,7 +847,7 @@ Példa: https://szerver.em:8787 MessageInput - + Hang up Hívás befejezése @@ -855,6 +868,11 @@ Példa: https://szerver.em:8787 + Stickers + + + + Emoji Hangulatjelek @@ -872,17 +890,17 @@ Példa: https://szerver.em:8787 MessageView - + Edit Szerkesztés - + React Reakció - + Reply Válasz @@ -892,7 +910,7 @@ Példa: https://szerver.em:8787 Műveletek - + &Copy @@ -1100,7 +1118,7 @@ Példa: https://szerver.em:8787 Placeholder - + unimplemented event: nem implementált esemény: @@ -1220,7 +1238,7 @@ Példa: https://szerver.em:8787 ReplyPopup - + Close Bezárás @@ -1233,7 +1251,7 @@ Példa: https://szerver.em:8787 RoomInfo - + no version stored nincs tárolva verzió @@ -1241,7 +1259,7 @@ Példa: https://szerver.em:8787 RoomList - + New tag @@ -1281,17 +1299,7 @@ Példa: https://szerver.em:8787 - - Accept - Elfogadás - - - - Decline - Elutasítás - - - + Status Message @@ -1341,20 +1349,41 @@ Példa: https://szerver.em:8787 Felhasználói beállítások + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + Invite more people + + + RoomSettings - + Room Settings Szobabeállítások - + %1 member(s) %1 tag - + SETTINGS BEÁLLÍTÁSOK @@ -1438,11 +1467,6 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh Room Version Szoba verziója - - - OK - OK - Failed to enable encryption: %1 @@ -1475,6 +1499,24 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh Nem sikerült a kép feltöltése: %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1532,7 +1574,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh StatusIndicator - + Failed Sikertelen @@ -1552,6 +1594,14 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh Elolvasva + + StickerPicker + + + Search + Keresés + + Success @@ -1573,7 +1623,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh TimelineModel - + Message redaction failed: %1 Az üzenet visszavonása nem sikerült: %1 @@ -1584,7 +1634,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh Nem sikerült titkosítani az eseményt, küldés megszakítva! - + Save image Kép mentése @@ -1717,12 +1767,12 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh %1 visszavonta a kopogását. - + You joined this room. Csatlakoztál ehhez a szobához. - + %1 has changed their avatar and changed their display name to %2. @@ -1751,7 +1801,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh TimelineRow - + Edited Szerkesztve @@ -1759,17 +1809,32 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh TimelineView - + No room open Nincs nyitott szoba - + %1 member(s) %1 tag - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list Vissza a szobák listájára @@ -1777,7 +1842,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Nem található titkosított privát csevegés ezzel a felhasználóval. Hozz létre egy titkosított privát csevegést vele, és próbáld újra! @@ -1785,18 +1850,17 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh TopBar - + Back to room list Vissza a szobák listájára - - + No room selected Nincs kiválasztva szoba - + Room options Szoba beállításai @@ -1837,7 +1901,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh UserProfile - + Global User Profile Globális felhasználói profil @@ -1847,7 +1911,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh Szobai felhasználói profil - + Verify Hitelesítés @@ -1896,7 +1960,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh UserSettings - + Default Alapértelmezett @@ -1905,7 +1969,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh UserSettingsPage - + Minimize to tray Kicsinyítés a tálcára @@ -2363,7 +2427,7 @@ Ettől általában animálttá válik az alkalmazásablakok listáján szereplő Waiting - + Waiting for other party… Várakozás a másik félre… @@ -2414,7 +2478,7 @@ Ettől általában animálttá válik az alkalmazásablakok listáján szereplő descriptiveTime - + Yesterday Tegnap @@ -2485,19 +2549,6 @@ Ettől általában animálttá válik az alkalmazásablakok listáján szereplő Nyisd meg a fallback-ket, kövesd az utasításokat, és erősítsd meg, ha végeztél velük! - - dialogs::InviteUsers - - - Cancel - Mégse - - - - User ID to invite - Meghívandó felhasználó azonosítója - - dialogs::JoinRoom diff --git a/resources/langs/nheko_it.ts b/resources/langs/nheko_it.ts index b0b8ec48..6056b31a 100644 --- a/resources/langs/nheko_it.ts +++ b/resources/langs/nheko_it.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation In attesa di conferma @@ -48,7 +48,7 @@ In attesa della conferma dall'altra parte per la verifica. - + Cancel Annulla @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Impossibile invitare l'utente: %1 @@ -157,12 +157,12 @@ - + Confirm invite Conferma Invito - + Do you really want to invite %1 (%2)? Vuoi davvero inviare %1 (%2)? @@ -227,12 +227,12 @@ Rimosso il ban dall'utente: %1 - + Do you really want to start a private chat with %1? Sei sicuro di voler avviare una chat privata con %1? - + Cache migration failed! Migrazione della cache fallita! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets Decifra i segreti @@ -426,12 +426,12 @@ EmojiPicker - + Search Cerca - + People Membri @@ -607,7 +607,7 @@ InputBar - + Select a file Seleziona un file @@ -617,17 +617,43 @@ Tutti i File (*) - + Failed to upload media. Please try again. Impossibile inviare il file multimediale. Per favore riprova. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + ID utente da invitare + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + - - Remove - Rimuovi + + Add + + + + + Invite + + + + + Cancel + Annulla @@ -744,23 +770,10 @@ Esempio: https://server.mio:8787 Accesso SSO fallito - - MemberList - - - Room members - Membri della stanza - - - - OK - OK - - MessageDelegate - + removed rimosso @@ -771,7 +784,7 @@ Esempio: https://server.mio:8787 Crittografia abilitata - + room name changed to: %1 nome della stanza cambiato in: %1 @@ -781,7 +794,7 @@ Esempio: https://server.mio:8787 nome della stanza rimosso - + topic changed to: %1 argomento cambiato in: %1 @@ -791,17 +804,17 @@ Esempio: https://server.mio:8787 argomento rimosso - + %1 changed the room avatar - + %1 created and configured room: %2 %1 creato e configurata stanza: %2 - + %1 placed a voice call. %1 ha avviato una chiamata audio. @@ -816,17 +829,17 @@ Esempio: https://server.mio:8787 - + %1 answered the call. %1 ha risposto alla chiamata. - + %1 ended the call. %1 ha terminato la chiamata. - + Negotiating call... @@ -834,7 +847,7 @@ Esempio: https://server.mio:8787 MessageInput - + Hang up Termina @@ -855,6 +868,11 @@ Esempio: https://server.mio:8787 + Stickers + + + + Emoji Emoji @@ -872,17 +890,17 @@ Esempio: https://server.mio:8787 MessageView - + Edit Modifica - + React Reagisci - + Reply Risposta @@ -892,7 +910,7 @@ Esempio: https://server.mio:8787 Opzioni - + &Copy @@ -1101,7 +1119,7 @@ Verificare %1 adesso? Placeholder - + unimplemented event: evento non implementato: @@ -1221,7 +1239,7 @@ Verificare %1 adesso? ReplyPopup - + Close Chiudi @@ -1234,7 +1252,7 @@ Verificare %1 adesso? RoomInfo - + no version stored nessuna versione memorizzata @@ -1242,7 +1260,7 @@ Verificare %1 adesso? RoomList - + New tag @@ -1282,17 +1300,7 @@ Verificare %1 adesso? - - Accept - Accetta - - - - Decline - Rifiuta - - - + Status Message @@ -1342,20 +1350,42 @@ Verificare %1 adesso? Impostazioni utente + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1437,11 +1467,6 @@ Verificare %1 adesso? Room Version - - - OK - OK - Failed to enable encryption: %1 @@ -1474,6 +1499,24 @@ Verificare %1 adesso? Impossibile fare l'upload dell'immagine: %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1531,7 +1574,7 @@ Verificare %1 adesso? StatusIndicator - + Failed Fallito @@ -1551,6 +1594,14 @@ Verificare %1 adesso? Letto + + StickerPicker + + + Search + Cerca + + Success @@ -1572,7 +1623,7 @@ Verificare %1 adesso? TimelineModel - + Message redaction failed: %1 Oscuramento del messaggio fallito: %1 @@ -1583,7 +1634,7 @@ Verificare %1 adesso? - + Save image Salva immagine @@ -1717,12 +1768,12 @@ Verificare %1 adesso? %1 ha oscurato la sua bussata. - + You joined this room. Sei entrato in questa stanza. - + %1 has changed their avatar and changed their display name to %2. @@ -1751,7 +1802,7 @@ Verificare %1 adesso? TimelineRow - + Edited @@ -1759,17 +1810,32 @@ Verificare %1 adesso? TimelineView - + No room open Nessuna stanza aperta - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1777,7 +1843,7 @@ Verificare %1 adesso? TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1785,18 +1851,17 @@ Verificare %1 adesso? TopBar - + Back to room list - - + No room selected - + Room options Opzioni della stanza @@ -1837,7 +1902,7 @@ Verificare %1 adesso? UserProfile - + Global User Profile @@ -1847,7 +1912,7 @@ Verificare %1 adesso? - + Verify @@ -1896,7 +1961,7 @@ Verificare %1 adesso? UserSettings - + Default @@ -1905,7 +1970,7 @@ Verificare %1 adesso? UserSettingsPage - + Minimize to tray Minimizza nella tray @@ -2351,7 +2416,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2402,7 +2467,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Ieri @@ -2473,19 +2538,6 @@ This usually causes the application icon in the task bar to animate in some fash Apri il ripiego, segui i passaggi e conferma dopo averli completati. - - dialogs::InviteUsers - - - Cancel - Annulla - - - - User ID to invite - ID utente da invitare - - dialogs::JoinRoom diff --git a/resources/langs/nheko_ja.ts b/resources/langs/nheko_ja.ts index c7872ce0..a8c18795 100644 --- a/resources/langs/nheko_ja.ts +++ b/resources/langs/nheko_ja.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation @@ -48,7 +48,7 @@ - + Cancel キャンセル @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 ユーザーを招待できませんでした: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ 永久追放を解除されたユーザー: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file ファイルを選択 @@ -617,17 +617,43 @@ 全てのファイル (*) - + Failed to upload media. Please try again. メディアをアップロードできませんでした。やり直して下さい。 - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + 招待するユーザーのID + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + - - Remove - 削除 + + Cancel + キャンセル @@ -740,23 +766,10 @@ Example: https://server.my:8787 - - MemberList - - - Room members - 部屋の参加者 - - - - OK - OK - - MessageDelegate - + removed @@ -767,7 +780,7 @@ Example: https://server.my:8787 暗号化が有効です - + room name changed to: %1 部屋名が変更されました: %1 @@ -777,7 +790,7 @@ Example: https://server.my:8787 部屋名が削除されました - + topic changed to: %1 話題が変更されました: %1 @@ -787,17 +800,17 @@ Example: https://server.my:8787 話題が削除されました - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -812,17 +825,17 @@ Example: https://server.my:8787 - + %1 answered the call. - + %1 ended the call. - + Negotiating call... @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji 絵文字 @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply 返信 @@ -888,7 +906,7 @@ Example: https://server.my:8787 オプション - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: 未実装のイベント: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close 閉じる @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored バージョンが保存されていません @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - 容認 - - - - Decline - 拒否 - - - + Status Message @@ -1337,20 +1345,41 @@ Example: https://server.my:8787 ユーザー設定 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1461,6 @@ Example: https://server.my:8787 Room Version - - - OK - OK - Failed to enable encryption: %1 @@ -1469,6 +1493,24 @@ Example: https://server.my:8787 画像をアップロードできませんでした: %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1568,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed 失敗 @@ -1546,6 +1588,14 @@ Example: https://server.my:8787 既読 + + StickerPicker + + + Search + + + Success @@ -1567,7 +1617,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 メッセージを編集できませんでした: %1 @@ -1578,7 +1628,7 @@ Example: https://server.my:8787 - + Save image 画像を保存 @@ -1711,12 +1761,12 @@ Example: https://server.my:8787 %1がノックを編集しました。 - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1745,7 +1795,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1753,17 +1803,32 @@ Example: https://server.my:8787 TimelineView - + No room open 部屋が開いていません - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1771,7 +1836,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1779,18 +1844,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options 部屋のオプション @@ -1831,7 +1895,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1841,7 +1905,7 @@ Example: https://server.my:8787 - + Verify @@ -1890,7 +1954,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1899,7 +1963,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray トレイへ最小化 @@ -2345,7 +2409,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2396,7 +2460,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday 昨日 @@ -2467,19 +2531,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - キャンセル - - - - User ID to invite - 招待するユーザーのID - - dialogs::JoinRoom diff --git a/resources/langs/nheko_ml.ts b/resources/langs/nheko_ml.ts index 0bdf3b63..aeb704eb 100644 --- a/resources/langs/nheko_ml.ts +++ b/resources/langs/nheko_ml.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation സ്ഥിരീകരണത്തിനായി കാത്തിരിക്കുന്നു @@ -48,7 +48,7 @@ - + Cancel റദ്ദാക്കു @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 ഉപയോക്താവിനെ ക്ഷണിക്കുന്നതിൽ പരാജയപ്പെട്ടു: %1 @@ -157,12 +157,12 @@ - + Confirm invite ക്ഷണം ഉറപ്പാക്കു - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search തിരയുക - + People ആളുകൾ @@ -607,7 +607,7 @@ InputBar - + Select a file ഒരു ഫയൽ തിരഞ്ഞെടുക്കുക @@ -617,17 +617,43 @@ - + Failed to upload media. Please try again. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + - - Remove - നീക്കംചെയ്യുക + + Cancel + റദ്ദാക്കു @@ -740,28 +766,15 @@ Example: https://server.my:8787 - - MemberList - - - Room members - - - - - OK - ശരി - - MessageDelegate - + Encryption enabled - + room name changed to: %1 @@ -771,7 +784,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -781,17 +794,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -806,23 +819,23 @@ Example: https://server.my:8787 - + Negotiating call... - + %1 answered the call. - + removed നീക്കംചെയ്‌തു - + %1 ended the call. @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji ഇമോജി @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -888,7 +906,7 @@ Example: https://server.my:8787 - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close അടയ്‌ക്കുക @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - - - - - Decline - നിരസിക്കുക - - - + Status Message @@ -1337,20 +1345,42 @@ Example: https://server.my:8787 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1462,6 @@ Example: https://server.my:8787 Room Version - - - OK - ശരി - Failed to enable encryption: %1 @@ -1469,6 +1494,24 @@ Example: https://server.my:8787 + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1569,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1589,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + തിരയുക + + Success @@ -1567,7 +1618,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1578,7 +1629,7 @@ Example: https://server.my:8787 - + Save image @@ -1712,12 +1763,12 @@ Example: https://server.my:8787 - + You joined this room. നിങ്ങൾ ഈ മുറിയിൽ ചേർന്നു. - + %1 has changed their avatar and changed their display name to %2. @@ -1746,7 +1797,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1754,17 +1805,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1772,7 +1838,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1780,18 +1846,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1832,7 +1897,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1842,7 +1907,7 @@ Example: https://server.my:8787 - + Verify @@ -1891,7 +1956,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1900,7 +1965,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2346,7 +2411,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2397,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2468,19 +2533,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - റദ്ദാക്കു - - - - User ID to invite - - - dialogs::JoinRoom diff --git a/resources/langs/nheko_nl.ts b/resources/langs/nheko_nl.ts index 3f2a147f..ba3ceec1 100644 --- a/resources/langs/nheko_nl.ts +++ b/resources/langs/nheko_nl.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation @@ -48,7 +48,7 @@ - + Cancel Annuleren @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Gebruiker uitnodigen mislukt: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file Kies een bestand @@ -617,18 +617,44 @@ Alle bestanden (*) - + Failed to upload media. Please try again. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + Uit te nodigen gebruikers-id + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + - - Remove + + Invite + + + Cancel + Annuleren + LoginPage @@ -740,23 +766,10 @@ Example: https://server.my:8787 - - MemberList - - - Room members - Kamerleden - - - - OK - - - MessageDelegate - + removed @@ -767,7 +780,7 @@ Example: https://server.my:8787 - + room name changed to: %1 @@ -777,7 +790,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -787,17 +800,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -812,17 +825,17 @@ Example: https://server.my:8787 - + %1 answered the call. - + %1 ended the call. - + Negotiating call... @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -888,7 +906,7 @@ Example: https://server.my:8787 - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - Accepteren - - - - Decline - Afwijzen - - - + Status Message @@ -1337,20 +1345,42 @@ Example: https://server.my:8787 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1462,6 @@ Example: https://server.my:8787 Room Version - - - OK - - Failed to enable encryption: %1 @@ -1469,6 +1494,24 @@ Example: https://server.my:8787 + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1569,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1589,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + + + Success @@ -1567,7 +1618,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1578,7 +1629,7 @@ Example: https://server.my:8787 - + Save image Afbeelding opslaan @@ -1712,12 +1763,12 @@ Example: https://server.my:8787 - + You joined this room. Je bent lid geworden van deze kamer. - + %1 has changed their avatar and changed their display name to %2. @@ -1746,7 +1797,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1754,17 +1805,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1772,7 +1838,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1780,18 +1846,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1832,7 +1897,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1842,7 +1907,7 @@ Example: https://server.my:8787 - + Verify @@ -1891,7 +1956,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1900,7 +1965,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Minimaliseren naar systeemvak @@ -2346,7 +2411,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2397,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2468,19 +2533,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - Annuleren - - - - User ID to invite - Uit te nodigen gebruikers-id - - dialogs::JoinRoom diff --git a/resources/langs/nheko_pl.ts b/resources/langs/nheko_pl.ts index 6abcd147..4b6c31f2 100644 --- a/resources/langs/nheko_pl.ts +++ b/resources/langs/nheko_pl.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Oczekiwanie na potwierdzenie @@ -48,7 +48,7 @@ Oczekiwanie na dokończenie weryfikacji przez drugą stronę. - + Cancel Anuluj @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Nie udało się zaprosić użytkownika: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? Czy na pewno chcesz zaprosić %1 (%2)? @@ -227,12 +227,12 @@ Odblokowano użytkownika: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! Nie udało się przenieść pamięci podręcznej! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search Szukaj - + People Ludzie @@ -607,7 +607,7 @@ InputBar - + Select a file Wybierz plik @@ -617,17 +617,43 @@ Wszystkie pliki (*) - + Failed to upload media. Please try again. - InviteeItem + InviteDialog - - Remove - Usuń + + Invite users to %1 + + + + + User ID to invite + ID użytkownika do zaproszenia + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + + + + Cancel + Anuluj @@ -742,23 +768,10 @@ Example: https://server.my:8787 Logowanie SSO zakończone niepowodzeniem - - MemberList - - - Room members - Członkowie pokoju - - - - OK - OK - - MessageDelegate - + removed @@ -769,7 +782,7 @@ Example: https://server.my:8787 Szyfrowanie włączone - + room name changed to: %1 Nazwa pokoju zmieniona na: %1 @@ -779,7 +792,7 @@ Example: https://server.my:8787 usunięto nazwę pokoju - + topic changed to: %1 temat zmieniono na: %1 @@ -789,17 +802,17 @@ Example: https://server.my:8787 usunięto temat - + %1 changed the room avatar - + %1 created and configured room: %2 %1 utworzył i skonfigurował pokój: %2 - + %1 placed a voice call. %1 rozpoczął(-ęła) połączenie głosowe. @@ -814,17 +827,17 @@ Example: https://server.my:8787 %1 rozpoczął(-ęła) połączenie. - + %1 answered the call. %1 odebrał(a) połączenie. - + %1 ended the call. %1 zakończył(a) połączenie. - + Negotiating call... Negocjowanie połączenia… @@ -832,7 +845,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -853,6 +866,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji Emoji @@ -870,17 +888,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -890,7 +908,7 @@ Example: https://server.my:8787 - + &Copy @@ -1098,7 +1116,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: Niezaimplementowane wydarzenie: @@ -1218,7 +1236,7 @@ Example: https://server.my:8787 ReplyPopup - + Close Zamknij @@ -1231,7 +1249,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1239,7 +1257,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1279,17 +1297,7 @@ Example: https://server.my:8787 - - Accept - Akceptuj - - - - Decline - Odrzuć - - - + Status Message @@ -1339,20 +1347,43 @@ Example: https://server.my:8787 Ustawienia użytkownika + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1434,11 +1465,6 @@ Example: https://server.my:8787 Room Version - - - OK - OK - Failed to enable encryption: %1 @@ -1471,6 +1497,24 @@ Example: https://server.my:8787 Nie udało się wysłać obrazu: %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1528,7 +1572,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1548,6 +1592,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + Szukaj + + Success @@ -1569,7 +1621,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 Redagowanie wiadomości nie powiodło się: %1 @@ -1580,7 +1632,7 @@ Example: https://server.my:8787 - + Save image Zapisz obraz @@ -1715,12 +1767,12 @@ Example: https://server.my:8787 - + You joined this room. Dołączyłeś(-łaś) do tego pokoju. - + %1 has changed their avatar and changed their display name to %2. @@ -1749,7 +1801,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1757,17 +1809,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1775,7 +1842,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1783,18 +1850,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options Ustawienia pokoju @@ -1835,7 +1901,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1845,7 +1911,7 @@ Example: https://server.my:8787 - + Verify @@ -1894,7 +1960,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1903,7 +1969,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Zminimalizuj do paska zadań @@ -2349,7 +2415,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2400,7 +2466,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2471,19 +2537,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - Anuluj - - - - User ID to invite - ID użytkownika do zaproszenia - - dialogs::JoinRoom diff --git a/resources/langs/nheko_pt_BR.ts b/resources/langs/nheko_pt_BR.ts index fa0ea193..7774ba58 100644 --- a/resources/langs/nheko_pt_BR.ts +++ b/resources/langs/nheko_pt_BR.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation @@ -48,7 +48,7 @@ Esperando o outro lado completar a verificação. - + Cancel Cancelar @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Falha ao convidar usuário: %1 @@ -157,12 +157,12 @@ - + Confirm invite Confirmar convite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ Usuário desbanido: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! Migração do cache falhou! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file @@ -617,18 +617,44 @@ - + Failed to upload media. Please try again. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + - - Remove + + Invite + + + Cancel + Cancelar + LoginPage @@ -740,28 +766,15 @@ Example: https://server.my:8787 - - MemberList - - - Room members - - - - - OK - - - MessageDelegate - + Encryption enabled - + room name changed to: %1 @@ -771,7 +784,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -781,17 +794,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -806,23 +819,23 @@ Example: https://server.my:8787 - + Negotiating call... - + %1 answered the call. - + removed - + %1 ended the call. @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -888,7 +906,7 @@ Example: https://server.my:8787 - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - Aceitar - - - - Decline - Rejeitar - - - + Status Message @@ -1337,20 +1345,42 @@ Example: https://server.my:8787 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1462,6 @@ Example: https://server.my:8787 Room Version - - - OK - - Failed to enable encryption: %1 @@ -1469,6 +1494,24 @@ Example: https://server.my:8787 + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1569,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1589,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + + + Success @@ -1567,7 +1618,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1578,7 +1629,7 @@ Example: https://server.my:8787 - + Save image @@ -1712,12 +1763,12 @@ Example: https://server.my:8787 - + You joined this room. Você entrou nessa sala. - + %1 has changed their avatar and changed their display name to %2. @@ -1746,7 +1797,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1754,17 +1805,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1772,7 +1838,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1780,18 +1846,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1832,7 +1897,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1842,7 +1907,7 @@ Example: https://server.my:8787 - + Verify @@ -1891,7 +1956,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1900,7 +1965,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2346,7 +2411,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2397,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2468,19 +2533,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - Cancelar - - - - User ID to invite - - - dialogs::JoinRoom diff --git a/resources/langs/nheko_pt_PT.ts b/resources/langs/nheko_pt_PT.ts index 81343f97..cafbcdd6 100644 --- a/resources/langs/nheko_pt_PT.ts +++ b/resources/langs/nheko_pt_PT.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation @@ -48,7 +48,7 @@ - + Cancel @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file @@ -617,16 +617,42 @@ - + Failed to upload media. Please try again. - InviteeItem + InviteDialog - - Remove + + Invite users to %1 + + + + + User ID to invite + + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + + + + Cancel @@ -740,28 +766,15 @@ Example: https://server.my:8787 - - MemberList - - - Room members - - - - - OK - - - MessageDelegate - + Encryption enabled - + room name changed to: %1 @@ -771,7 +784,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -781,17 +794,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -806,23 +819,23 @@ Example: https://server.my:8787 - + Negotiating call... - + %1 answered the call. - + removed - + %1 ended the call. @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -888,7 +906,7 @@ Example: https://server.my:8787 - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - - - - - Decline - - - - + Status Message @@ -1337,20 +1345,42 @@ Example: https://server.my:8787 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1462,6 @@ Example: https://server.my:8787 Room Version - - - OK - - Failed to enable encryption: %1 @@ -1469,6 +1494,24 @@ Example: https://server.my:8787 + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1569,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1589,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + + + Success @@ -1567,7 +1618,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1578,7 +1629,7 @@ Example: https://server.my:8787 - + Save image @@ -1712,12 +1763,12 @@ Example: https://server.my:8787 - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1746,7 +1797,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1754,17 +1805,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1772,7 +1838,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1780,18 +1846,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1832,7 +1897,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1842,7 +1907,7 @@ Example: https://server.my:8787 - + Verify @@ -1891,7 +1956,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1900,7 +1965,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2346,7 +2411,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2397,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2468,19 +2533,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - - - - - User ID to invite - - - dialogs::JoinRoom diff --git a/resources/langs/nheko_ro.ts b/resources/langs/nheko_ro.ts index c21bb069..8ff28d24 100644 --- a/resources/langs/nheko_ro.ts +++ b/resources/langs/nheko_ro.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation @@ -48,7 +48,7 @@ - + Cancel @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Nu s-a putut invita utilizatorul: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ Utilizator dezinterzis: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! Nu s-a putut migra cache-ul! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file @@ -617,17 +617,43 @@ Toate fișierele (*) - + Failed to upload media. Please try again. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + IDul utilizatorului de invitat + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + - - Remove - Ștergere + + Cancel + @@ -744,23 +770,10 @@ Exemplu: https://serverul.meu:8787 Conectarea SSO a eșuat - - MemberList - - - Room members - Membrii camerei - - - - OK - OK - - MessageDelegate - + removed @@ -771,7 +784,7 @@ Exemplu: https://serverul.meu:8787 Criptare activată - + room name changed to: %1 numele camerei schimbat la: %1 @@ -781,7 +794,7 @@ Exemplu: https://serverul.meu:8787 numele camerei șters - + topic changed to: %1 subiect schimbat la: %1 @@ -791,17 +804,17 @@ Exemplu: https://serverul.meu:8787 subiect șters - + %1 changed the room avatar - + %1 created and configured room: %2 %1 a creat și configurat camera: %2 - + %1 placed a voice call. @@ -816,17 +829,17 @@ Exemplu: https://serverul.meu:8787 - + %1 answered the call. %1 a răspuns apelului. - + %1 ended the call. %1 a închis apelul. - + Negotiating call... @@ -834,7 +847,7 @@ Exemplu: https://serverul.meu:8787 MessageInput - + Hang up @@ -855,6 +868,11 @@ Exemplu: https://serverul.meu:8787 + Stickers + + + + Emoji @@ -872,17 +890,17 @@ Exemplu: https://serverul.meu:8787 MessageView - + Edit - + React - + Reply Răspuns @@ -892,7 +910,7 @@ Exemplu: https://serverul.meu:8787 Opțiuni - + &Copy @@ -1100,7 +1118,7 @@ Exemplu: https://serverul.meu:8787 Placeholder - + unimplemented event: eveniment neimplementat: @@ -1220,7 +1238,7 @@ Exemplu: https://serverul.meu:8787 ReplyPopup - + Close Închide @@ -1233,7 +1251,7 @@ Exemplu: https://serverul.meu:8787 RoomInfo - + no version stored nicio versiune stocată @@ -1241,7 +1259,7 @@ Exemplu: https://serverul.meu:8787 RoomList - + New tag @@ -1281,17 +1299,7 @@ Exemplu: https://serverul.meu:8787 - - Accept - Acceptare - - - - Decline - Refuzare - - - + Status Message @@ -1341,20 +1349,43 @@ Exemplu: https://serverul.meu:8787 Setări utilizator + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1436,11 +1467,6 @@ Exemplu: https://serverul.meu:8787 Room Version - - - OK - OK - Failed to enable encryption: %1 @@ -1473,6 +1499,24 @@ Exemplu: https://serverul.meu:8787 Nu s-a putut încărca imaginea: %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1530,7 +1574,7 @@ Exemplu: https://serverul.meu:8787 StatusIndicator - + Failed Eșuat @@ -1550,6 +1594,14 @@ Exemplu: https://serverul.meu:8787 Citit + + StickerPicker + + + Search + + + Success @@ -1571,7 +1623,7 @@ Exemplu: https://serverul.meu:8787 TimelineModel - + Message redaction failed: %1 Redactare mesaj eșuată: %1 @@ -1582,7 +1634,7 @@ Exemplu: https://serverul.meu:8787 - + Save image Salvați imaginea @@ -1717,12 +1769,12 @@ Exemplu: https://serverul.meu:8787 %1 și-a redactat ciocănitul. - + You joined this room. Te-ai alăturat camerei. - + %1 has changed their avatar and changed their display name to %2. @@ -1751,7 +1803,7 @@ Exemplu: https://serverul.meu:8787 TimelineRow - + Edited @@ -1759,17 +1811,32 @@ Exemplu: https://serverul.meu:8787 TimelineView - + No room open Nicio cameră deschisă - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1777,7 +1844,7 @@ Exemplu: https://serverul.meu:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1785,18 +1852,17 @@ Exemplu: https://serverul.meu:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1837,7 +1903,7 @@ Exemplu: https://serverul.meu:8787 UserProfile - + Global User Profile @@ -1847,7 +1913,7 @@ Exemplu: https://serverul.meu:8787 - + Verify @@ -1896,7 +1962,7 @@ Exemplu: https://serverul.meu:8787 UserSettings - + Default @@ -1905,7 +1971,7 @@ Exemplu: https://serverul.meu:8787 UserSettingsPage - + Minimize to tray Minimizează în bara de notificări @@ -2351,7 +2417,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2402,7 +2468,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Ieri @@ -2473,19 +2539,6 @@ This usually causes the application icon in the task bar to animate in some fash Deschideți fallback, urmăriți pașii și confirmați după ce i-ați completat. - - dialogs::InviteUsers - - - Cancel - Anulare - - - - User ID to invite - IDul utilizatorului de invitat - - dialogs::JoinRoom diff --git a/resources/langs/nheko_ru.ts b/resources/langs/nheko_ru.ts index 6f2b19af..be97413f 100644 --- a/resources/langs/nheko_ru.ts +++ b/resources/langs/nheko_ru.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Ожидание Подтверждения @@ -48,7 +48,7 @@ Ожидание подтверждения у собеседника. - + Cancel Отмена @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Не удалось пригласить пользователя: %1 @@ -157,12 +157,12 @@ - + Confirm invite Подтвердите приглашение - + Do you really want to invite %1 (%2)? Вы точно хотите пригласить %1 (%2)? @@ -227,12 +227,12 @@ Разблокированный пользователь: %1 - + Do you really want to start a private chat with %1? Вы действительно хотите начать личную переписку с %1? - + Cache migration failed! Миграция кэша не удалась! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets Расшифровать секреты @@ -426,12 +426,12 @@ EmojiPicker - + Search Поиск - + People Люди @@ -607,7 +607,7 @@ InputBar - + Select a file Выберите файл @@ -617,17 +617,43 @@ Все файлы (*) - + Failed to upload media. Please try again. Не удалось загрузить медиа. Пожалуйста попробуйте ещё раз - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + Идентификатор пользователя + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + - - Remove - Удалить + + Add + + + + + Invite + + + + + Cancel + @@ -744,23 +770,10 @@ Example: https://server.my:8787 SSO вход не удался - - MemberList - - - Room members - Участники комнаты - - - - OK - ОК - - MessageDelegate - + removed убрано @@ -771,7 +784,7 @@ Example: https://server.my:8787 Шифрование включено - + room name changed to: %1 имя комнаты изменено на: %1 @@ -781,7 +794,7 @@ Example: https://server.my:8787 название комнаты убрано - + topic changed to: %1 тема изменена на: %1 @@ -791,17 +804,17 @@ Example: https://server.my:8787 тема убрана - + %1 changed the room avatar - + %1 created and configured room: %2 %1 создал и настроил комнату: %2 - + %1 placed a voice call. %1 начал голосовой звонок. @@ -816,17 +829,17 @@ Example: https://server.my:8787 %1 начал вызов. - + %1 answered the call. %1 ответил на звонок. - + %1 ended the call. %1 завершил вызов. - + Negotiating call... Совершение звонка... @@ -834,7 +847,7 @@ Example: https://server.my:8787 MessageInput - + Hang up Завершить звонок @@ -855,6 +868,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji Эмоджи @@ -872,17 +890,17 @@ Example: https://server.my:8787 MessageView - + Edit Редактировать - + React Реакция - + Reply Ответить @@ -892,7 +910,7 @@ Example: https://server.my:8787 Опции - + &Copy @@ -1100,7 +1118,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: не реализованное событие @@ -1220,7 +1238,7 @@ Example: https://server.my:8787 ReplyPopup - + Close Закрыть @@ -1233,7 +1251,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored нет сохраненной версии @@ -1241,7 +1259,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1281,17 +1299,7 @@ Example: https://server.my:8787 - - Accept - Принять - - - - Decline - Отказаться - - - + Status Message @@ -1341,20 +1349,43 @@ Example: https://server.my:8787 Пользовательские настройки + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + + Invite more people + + + RoomSettings - + Room Settings Настройки комнаты - + %1 member(s) %1 участник(ов) - + SETTINGS НАЙСТРОЙКИ @@ -1436,11 +1467,6 @@ Example: https://server.my:8787 Room Version Версия Комнаты - - - OK - ОК - Failed to enable encryption: %1 @@ -1473,6 +1499,24 @@ Example: https://server.my:8787 Не удалось загрузить изображение: %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1530,7 +1574,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed Не удалоcь @@ -1550,6 +1594,14 @@ Example: https://server.my:8787 Прочитано + + StickerPicker + + + Search + Поиск + + Success @@ -1571,7 +1623,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 Ошибка редактирования сообщения: %1 @@ -1582,7 +1634,7 @@ Example: https://server.my:8787 Не удалось зашифровать сообщение, отправка отменена! - + Save image Сохранить изображение @@ -1717,12 +1769,12 @@ Example: https://server.my:8787 %1 отредактировал его "стук". - + You joined this room. Вы присоединились к этой комнате. - + %1 has changed their avatar and changed their display name to %2. @@ -1751,7 +1803,7 @@ Example: https://server.my:8787 TimelineRow - + Edited Изменено @@ -1759,17 +1811,32 @@ Example: https://server.my:8787 TimelineView - + No room open Комната не выбрана - + %1 member(s) %1 участник(ов) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list Вернуться к списку комнат @@ -1777,7 +1844,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Не найдено личного чата с этим пользователем. Создайте зашифрованный личный чат с этим пользователем и попытайтесь еще раз. @@ -1785,18 +1852,17 @@ Example: https://server.my:8787 TopBar - + Back to room list Вернуться к списку комнат - - + No room selected Комнаты не выбраны - + Room options Настройки комнаты @@ -1837,7 +1903,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile Глобальный Пользовательский Профиль @@ -1847,7 +1913,7 @@ Example: https://server.my:8787 Поользовательский Профиль в Комнате - + Verify Верифицировать @@ -1896,7 +1962,7 @@ Example: https://server.my:8787 UserSettings - + Default По умолчанию @@ -1905,7 +1971,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Сворачивать в системную панель @@ -2357,7 +2423,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2408,7 +2474,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday Вчера @@ -2479,19 +2545,6 @@ This usually causes the application icon in the task bar to animate in some fash Запустите резервный вариант, пройдите его шаги и подтвердите завершение. - - dialogs::InviteUsers - - - Cancel - Отмена - - - - User ID to invite - Идентификатор пользователя - - dialogs::JoinRoom diff --git a/resources/langs/nheko_si.ts b/resources/langs/nheko_si.ts index a80adb1b..67f09710 100644 --- a/resources/langs/nheko_si.ts +++ b/resources/langs/nheko_si.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation @@ -48,7 +48,7 @@ - + Cancel @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file @@ -617,16 +617,42 @@ - + Failed to upload media. Please try again. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + - - Remove + + Invite + + + + + Cancel @@ -740,23 +766,10 @@ Example: https://server.my:8787 - - MemberList - - - Room members - - - - - OK - - - MessageDelegate - + removed @@ -767,7 +780,7 @@ Example: https://server.my:8787 - + room name changed to: %1 @@ -777,7 +790,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -787,17 +800,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -812,17 +825,17 @@ Example: https://server.my:8787 - + %1 answered the call. - + %1 ended the call. - + Negotiating call... @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -888,7 +906,7 @@ Example: https://server.my:8787 - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - - - - - Decline - - - - + Status Message @@ -1337,20 +1345,42 @@ Example: https://server.my:8787 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1462,6 @@ Example: https://server.my:8787 Room Version - - - OK - - Failed to enable encryption: %1 @@ -1469,6 +1494,24 @@ Example: https://server.my:8787 + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1569,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1589,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + + + Success @@ -1567,7 +1618,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1578,7 +1629,7 @@ Example: https://server.my:8787 - + Save image @@ -1712,12 +1763,12 @@ Example: https://server.my:8787 - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1746,7 +1797,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1754,17 +1805,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1772,7 +1838,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1780,18 +1846,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options @@ -1832,7 +1897,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1842,7 +1907,7 @@ Example: https://server.my:8787 - + Verify @@ -1891,7 +1956,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1900,7 +1965,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2346,7 +2411,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2397,7 +2462,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2468,19 +2533,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - - - - - User ID to invite - - - dialogs::JoinRoom diff --git a/resources/langs/nheko_sv.ts b/resources/langs/nheko_sv.ts index 8069dcea..fb662292 100644 --- a/resources/langs/nheko_sv.ts +++ b/resources/langs/nheko_sv.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation Inväntar Bekräftelse @@ -48,7 +48,7 @@ Väntar på att motparten ska slutföra verifikationen. - + Cancel Avbryt @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 Kunde inte bjuda in användare: %1 @@ -157,12 +157,12 @@ - + Confirm invite Bekräfta inbjudan - + Do you really want to invite %1 (%2)? Är du säker på att du vill bjuda in %1 (%2)? @@ -227,12 +227,12 @@ Hävde bannlysningen av användare: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! Cache-migration misslyckades! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets Dekryptera hemliga nycklar @@ -426,12 +426,12 @@ EmojiPicker - + Search Sök - + People Personer @@ -607,7 +607,7 @@ InputBar - + Select a file Välj en fil @@ -617,17 +617,43 @@ Alla Filer (*) - + Failed to upload media. Please try again. Kunde inte ladda upp media. Vänligen försök igen. - InviteeItem + InviteDialog + + + Invite users to %1 + + + + + User ID to invite + Användar-ID att bjuda in + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + - - Remove - Ta bort + + Cancel + Avbryt @@ -744,28 +770,15 @@ Exempel: https://server.my:8787 SSO-inloggning misslyckades - - MemberList - - - Room members - Rumsmedlemmar - - - - OK - OK - - MessageDelegate - + Encryption enabled Kryptering aktiverad - + room name changed to: %1 rummets namn ändrat till: %1 @@ -775,7 +788,7 @@ Exempel: https://server.my:8787 tog bort rummets namn - + topic changed to: %1 ämne ändrat till: %1 @@ -785,17 +798,17 @@ Exempel: https://server.my:8787 tog bort ämne - + %1 changed the room avatar - + %1 created and configured room: %2 %1 skapade och konfigurerade rum: %2 - + %1 placed a voice call. %1 påbörjade ett röstsamtal. @@ -810,23 +823,23 @@ Exempel: https://server.my:8787 %1 påbörjade ett samtal. - + Negotiating call... Förhandlar samtal… - + %1 answered the call. %1 besvarade samtalet. - + removed borttagen - + %1 ended the call. %1 avslutade samtalet. @@ -834,7 +847,7 @@ Exempel: https://server.my:8787 MessageInput - + Hang up Lägg på @@ -855,6 +868,11 @@ Exempel: https://server.my:8787 + Stickers + + + + Emoji Emoji @@ -872,17 +890,17 @@ Exempel: https://server.my:8787 MessageView - + Edit - + React Reagera - + Reply Svara @@ -892,7 +910,7 @@ Exempel: https://server.my:8787 Alternativ - + &Copy @@ -1100,7 +1118,7 @@ Exempel: https://server.my:8787 Placeholder - + unimplemented event: ej implementerat event: @@ -1220,7 +1238,7 @@ Exempel: https://server.my:8787 ReplyPopup - + Close Stäng @@ -1233,7 +1251,7 @@ Exempel: https://server.my:8787 RoomInfo - + no version stored ingen version lagrad @@ -1241,7 +1259,7 @@ Exempel: https://server.my:8787 RoomList - + New tag @@ -1281,17 +1299,7 @@ Exempel: https://server.my:8787 - - Accept - Godkänn - - - - Decline - - - - + Status Message @@ -1341,20 +1349,42 @@ Exempel: https://server.my:8787 Användarinställningar + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1436,11 +1466,6 @@ Exempel: https://server.my:8787 Room Version - - - OK - OK - Failed to enable encryption: %1 @@ -1473,6 +1498,24 @@ Exempel: https://server.my:8787 Kunde inte ladda upp bilden: %s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1530,7 +1573,7 @@ Exempel: https://server.my:8787 StatusIndicator - + Failed Misslyckat @@ -1550,6 +1593,14 @@ Exempel: https://server.my:8787 Läst + + StickerPicker + + + Search + Sök + + Success @@ -1571,7 +1622,7 @@ Exempel: https://server.my:8787 TimelineModel - + Message redaction failed: %1 Kunde inte maskera meddelande: %1 @@ -1582,7 +1633,7 @@ Exempel: https://server.my:8787 Kunde inte kryptera event, sändning avbruten! - + Save image Spara bild @@ -1716,12 +1767,12 @@ Exempel: https://server.my:8787 %1 maskerade sin knackning. - + You joined this room. Du gick med i detta rum. - + %1 has changed their avatar and changed their display name to %2. @@ -1750,7 +1801,7 @@ Exempel: https://server.my:8787 TimelineRow - + Edited @@ -1758,17 +1809,32 @@ Exempel: https://server.my:8787 TimelineView - + No room open Inget rum öppet - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list Tillbaka till rumlista @@ -1776,7 +1842,7 @@ Exempel: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Ingen krypterad privat chatt med denna användare kunde hittas. Skapa en krypterad privat chatt med användaren och försök igen. @@ -1784,18 +1850,17 @@ Exempel: https://server.my:8787 TopBar - + Back to room list Tillbaka till rumlista - - + No room selected Inget rum markerat - + Room options Alternativ för rum @@ -1836,7 +1901,7 @@ Exempel: https://server.my:8787 UserProfile - + Global User Profile @@ -1846,7 +1911,7 @@ Exempel: https://server.my:8787 - + Verify Bekräfta @@ -1895,7 +1960,7 @@ Exempel: https://server.my:8787 UserSettings - + Default @@ -1904,7 +1969,7 @@ Exempel: https://server.my:8787 UserSettingsPage - + Minimize to tray Minimera till systemtråg @@ -2358,7 +2423,7 @@ Detta gör vanligtvis att ikonen i aktivitetsfältet animeras på något sätt.< Waiting - + Waiting for other party… Väntar på motparten… @@ -2409,7 +2474,7 @@ Detta gör vanligtvis att ikonen i aktivitetsfältet animeras på något sätt.< descriptiveTime - + Yesterday Igår @@ -2480,19 +2545,6 @@ Detta gör vanligtvis att ikonen i aktivitetsfältet animeras på något sätt.< Öppna reserven, följ stegen och bekräfta när du slutfört dem. - - dialogs::InviteUsers - - - Cancel - Avbryt - - - - User ID to invite - Användar-ID att bjuda in - - dialogs::JoinRoom diff --git a/resources/langs/nheko_zh_CN.ts b/resources/langs/nheko_zh_CN.ts index d468dfaa..c84e3c82 100644 --- a/resources/langs/nheko_zh_CN.ts +++ b/resources/langs/nheko_zh_CN.ts @@ -38,7 +38,7 @@ AwaitingVerificationConfirmation - + Awaiting Confirmation @@ -48,7 +48,7 @@ - + Cancel 取消 @@ -125,7 +125,7 @@ ChatPage - + Failed to invite user: %1 邀请用户失败: %1 @@ -157,12 +157,12 @@ - + Confirm invite - + Do you really want to invite %1 (%2)? @@ -227,12 +227,12 @@ 解禁用户: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! 缓存迁移失败! @@ -352,7 +352,7 @@ CrossSigningSecrets - + Decrypt secrets @@ -426,12 +426,12 @@ EmojiPicker - + Search - + People @@ -607,7 +607,7 @@ InputBar - + Select a file 选择一个文件 @@ -617,17 +617,43 @@ 所有文件(*) - + Failed to upload media. Please try again. - InviteeItem + InviteDialog - - Remove - 移除 + + Invite users to %1 + + + + + User ID to invite + 要邀请的用户 ID + + + + @joe:matrix.org + Example user id. The name 'joe' can be localized however you want. + + + + + Add + + + + + Invite + + + + + Cancel + 取消 @@ -740,23 +766,10 @@ Example: https://server.my:8787 - - MemberList - - - Room members - 聊天室成员 - - - - OK - - - MessageDelegate - + removed @@ -767,7 +780,7 @@ Example: https://server.my:8787 - + room name changed to: %1 @@ -777,7 +790,7 @@ Example: https://server.my:8787 - + topic changed to: %1 @@ -787,17 +800,17 @@ Example: https://server.my:8787 - + %1 changed the room avatar - + %1 created and configured room: %2 - + %1 placed a voice call. @@ -812,17 +825,17 @@ Example: https://server.my:8787 - + %1 answered the call. - + %1 ended the call. - + Negotiating call... @@ -830,7 +843,7 @@ Example: https://server.my:8787 MessageInput - + Hang up @@ -851,6 +864,11 @@ Example: https://server.my:8787 + Stickers + + + + Emoji @@ -868,17 +886,17 @@ Example: https://server.my:8787 MessageView - + Edit - + React - + Reply @@ -888,7 +906,7 @@ Example: https://server.my:8787 - + &Copy @@ -1096,7 +1114,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1216,7 +1234,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1229,7 +1247,7 @@ Example: https://server.my:8787 RoomInfo - + no version stored @@ -1237,7 +1255,7 @@ Example: https://server.my:8787 RoomList - + New tag @@ -1277,17 +1295,7 @@ Example: https://server.my:8787 - - Accept - 接受 - - - - Decline - 拒绝 - - - + Status Message @@ -1337,20 +1345,41 @@ Example: https://server.my:8787 用户设置 + + RoomMembers + + + Members of %1 + + + + + %n people in %1 + Summary above list of members + + + + + + + Invite more people + + + RoomSettings - + Room Settings - + %1 member(s) - + SETTINGS @@ -1432,11 +1461,6 @@ Example: https://server.my:8787 Room Version - - - OK - - Failed to enable encryption: %1 @@ -1469,6 +1493,24 @@ Example: https://server.my:8787 上传图像失败:%s + + RoomlistModel + + + Pending invite. + + + + + Previewing this room + + + + + No preview available + + + ScreenShare @@ -1526,7 +1568,7 @@ Example: https://server.my:8787 StatusIndicator - + Failed @@ -1546,6 +1588,14 @@ Example: https://server.my:8787 + + StickerPicker + + + Search + + + Success @@ -1567,7 +1617,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 删除消息失败:%1 @@ -1578,7 +1628,7 @@ Example: https://server.my:8787 - + Save image 保存图像 @@ -1711,12 +1761,12 @@ Example: https://server.my:8787 - + You joined this room. 您已加入此房间 - + %1 has changed their avatar and changed their display name to %2. @@ -1745,7 +1795,7 @@ Example: https://server.my:8787 TimelineRow - + Edited @@ -1753,17 +1803,32 @@ Example: https://server.my:8787 TimelineView - + No room open - + %1 member(s) - + + join the conversation + + + + + accept invite + + + + + decline invite + + + + Back to room list @@ -1771,7 +1836,7 @@ Example: https://server.my:8787 TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1779,18 +1844,17 @@ Example: https://server.my:8787 TopBar - + Back to room list - - + No room selected - + Room options 聊天室选项 @@ -1831,7 +1895,7 @@ Example: https://server.my:8787 UserProfile - + Global User Profile @@ -1841,7 +1905,7 @@ Example: https://server.my:8787 - + Verify @@ -1890,7 +1954,7 @@ Example: https://server.my:8787 UserSettings - + Default @@ -1899,7 +1963,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray 最小化至托盘 @@ -2345,7 +2409,7 @@ This usually causes the application icon in the task bar to animate in some fash Waiting - + Waiting for other party… @@ -2396,7 +2460,7 @@ This usually causes the application icon in the task bar to animate in some fash descriptiveTime - + Yesterday @@ -2467,19 +2531,6 @@ This usually causes the application icon in the task bar to animate in some fash - - dialogs::InviteUsers - - - Cancel - 取消 - - - - User ID to invite - 要邀请的用户 ID - - dialogs::JoinRoom diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index c6b42d29..5aaf0d6d 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -29,7 +29,7 @@ ApplicationWindow { close(); } - title: qsTr("Invite users to ") + plainRoomName + title: qsTr("Invite users to %1").arg(plainRoomName) x: MainWindow.x + (MainWindow.width / 2) - (width / 2) y: MainWindow.y + (MainWindow.height / 2) - (height / 2) height: 380 diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 3758cb0b..bc8a90d2 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -14,7 +14,7 @@ ApplicationWindow { property MemberList members - title: qsTr("Members of ") + members.roomName + title: qsTr("Members of %1").arg(members.roomName) x: MainWindow.x + (MainWindow.width / 2) - (width / 2) y: MainWindow.y + (MainWindow.height / 2) - (height / 2) height: 650 @@ -46,7 +46,7 @@ ApplicationWindow { ElidedLabel { font.pixelSize: fontMetrics.font.pixelSize * 2 - fullText: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + members.roomName + fullText: qsTr("%n people in %1", "Summary above list of members", members.memberCount).arg(members.roomName) Layout.alignment: Qt.AlignHCenter elideWidth: parent.width - Nheko.paddingMedium } -- cgit 1.4.1 From 44be4c1f4a4e1ef60fbb6c1f51adc93e5a555f14 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Wed, 21 Jul 2021 18:56:20 -0400 Subject: Move various room auxiliary functions to TimelineManager --- resources/qml/RoomMembers.qml | 5 ++--- resources/qml/RoomSettings.qml | 2 +- resources/qml/Root.qml | 2 +- resources/qml/TopBar.qml | 10 +++++----- src/timeline/TimelineModel.cpp | 25 ------------------------- src/timeline/TimelineModel.h | 7 ------- src/timeline/TimelineViewManager.cpp | 28 ++++++++++++++++++++++++++++ src/timeline/TimelineViewManager.h | 7 +++++++ 8 files changed, 44 insertions(+), 42 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml index 3758cb0b..5bf847ca 100644 --- a/resources/qml/RoomMembers.qml +++ b/resources/qml/RoomMembers.qml @@ -41,7 +41,7 @@ ApplicationWindow { displayName: members.roomName Layout.alignment: Qt.AlignHCenter url: members.avatarUrl.replace("mxc://", "image://MxcImage/") - onClicked: Rooms.currentRoom.openRoomSettings(members.roomId) + onClicked: TimelineManager.openRoomSettings(members.roomId) } ElidedLabel { @@ -57,7 +57,7 @@ ApplicationWindow { hoverEnabled: true ToolTip.visible: hovered ToolTip.text: qsTr("Invite more people") - onClicked: Rooms.currentRoom.openInviteUsers() + onClicked: TimelineManager.openInviteUsers(members.roomId) } ScrollView { @@ -121,7 +121,6 @@ ApplicationWindow { footer: Item { width: parent.width visible: (members.numUsersLoaded < members.memberCount) && members.loadingMoreMembers - // use the default height if it's visible, otherwise no height at all height: membersLoadingSpinner.height anchors.margins: Nheko.paddingMedium diff --git a/resources/qml/RoomSettings.qml b/resources/qml/RoomSettings.qml index 8746d4d3..b4936f3e 100644 --- a/resources/qml/RoomSettings.qml +++ b/resources/qml/RoomSettings.qml @@ -107,7 +107,7 @@ ApplicationWindow { Layout.alignment: Qt.AlignHCenter TapHandler { - onTapped: Rooms.currentRoom.openRoomMembers(roomSettings.roomId) + onTapped: TimelineManager.openRoomMembers(roomSettings.roomId) } CursorShape { diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index f71c18e2..8e226639 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -133,7 +133,7 @@ Page { } Connections { - target: Rooms.currentRoom + target: TimelineManager onOpenRoomMembersDialog: { var membersDialog = roomMembersComponent.createObject(timelineRoot, { "members": members, diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml index 48491f84..8543d02a 100644 --- a/resources/qml/TopBar.qml +++ b/resources/qml/TopBar.qml @@ -24,7 +24,7 @@ Rectangle { TapHandler { onSingleTapped: { if (room) - room.openRoomSettings(); + TimelineManager.openRoomSettings(room.roomId); eventPoint.accepted = true; } @@ -66,7 +66,7 @@ Rectangle { displayName: roomName onClicked: { if (room) - room.openRoomSettings(); + TimelineManager.openRoomSettings(room.roomId); } } @@ -111,12 +111,12 @@ Rectangle { Platform.MenuItem { visible: room ? room.permissions.canInvite() : false text: qsTr("Invite users") - onTriggered: Rooms.currentRoom.openInviteUsers() + onTriggered: TimelineManager.openInviteUsers(room.roomId) } Platform.MenuItem { text: qsTr("Members") - onTriggered: Rooms.currentRoom.openRoomMembers() + onTriggered: TimelineManager.openRoomMembers(room.roomId) } Platform.MenuItem { @@ -126,7 +126,7 @@ Rectangle { Platform.MenuItem { text: qsTr("Settings") - onTriggered: room.openRoomSettings() + onTriggered: TimelineManager.openRoomSettings(room.roomId) } } diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index e9fa4a05..ee5564a5 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -1066,31 +1066,6 @@ TimelineModel::openUserProfile(QString userid) emit manager_->openProfile(userProfile); } -void -TimelineModel::openRoomMembers(QString room_id) -{ - MemberList *memberList = new MemberList(room_id == QString() ? roomId() : room_id, this); - emit openRoomMembersDialog(memberList); -} - -void -TimelineModel::openRoomSettings(QString room_id) -{ - RoomSettings *settings = new RoomSettings(room_id == QString() ? roomId() : room_id, this); - connect(this, &TimelineModel::roomAvatarUrlChanged, settings, &RoomSettings::avatarChanged); - emit openRoomSettingsDialog(settings); -} - -void -TimelineModel::openInviteUsers(QString roomId) -{ - InviteesModel *model = new InviteesModel{this}; - connect(model, &InviteesModel::accept, this, [this, model, roomId]() { - emit manager_->inviteUsers(roomId == QString() ? room_id_ : roomId, model->mxids()); - }); - emit openInviteUsersDialog(model); -} - void TimelineModel::replyAction(QString id) { diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 077245cb..0e2ce153 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -239,9 +239,6 @@ public: Q_INVOKABLE void forwardMessage(QString eventId, QString roomId); Q_INVOKABLE void viewDecryptedRawMessage(QString id) const; Q_INVOKABLE void openUserProfile(QString userid); - Q_INVOKABLE void openRoomMembers(QString room_id = QString()); - Q_INVOKABLE void openRoomSettings(QString room_id = QString()); - Q_INVOKABLE void openInviteUsers(QString roomId = QString()); Q_INVOKABLE void editAction(QString id); Q_INVOKABLE void replyAction(QString id); Q_INVOKABLE void readReceiptsAction(QString id) const; @@ -358,10 +355,6 @@ signals: void lastMessageChanged(); void notificationsChanged(); - void openRoomMembersDialog(MemberList *members); - void openRoomSettingsDialog(RoomSettings *settings); - void openInviteUsersDialog(InviteesModel *invitees); - void newMessageToSend(mtx::events::collections::TimelineEvents event); void addPendingMessageToStore(mtx::events::collections::TimelineEvents event); void updateFlowEventId(std::string event_id); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 64493e5b..b1643798 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -351,6 +351,34 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par &TimelineViewManager::openImageOverlayInternal); } +void +TimelineViewManager::openRoomMembers(QString room_id) +{ + MemberList *memberList = new MemberList(room_id, this); + emit openRoomMembersDialog(memberList); +} + +void +TimelineViewManager::openRoomSettings(QString room_id) +{ + RoomSettings *settings = new RoomSettings(room_id, this); + connect(rooms_->getRoomById(room_id).data(), + &TimelineModel::roomAvatarUrlChanged, + settings, + &RoomSettings::avatarChanged); + emit openRoomSettingsDialog(settings); +} + +void +TimelineViewManager::openInviteUsers(QString roomId) +{ + InviteesModel *model = new InviteesModel{this}; + connect(model, &InviteesModel::accept, this, [this, model, roomId]() { + emit inviteUsers(roomId, model->mxids()); + }); + emit openInviteUsersDialog(model); +} + void TimelineViewManager::setVideoCallItem() { diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 945ba2d5..374685e3 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -64,6 +64,10 @@ public: Q_INVOKABLE QString userPresence(QString id) const; Q_INVOKABLE QString userStatus(QString id) const; + Q_INVOKABLE void openRoomMembers(QString room_id); + Q_INVOKABLE void openRoomSettings(QString room_id); + Q_INVOKABLE void openInviteUsers(QString roomId); + Q_INVOKABLE void focusMessageInput(); Q_INVOKABLE void openLeaveRoomDialog(QString roomid) const; Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow); @@ -85,6 +89,9 @@ signals: void focusChanged(); void focusInput(); void openImageOverlayInternalCb(QString eventId, QImage img); + void openRoomMembersDialog(MemberList *members); + void openRoomSettingsDialog(RoomSettings *settings); + void openInviteUsersDialog(InviteesModel *invitees); void openProfile(UserProfile *profile); public slots: -- cgit 1.4.1 From 0971fd0fccddf1aa8c88780961df12803a132aa6 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Wed, 21 Jul 2021 20:37:36 -0400 Subject: Pad the loading spinner --- resources/qml/MessageView.qml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index 564c8dc7..d2c97d57 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -477,12 +477,22 @@ ScrollView { } - footer: Spinner { + footer: Item { anchors.horizontalCenter: parent.horizontalCenter - running: chat.model && chat.model.paginationInProgress - foreground: Nheko.colors.mid + anchors.margins: Nheko.paddingLarge visible: chat.model && chat.model.paginationInProgress - z: 3 + // hacky, but works + height: loadingSpinner.height + 2 * Nheko.paddingLarge + + Spinner { + id: loadingSpinner + + anchors.centerIn: parent + anchors.margins: Nheko.paddingLarge + running: chat.model && chat.model.paginationInProgress + foreground: Nheko.colors.mid + z: 3 + } } } -- cgit 1.4.1 From bbecadf1a8c3d78609a6112a879288f841b592f4 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Wed, 21 Jul 2021 20:38:18 -0400 Subject: Add functionality for loading global user profile where needed This is so viewing profiles from the invite dialog will work as expected. --- resources/qml/InviteDialog.qml | 2 +- src/timeline/TimelineViewManager.cpp | 6 ++++++ src/timeline/TimelineViewManager.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml index 5aaf0d6d..50287ad5 100644 --- a/resources/qml/InviteDialog.qml +++ b/resources/qml/InviteDialog.qml @@ -107,7 +107,7 @@ ApplicationWindow { userid: model.mxid url: model.avatarUrl.replace("mxc://", "image://MxcImage/") displayName: model.displayName - onClicked: Rooms.currentRoom.openUserProfile(model.mxid) + onClicked: TimelineManager.openGlobalUserProfile(model.mxid) } ColumnLayout { diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index b1643798..da3ba282 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -379,6 +379,12 @@ TimelineViewManager::openInviteUsers(QString roomId) emit openInviteUsersDialog(model); } +void TimelineViewManager::openGlobalUserProfile(QString userId) +{ + UserProfile *profile = new UserProfile{QString{}, userId, this}; + emit openProfile(profile); +} + void TimelineViewManager::setVideoCallItem() { diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 374685e3..bfc116b1 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -67,6 +67,7 @@ public: Q_INVOKABLE void openRoomMembers(QString room_id); Q_INVOKABLE void openRoomSettings(QString room_id); Q_INVOKABLE void openInviteUsers(QString roomId); + Q_INVOKABLE void openGlobalUserProfile(QString userId); Q_INVOKABLE void focusMessageInput(); Q_INVOKABLE void openLeaveRoomDialog(QString roomid) const; -- cgit 1.4.1 From 0ce7d02abed2f687a1a9795da8ab8e2ec96b0d65 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Thu, 22 Jul 2021 07:55:12 -0400 Subject: make lint --- resources/qml/MessageView.qml | 1 + src/timeline/TimelineViewManager.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index d2c97d57..50cbd371 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -493,6 +493,7 @@ ScrollView { foreground: Nheko.colors.mid z: 3 } + } } diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index da3ba282..c08cfd53 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -379,7 +379,8 @@ TimelineViewManager::openInviteUsers(QString roomId) emit openInviteUsersDialog(model); } -void TimelineViewManager::openGlobalUserProfile(QString userId) +void +TimelineViewManager::openGlobalUserProfile(QString userId) { UserProfile *profile = new UserProfile{QString{}, userId, this}; emit openProfile(profile); -- cgit 1.4.1 From 0ac550ecbb77c8aa3e3427c466f1be2c436a42aa Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 22 Jul 2021 15:07:33 +0200 Subject: Show confirmation dialog when leaving a room via the context menu --- resources/qml/RoomList.qml | 12 +++++++++++- resources/qml/RoomSettings.qml | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'resources/qml') diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index 9dac5830..2be5fe92 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -61,9 +61,19 @@ Page { } } + Platform.MessageDialog { + id: leaveRoomDialog + + title: qsTr("Leave Room") + text: qsTr("Are you sure you want to leave this room?") + modality: Qt.Modal + onAccepted: Rooms.leave(roomContextMenu.roomid) + buttons: Dialog.Ok | Dialog.Cancel + } + Platform.MenuItem { text: qsTr("Leave room") - onTriggered: Rooms.leave(roomContextMenu.roomid) + onTriggered: leaveRoomDialog.open() } Platform.MenuSeparator { diff --git a/resources/qml/RoomSettings.qml b/resources/qml/RoomSettings.qml index b4936f3e..11b9fa2a 100644 --- a/resources/qml/RoomSettings.qml +++ b/resources/qml/RoomSettings.qml @@ -219,7 +219,7 @@ ApplicationWindow { title: qsTr("End-to-End Encryption") text: qsTr("Encryption is currently experimental and things might break unexpectedly.
Please take note that it can't be disabled afterwards.") - modality: Qt.NonModal + modality: Qt.Modal onAccepted: { if (roomSettings.isEncryptionEnabled) return ; -- cgit 1.4.1 From 50cc0fca3b01f65fd2fe0707736160c92bc35f21 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 22 Jul 2021 15:31:07 +0200 Subject: Fix emoji picker not connected to input --- resources/qml/MessageInput.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'resources/qml') diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index c135aff9..58d71a4e 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml @@ -355,7 +355,7 @@ Rectangle { image: ":/icons/icons/ui/smile.png" ToolTip.visible: hovered ToolTip.text: qsTr("Emoji") - onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(function(emoji) { + onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(emojiButton, function(emoji) { messageInput.insert(messageInput.cursorPosition, emoji); TimelineManager.focusMessageInput(); }) -- cgit 1.4.1 From eafbab6ae128dd5b14f145ba9214a6673e982951 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 21 Jul 2021 13:37:57 +0200 Subject: Add menu to enable or disable stickers globally --- CMakeLists.txt | 4 + resources/qml/RoomSettings.qml | 11 + resources/qml/Root.qml | 15 ++ resources/qml/dialogs/ImagePackSettingsDialog.qml | 309 ++++++++++++++++++++++ resources/res.qrc | 1 + src/Cache.cpp | 33 ++- src/CacheStructs.h | 5 +- src/Cache_p.h | 9 +- src/CombinedImagePackModel.cpp | 5 +- src/ImagePackListModel.cpp | 76 ++++++ src/ImagePackListModel.h | 37 +++ src/SingleImagePackModel.cpp | 100 +++++++ src/SingleImagePackModel.h | 61 +++++ src/timeline/TimelineViewManager.cpp | 20 ++ src/timeline/TimelineViewManager.h | 3 + src/ui/RoomSettings.h | 2 +- 16 files changed, 674 insertions(+), 17 deletions(-) create mode 100644 resources/qml/dialogs/ImagePackSettingsDialog.qml create mode 100644 src/ImagePackListModel.cpp create mode 100644 src/ImagePackListModel.h create mode 100644 src/SingleImagePackModel.cpp create mode 100644 src/SingleImagePackModel.h (limited to 'resources/qml') diff --git a/CMakeLists.txt b/CMakeLists.txt index b802d37c..90ad1276 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,8 @@ set(SRC_FILES src/RegisterPage.cpp src/SSOHandler.cpp src/CombinedImagePackModel.cpp + src/SingleImagePackModel.cpp + src/ImagePackListModel.cpp src/TrayIcon.cpp src/UserSettingsPage.cpp src/UsersModel.cpp @@ -559,6 +561,8 @@ qt5_wrap_cpp(MOC_HEADERS src/RegisterPage.h src/SSOHandler.h src/CombinedImagePackModel.h + src/SingleImagePackModel.h + src/ImagePackListModel.h src/TrayIcon.h src/UserSettingsPage.h src/UsersModel.h diff --git a/resources/qml/RoomSettings.qml b/resources/qml/RoomSettings.qml index 11b9fa2a..accb5637 100644 --- a/resources/qml/RoomSettings.qml +++ b/resources/qml/RoomSettings.qml @@ -249,6 +249,17 @@ ApplicationWindow { Layout.alignment: Qt.AlignRight } + MatrixText { + text: qsTr("Sticker & Emote Settings") + } + + Button { + text: qsTr("Change") + ToolTip.text: qsTr("Change what packs are enabled, remove packs or create new ones") + onClicked: TimelineManager.openImagePackSettings(roomSettings.roomId) + Layout.alignment: Qt.AlignRight + } + Item { // for adding extra space between sections Layout.fillWidth: true diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index 8e226639..1793d9bc 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -4,6 +4,7 @@ import "./delegates" import "./device-verification" +import "./dialogs" import "./emoji" import "./voip" import Qt.labs.platform 1.1 as Platform @@ -87,6 +88,14 @@ Page { } + Component { + id: packSettingsComponent + + ImagePackSettingsDialog { + } + + } + Shortcut { sequence: "Ctrl+K" onActivated: { @@ -120,6 +129,12 @@ Page { }); userProfile.show(); } + onShowImagePackSettings: { + var packSet = packSettingsComponent.createObject(timelineRoot, { + "packlist": packlist + }); + packSet.show(); + } } Connections { diff --git a/resources/qml/dialogs/ImagePackSettingsDialog.qml b/resources/qml/dialogs/ImagePackSettingsDialog.qml new file mode 100644 index 00000000..c4b4a885 --- /dev/null +++ b/resources/qml/dialogs/ImagePackSettingsDialog.qml @@ -0,0 +1,309 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import ".." +import "../components" +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import im.nheko 1.0 + +ApplicationWindow { + id: win + + property ImagePackListModel packlist + property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.3) + property SingleImagePackModel currentPack: packlist.packAt(currentPackIndex) + property int currentPackIndex: 0 + readonly property int stickerDim: 128 + readonly property int stickerDimPad: 128 + Nheko.paddingSmall + + title: qsTr("Image pack settings") + x: MainWindow.x + (MainWindow.width / 2) - (width / 2) + y: MainWindow.y + (MainWindow.height / 2) - (height / 2) + height: 400 + width: 600 + palette: Nheko.colors + color: Nheko.colors.base + modality: Qt.NonModal + flags: Qt.Dialog + + AdaptiveLayout { + id: adaptiveView + + anchors.fill: parent + singlePageMode: false + pageIndex: 0 + + AdaptiveLayoutElement { + id: packlistC + + visible: Settings.groupView + minimumWidth: 200 + collapsedWidth: 200 + preferredWidth: 300 + maximumWidth: 300 + + ListView { + model: packlist + clip: true + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + + delegate: Rectangle { + id: packItem + + property color background: Nheko.colors.window + property color importantText: Nheko.colors.text + property color unimportantText: Nheko.colors.buttonText + property color bubbleBackground: Nheko.colors.highlight + property color bubbleText: Nheko.colors.highlightedText + required property string displayName + required property string avatarUrl + required property bool fromAccountData + required property bool fromCurrentRoom + required property int index + + color: background + height: avatarSize + 2 * Nheko.paddingMedium + width: ListView.view.width + state: "normal" + states: [ + State { + name: "highlight" + when: hovered.hovered && !(index == currentPackIndex) + + PropertyChanges { + target: packItem + background: Nheko.colors.dark + importantText: Nheko.colors.brightText + unimportantText: Nheko.colors.brightText + bubbleBackground: Nheko.colors.highlight + bubbleText: Nheko.colors.highlightedText + } + + }, + State { + name: "selected" + when: index == currentPackIndex + + PropertyChanges { + target: packItem + background: Nheko.colors.highlight + importantText: Nheko.colors.highlightedText + unimportantText: Nheko.colors.highlightedText + bubbleBackground: Nheko.colors.highlightedText + bubbleText: Nheko.colors.highlight + } + + } + ] + + TapHandler { + margin: -Nheko.paddingSmall + onSingleTapped: currentPackIndex = index + } + + HoverHandler { + id: hovered + } + + RowLayout { + spacing: Nheko.paddingMedium + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + + Avatar { + // In the future we could show an online indicator by setting the userid for the avatar + //userid: Nheko.currentUser.userid + + id: avatar + + enabled: false + Layout.alignment: Qt.AlignVCenter + height: avatarSize + width: avatarSize + url: avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: packItem.displayName + } + + ColumnLayout { + id: textContent + + Layout.alignment: Qt.AlignLeft + Layout.fillWidth: true + Layout.minimumWidth: 100 + width: parent.width - avatar.width + Layout.preferredWidth: parent.width - avatar.width + spacing: Nheko.paddingSmall + + RowLayout { + Layout.fillWidth: true + spacing: 0 + + ElidedLabel { + Layout.alignment: Qt.AlignBottom + color: packItem.importantText + elideWidth: textContent.width - Nheko.paddingMedium + fullText: displayName + textFormat: Text.PlainText + } + + Item { + Layout.fillWidth: true + } + + } + + RowLayout { + Layout.fillWidth: true + spacing: 0 + + ElidedLabel { + color: packItem.unimportantText + font.pixelSize: fontMetrics.font.pixelSize * 0.9 + elideWidth: textContent.width - Nheko.paddingSmall + fullText: { + if (fromAccountData) + return qsTr("Private pack"); + else if (fromCurrentRoom) + return qsTr("Pack from this room"); + else + return qsTr("Globally enabled pack"); + } + textFormat: Text.PlainText + } + + Item { + Layout.fillWidth: true + } + + } + + } + + } + + } + + } + + } + + AdaptiveLayoutElement { + id: packinfoC + + Rectangle { + color: Nheko.colors.window + + ColumnLayout { + id: packinfo + + property string packName: currentPack ? currentPack.packname : "" + property string avatarUrl: currentPack ? currentPack.avatarUrl : "" + + anchors.fill: parent + anchors.margins: Nheko.paddingLarge + spacing: Nheko.paddingLarge + + Avatar { + url: packinfo.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: packinfo.packName + height: 100 + width: 100 + Layout.alignment: Qt.AlignHCenter + enabled: false + } + + MatrixText { + text: packinfo.packName + font.pixelSize: 24 + Layout.alignment: Qt.AlignHCenter + } + + GridLayout { + Layout.alignment: Qt.AlignHCenter + visible: currentPack && currentPack.roomid != "" + columns: 2 + rowSpacing: Nheko.paddingMedium + + MatrixText { + text: qsTr("Enable globally") + } + + ToggleButton { + ToolTip.text: qsTr("Enables this pack to be used in all rooms") + checked: currentPack ? currentPack.isGloballyEnabled : false + onClicked: currentPack.isGloballyEnabled = !currentPack.isGloballyEnabled + Layout.alignment: Qt.AlignRight + } + + } + + GridView { + Layout.fillHeight: true + Layout.fillWidth: true + model: currentPack + cellWidth: stickerDimPad + cellHeight: stickerDimPad + boundsBehavior: Flickable.StopAtBounds + clip: true + currentIndex: -1 // prevent sorting from stealing focus + cacheBuffer: 500 + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + + // Individual emoji + delegate: AbstractButton { + width: stickerDim + height: stickerDim + hoverEnabled: true + ToolTip.text: ":" + model.shortcode + ": - " + model.body + ToolTip.visible: hovered + + contentItem: Image { + height: stickerDim + width: stickerDim + source: model.url.replace("mxc://", "image://MxcImage/") + fillMode: Image.PreserveAspectFit + } + + background: Rectangle { + anchors.fill: parent + color: hovered ? Nheko.colors.highlight : 'transparent' + radius: 5 + } + + } + + } + + } + + } + + } + + } + + footer: DialogButtonBox { + id: buttons + + Button { + text: qsTr("Close") + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + onClicked: win.close() + } + + } + +} diff --git a/resources/res.qrc b/resources/res.qrc index f8c040e4..5d37c397 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -160,6 +160,7 @@ qml/device-verification/Failed.qml qml/device-verification/Success.qml qml/dialogs/InputDialog.qml + qml/dialogs/ImagePackSettingsDialog.qml qml/ui/Ripple.qml qml/ui/Spinner.qml qml/ui/animations/BlinkAnimation.qml diff --git a/src/Cache.cpp b/src/Cache.cpp index 0bcf9fbf..d651b182 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -3383,26 +3383,30 @@ Cache::getChildRoomIds(const std::string &room_id) } std::vector -Cache::getImagePacks(const std::string &room_id, bool stickers) +Cache::getImagePacks(const std::string &room_id, std::optional stickers) { auto txn = ro_txn(env_); std::vector infos; - auto addPack = [&infos, stickers](const mtx::events::msc2545::ImagePack &pack) { - if (!pack.pack || (stickers ? pack.pack->is_sticker() : pack.pack->is_emoji())) { + auto addPack = [&infos, stickers](const mtx::events::msc2545::ImagePack &pack, + const std::string &source_room, + const std::string &state_key) { + if (!pack.pack || !stickers.has_value() || + (stickers.value() ? pack.pack->is_sticker() : pack.pack->is_emoji())) { ImagePackInfo info; - if (pack.pack) - info.packname = pack.pack->display_name; + info.source_room = source_room; + info.state_key = state_key; + info.pack.pack = pack.pack; for (const auto &img : pack.images) { if (img.second.overrides_usage() && (stickers ? !img.second.is_sticker() : !img.second.is_emoji())) continue; - info.images.insert(img); + info.pack.images.insert(img); } - if (!info.images.empty()) + if (!info.pack.images.empty()) infos.push_back(std::move(info)); } }; @@ -3414,7 +3418,7 @@ Cache::getImagePacks(const std::string &room_id, bool stickers) std::get_if>( &*accountpack); if (tmp) - addPack(tmp->content); + addPack(tmp->content, "", ""); } // packs from rooms, that were enabled globally @@ -3433,7 +3437,7 @@ Cache::getImagePacks(const std::string &room_id, bool stickers) if (auto pack = getStateEvent( txn, room_id2, state_id)) - addPack(pack->content); + addPack(pack->content, room_id2, state_id); } } } @@ -3441,16 +3445,23 @@ Cache::getImagePacks(const std::string &room_id, bool stickers) // packs from current room if (auto pack = getStateEvent(txn, room_id)) { - addPack(pack->content); + addPack(pack->content, room_id, ""); } for (const auto &pack : getStateEventsWithType(txn, room_id)) { - addPack(pack.content); + addPack(pack.content, room_id, pack.state_key); } return infos; } +std::optional +Cache::getAccountData(mtx::events::EventType type, const std::string &room_id) +{ + auto txn = ro_txn(env_); + return getAccountData(txn, type, room_id); +} + std::optional Cache::getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id) { diff --git a/src/CacheStructs.h b/src/CacheStructs.h index f274d70f..4a5c5c76 100644 --- a/src/CacheStructs.h +++ b/src/CacheStructs.h @@ -113,6 +113,7 @@ struct RoomSearchResult struct ImagePackInfo { - std::string packname; - std::map images; + mtx::events::msc2545::ImagePack pack; + std::string source_room; + std::string state_key; }; diff --git a/src/Cache_p.h b/src/Cache_p.h index 13fbc371..c9d42202 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -97,6 +97,12 @@ public: return getStateEvent(txn, room_id, state_key); } + //! retrieve a specific event from account data + //! pass empty room_id for global account data + std::optional getAccountData( + mtx::events::EventType type, + const std::string &room_id = ""); + //! Retrieve member info from a room. std::vector getMembers(const std::string &room_id, std::size_t startIndex = 0, @@ -225,7 +231,8 @@ public: std::vector getParentRoomIds(const std::string &room_id); std::vector getChildRoomIds(const std::string &room_id); - std::vector getImagePacks(const std::string &room_id, bool stickers); + std::vector getImagePacks(const std::string &room_id, + std::optional stickers); //! Mark a room that uses e2e encryption. void setEncryptedRoom(lmdb::txn &txn, const std::string &room_id); diff --git a/src/CombinedImagePackModel.cpp b/src/CombinedImagePackModel.cpp index c5b5b886..341a34ec 100644 --- a/src/CombinedImagePackModel.cpp +++ b/src/CombinedImagePackModel.cpp @@ -16,9 +16,10 @@ CombinedImagePackModel::CombinedImagePackModel(const std::string &roomId, auto packs = cache::client()->getImagePacks(room_id, stickers); for (const auto &pack : packs) { - QString packname = QString::fromStdString(pack.packname); + QString packname = + pack.pack.pack ? QString::fromStdString(pack.pack.pack->display_name) : ""; - for (const auto &img : pack.images) { + for (const auto &img : pack.pack.images) { ImageDesc i{}; i.shortcode = QString::fromStdString(img.first); i.packname = packname; diff --git a/src/ImagePackListModel.cpp b/src/ImagePackListModel.cpp new file mode 100644 index 00000000..89f1f68e --- /dev/null +++ b/src/ImagePackListModel.cpp @@ -0,0 +1,76 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ImagePackListModel.h" + +#include + +#include "Cache_p.h" +#include "SingleImagePackModel.h" + +ImagePackListModel::ImagePackListModel(const std::string &roomId, QObject *parent) + : QAbstractListModel(parent) + , room_id(roomId) +{ + auto packs_ = cache::client()->getImagePacks(room_id, std::nullopt); + + for (const auto &pack : packs_) { + packs.push_back( + QSharedPointer(new SingleImagePackModel(pack))); + } +} + +int +ImagePackListModel::rowCount(const QModelIndex &) const +{ + return (int)packs.size(); +} + +QHash +ImagePackListModel::roleNames() const +{ + return { + {Roles::DisplayName, "displayName"}, + {Roles::AvatarUrl, "avatarUrl"}, + {Roles::FromAccountData, "fromAccountData"}, + {Roles::FromCurrentRoom, "fromCurrentRoom"}, + {Roles::StateKey, "statekey"}, + {Roles::RoomId, "roomid"}, + }; +} + +QVariant +ImagePackListModel::data(const QModelIndex &index, int role) const +{ + if (hasIndex(index.row(), index.column(), index.parent())) { + const auto &pack = packs.at(index.row()); + switch (role) { + case Roles::DisplayName: + return pack->packname(); + case Roles::AvatarUrl: + return pack->avatarUrl(); + case Roles::FromAccountData: + return pack->roomid().isEmpty(); + case Roles::FromCurrentRoom: + return pack->roomid().toStdString() == this->room_id; + case Roles::StateKey: + return pack->statekey(); + case Roles::RoomId: + return pack->roomid(); + default: + return {}; + } + } + return {}; +} + +SingleImagePackModel * +ImagePackListModel::packAt(int row) +{ + if (row < 0 || static_cast(row) >= packs.size()) + return {}; + auto e = packs.at(row).get(); + QQmlEngine::setObjectOwnership(e, QQmlEngine::CppOwnership); + return e; +} diff --git a/src/ImagePackListModel.h b/src/ImagePackListModel.h new file mode 100644 index 00000000..0a044690 --- /dev/null +++ b/src/ImagePackListModel.h @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include +#include + +class SingleImagePackModel; +class ImagePackListModel : public QAbstractListModel +{ + Q_OBJECT +public: + enum Roles + { + DisplayName = Qt::UserRole, + AvatarUrl, + FromAccountData, + FromCurrentRoom, + StateKey, + RoomId, + }; + + ImagePackListModel(const std::string &roomId, QObject *parent = nullptr); + QHash roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + + Q_INVOKABLE SingleImagePackModel *packAt(int row); + +private: + std::string room_id; + + std::vector> packs; +}; diff --git a/src/SingleImagePackModel.cpp b/src/SingleImagePackModel.cpp new file mode 100644 index 00000000..ba873c19 --- /dev/null +++ b/src/SingleImagePackModel.cpp @@ -0,0 +1,100 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "SingleImagePackModel.h" + +#include "Cache_p.h" +#include "MatrixClient.h" + +SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent) + : QAbstractListModel(parent) + , roomid_(std::move(pack_.source_room)) + , statekey_(std::move(pack_.state_key)) + , pack(std::move(pack_.pack)) +{ + if (!pack.pack) + pack.pack = mtx::events::msc2545::ImagePack::PackDescription{}; + + for (const auto &e : pack.images) + shortcodes.push_back(e.first); +} + +int +SingleImagePackModel::rowCount(const QModelIndex &) const +{ + return (int)shortcodes.size(); +} + +QHash +SingleImagePackModel::roleNames() const +{ + return { + {Roles::Url, "url"}, + {Roles::ShortCode, "shortCode"}, + {Roles::Body, "body"}, + {Roles::IsEmote, "isEmote"}, + {Roles::IsSticker, "isSticker"}, + }; +} + +QVariant +SingleImagePackModel::data(const QModelIndex &index, int role) const +{ + if (hasIndex(index.row(), index.column(), index.parent())) { + const auto &img = pack.images.at(shortcodes.at(index.row())); + switch (role) { + case Url: + return QString::fromStdString(img.url); + case ShortCode: + return QString::fromStdString(shortcodes.at(index.row())); + case Body: + return QString::fromStdString(img.body); + case IsEmote: + return img.overrides_usage() ? img.is_emoji() : pack.pack->is_emoji(); + case IsSticker: + return img.overrides_usage() ? img.is_sticker() : pack.pack->is_sticker(); + default: + return {}; + } + } + return {}; +} + +bool +SingleImagePackModel::isGloballyEnabled() const +{ + if (auto roomPacks = + cache::client()->getAccountData(mtx::events::EventType::ImagePackRooms)) { + if (auto tmp = std::get_if< + mtx::events::EphemeralEvent>( + &*roomPacks)) { + if (tmp->content.rooms.count(roomid_) && + tmp->content.rooms.at(roomid_).count(statekey_)) + return true; + } + } + return false; +} +void +SingleImagePackModel::setGloballyEnabled(bool enabled) +{ + mtx::events::msc2545::ImagePackRooms content{}; + if (auto roomPacks = + cache::client()->getAccountData(mtx::events::EventType::ImagePackRooms)) { + if (auto tmp = std::get_if< + mtx::events::EphemeralEvent>( + &*roomPacks)) { + content = tmp->content; + } + } + + if (enabled) + content.rooms[roomid_][statekey_] = {}; + else + content.rooms[roomid_].erase(statekey_); + + http::client()->put_account_data(content, [this](mtx::http::RequestErr) { + // emit this->globallyEnabledChanged(); + }); +} diff --git a/src/SingleImagePackModel.h b/src/SingleImagePackModel.h new file mode 100644 index 00000000..e0c791ba --- /dev/null +++ b/src/SingleImagePackModel.h @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include + +#include + +#include "CacheStructs.h" + +class SingleImagePackModel : public QAbstractListModel +{ + Q_OBJECT + + Q_PROPERTY(QString roomid READ roomid CONSTANT) + Q_PROPERTY(QString statekey READ statekey CONSTANT) + Q_PROPERTY(QString attribution READ statekey CONSTANT) + Q_PROPERTY(QString packname READ packname CONSTANT) + Q_PROPERTY(QString avatarUrl READ avatarUrl CONSTANT) + Q_PROPERTY(bool isStickerPack READ isStickerPack CONSTANT) + Q_PROPERTY(bool isEmotePack READ isEmotePack CONSTANT) + Q_PROPERTY(bool isGloballyEnabled READ isGloballyEnabled WRITE setGloballyEnabled NOTIFY + globallyEnabledChanged) +public: + enum Roles + { + Url = Qt::UserRole, + ShortCode, + Body, + IsEmote, + IsSticker, + }; + + SingleImagePackModel(ImagePackInfo pack_, QObject *parent = nullptr); + QHash roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + + QString roomid() const { return QString::fromStdString(roomid_); } + QString statekey() const { return QString::fromStdString(statekey_); } + QString packname() const { return QString::fromStdString(pack.pack->display_name); } + QString attribution() const { return QString::fromStdString(pack.pack->attribution); } + QString avatarUrl() const { return QString::fromStdString(pack.pack->avatar_url); } + bool isStickerPack() const { return pack.pack->is_sticker(); } + bool isEmotePack() const { return pack.pack->is_emoji(); } + + bool isGloballyEnabled() const; + void setGloballyEnabled(bool enabled); + +signals: + void globallyEnabledChanged(); + +private: + std::string roomid_; + std::string statekey_; + + mtx::events::msc2545::ImagePack pack; + std::vector shortcodes; +}; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 2da7d789..4353ef62 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -20,12 +20,14 @@ #include "DelegateChooser.h" #include "DeviceVerificationFlow.h" #include "EventAccessors.h" +#include "ImagePackListModel.h" #include "InviteesModel.h" #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" #include "MxcImageProvider.h" #include "RoomsModel.h" +#include "SingleImagePackModel.h" #include "UserSettingsPage.h" #include "UsersModel.h" #include "dialogs/ImageOverlay.h" @@ -185,6 +187,18 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "Room Settings needs to be instantiated on the C++ side"); qmlRegisterUncreatableType( "im.nheko", 1, 0, "Room", "Room needs to be instantiated on the C++ side"); + qmlRegisterUncreatableType( + "im.nheko", + 1, + 0, + "ImagePackListModel", + "ImagePackListModel needs to be instantiated on the C++ side"); + qmlRegisterUncreatableType( + "im.nheko", + 1, + 0, + "SingleImagePackModel", + "SingleImagePackModel needs to be instantiated on the C++ side"); qmlRegisterUncreatableType( "im.nheko", 1, @@ -436,6 +450,12 @@ TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId) }); } +void +TimelineViewManager::openImagePackSettings(QString roomid) +{ + emit showImagePackSettings(new ImagePackListModel(roomid.toStdString(), this)); +} + void TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img) { diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 374685e3..bdec405a 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -33,6 +33,7 @@ class ColorImageProvider; class UserSettings; class ChatPage; class DeviceVerificationFlow; +class ImagePackListModel; class TimelineViewManager : public QObject { @@ -57,6 +58,7 @@ public: Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; } bool isWindowFocused() const { return isWindowFocused_; } Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId); + Q_INVOKABLE void openImagePackSettings(QString roomid); Q_INVOKABLE QColor userColor(QString id, QColor background); Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE QString htmlEscape(QString str) const { return str.toHtmlEscaped(); } @@ -93,6 +95,7 @@ signals: void openRoomSettingsDialog(RoomSettings *settings); void openInviteUsersDialog(InviteesModel *invitees); void openProfile(UserProfile *profile); + void showImagePackSettings(ImagePackListModel *packlist); public slots: void updateReadReceipts(const QString &room_id, const std::vector &event_ids); diff --git a/src/ui/RoomSettings.h b/src/ui/RoomSettings.h index 367f3111..cf36f795 100644 --- a/src/ui/RoomSettings.h +++ b/src/ui/RoomSettings.h @@ -136,4 +136,4 @@ private: RoomInfo info_; int notifications_ = 0; int accessRules_ = 0; -}; \ No newline at end of file +}; -- cgit 1.4.1