Merge remote-tracking branch 'upstream/master' into voip

This commit is contained in:
trilene 2020-07-10 19:39:44 -04:00
commit c73cfe1810
15 changed files with 179 additions and 128 deletions

View File

@ -71,7 +71,6 @@ cmake -GNinja -H. -Bbuild \
-DHUNTER_ROOT=".hunter" \ -DHUNTER_ROOT=".hunter" \
-DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF \ -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF \
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DHUNTER_CONFIGURATION_TYPES=RelWithDebInfo \ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHUNTER_CONFIGURATION_TYPES=RelWithDebInfo \
-DUSE_BUNDLED_OPENSSL=OFF \
-DCI_BUILD=ON -DCI_BUILD=ON
fi fi
cmake --build build cmake --build build

View File

@ -4,6 +4,7 @@ option(APPVEYOR_BUILD "Build on appveyor" OFF)
option(CI_BUILD "Set when building in CI. Enables -Werror where possible" OFF) option(CI_BUILD "Set when building in CI. Enables -Werror where possible" OFF)
option(ASAN "Compile with address sanitizers" OFF) option(ASAN "Compile with address sanitizers" OFF)
option(QML_DEBUGGING "Enable qml debugging" OFF) option(QML_DEBUGGING "Enable qml debugging" OFF)
option(COMPILE_QML "Compile Qml. It will make Nheko faster, but you will need to recompile it, when you update Qt." OFF)
set( set(
CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/toolchain.cmake" CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/toolchain.cmake"
@ -17,10 +18,9 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "compile as PIC by default")
option(HUNTER_ENABLED "Enable Hunter package manager" OFF) option(HUNTER_ENABLED "Enable Hunter package manager" OFF)
include("cmake/HunterGate.cmake") include("cmake/HunterGate.cmake")
HunterGate( HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.23.244.tar.gz" URL "https://github.com/cpp-pm/hunter/archive/v0.23.260.tar.gz"
SHA1 "2c0f491fd0b80f7b09e3d21adb97237161ef9835" SHA1 "13775235910a3fa85644568d1c5be8271de72e1c"
LOCAL )
)
option(USE_BUNDLED_BOOST "Use the bundled version of Boost." ${HUNTER_ENABLED}) option(USE_BUNDLED_BOOST "Use the bundled version of Boost." ${HUNTER_ENABLED})
option(USE_BUNDLED_SPDLOG "Use the bundled version of spdlog." option(USE_BUNDLED_SPDLOG "Use the bundled version of spdlog."
@ -35,8 +35,6 @@ option(USE_BUNDLED_JSON "Use the bundled version of nlohmann json."
option(USE_BUNDLED_OPENSSL "Use the bundled version of OpenSSL." option(USE_BUNDLED_OPENSSL "Use the bundled version of OpenSSL."
${HUNTER_ENABLED}) ${HUNTER_ENABLED})
option(USE_BUNDLED_MTXCLIENT "Use the bundled version of the Matrix Client library." ${HUNTER_ENABLED}) option(USE_BUNDLED_MTXCLIENT "Use the bundled version of the Matrix Client library." ${HUNTER_ENABLED})
option(USE_BUNDLED_SODIUM "Use the bundled version of libsodium."
${HUNTER_ENABLED})
option(USE_BUNDLED_LMDB "Use the bundled version of lmdb." option(USE_BUNDLED_LMDB "Use the bundled version of lmdb."
${HUNTER_ENABLED}) ${HUNTER_ENABLED})
option(USE_BUNDLED_LMDBXX "Use the bundled version of lmdb++." option(USE_BUNDLED_LMDBXX "Use the bundled version of lmdb++."
@ -334,7 +332,7 @@ find_package(Boost 1.70 REQUIRED
if(USE_BUNDLED_OPENSSL) if(USE_BUNDLED_OPENSSL)
hunter_add_package(OpenSSL) hunter_add_package(OpenSSL)
endif() endif()
find_package(OpenSSL REQUIRED) find_package(OpenSSL 1.1.0 REQUIRED)
if(USE_BUNDLED_MTXCLIENT) if(USE_BUNDLED_MTXCLIENT)
include(FetchContent) include(FetchContent)
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
@ -342,7 +340,7 @@ if(USE_BUNDLED_MTXCLIENT)
FetchContent_Declare( FetchContent_Declare(
MatrixClient MatrixClient
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
GIT_TAG v0.3.1 GIT_TAG eddd95a896fad0c51fc800741d82bbc43fc6d41e
) )
FetchContent_MakeAvailable(MatrixClient) FetchContent_MakeAvailable(MatrixClient)
else() else()

View File

@ -114,7 +114,6 @@ brew cask install nheko
- [cmark](https://github.com/commonmark/cmark) 0.29 or greater. - [cmark](https://github.com/commonmark/cmark) 0.29 or greater.
- Boost 1.70 or greater. - Boost 1.70 or greater.
- [libolm](https://gitlab.matrix.org/matrix-org/olm) - [libolm](https://gitlab.matrix.org/matrix-org/olm)
- [libsodium](https://github.com/jedisct1/libsodium)
- [spdlog](https://github.com/gabime/spdlog) - [spdlog](https://github.com/gabime/spdlog)
- A compiler that supports C++ 17: - A compiler that supports C++ 17:
- Clang 6 (tested on Travis CI) - Clang 6 (tested on Travis CI)
@ -136,8 +135,6 @@ The bundle flags are currently:
- USE_BUNDLED_JSON - USE_BUNDLED_JSON
- USE_BUNDLED_OPENSSL - USE_BUNDLED_OPENSSL
- USE_BUNDLED_MTXCLIENT - USE_BUNDLED_MTXCLIENT
- USE_BUNDLED_SODIUM
- USE_BUNDLED_ZLIB
- USE_BUNDLED_LMDB - USE_BUNDLED_LMDB
- USE_BUNDLED_LMDBXX - USE_BUNDLED_LMDBXX
- USE_BUNDLED_TWEENY - USE_BUNDLED_TWEENY
@ -162,8 +159,7 @@ sudo pacman -S qt5-base \
fontconfig \ fontconfig \
lmdb \ lmdb \
cmark \ cmark \
boost \ boost
libsodium
``` ```
##### Gentoo Linux ##### Gentoo Linux
@ -176,7 +172,7 @@ sudo emerge -a ">=dev-qt/qtgui-5.9.0" media-libs/fontconfig
```bash ```bash
# Build requirements + qml modules needed at runtime (you may not need all of them, but the following seem to work according to reports): # Build requirements + qml modules needed at runtime (you may not need all of them, but the following seem to work according to reports):
sudo apt install g++ cmake zlib1g-dev libssl-dev qt{base,declarative,tools,multimedia,quickcontrols2-}5-dev libqt5svg5-dev libboost-system-dev libboost-thread-dev libboost-iostreams-dev libolm-dev libsodium-dev liblmdb++-dev libcmark-dev nlohmann-json3-dev libspdlog-dev libgtest-dev qml-module-qt{gstreamer,multimedia,quick-extras,-labs-settings,graphicaleffects,quick-controls2} sudo apt install g++ cmake zlib1g-dev libssl-dev qt{base,declarative,tools,multimedia,quickcontrols2-}5-dev libqt5svg5-dev libboost-system-dev libboost-thread-dev libboost-iostreams-dev libolm-dev liblmdb++-dev libcmark-dev nlohmann-json3-dev libspdlog-dev libgtest-dev qml-module-qt{gstreamer,multimedia,quick-extras,-labs-settings,graphicaleffects,quick-controls2}
``` ```
This will install all dependencies, except for tweeny (use bundled tweeny) This will install all dependencies, except for tweeny (use bundled tweeny)
and mtxclient (needs to be build separately). and mtxclient (needs to be build separately).
@ -186,7 +182,7 @@ and mtxclient (needs to be build separately).
(User report, not sure if all of those are needed) (User report, not sure if all of those are needed)
```bash ```bash
sudo apt install cmake gcc make automake liblmdb-dev libsodium-dev \ sudo apt install cmake gcc make automake liblmdb-dev \
qt5-default libssl-dev libqt5multimedia5-plugins libqt5multimediagsttools5 libqt5multimediaquick5 libqt5svg5-dev \ qt5-default libssl-dev libqt5multimedia5-plugins libqt5multimediagsttools5 libqt5multimediaquick5 libqt5svg5-dev \
qml-module-qtgstreamer qtmultimedia5-dev qtquickcontrols2-5-dev qttools5-dev qttools5-dev-tools \ qml-module-qtgstreamer qtmultimedia5-dev qtquickcontrols2-5-dev qttools5-dev qttools5-dev-tools \
qml-module-qtgraphicaleffects qml-module-qtmultimedia qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtgraphicaleffects qml-module-qtmultimedia qml-module-qtquick-controls2 qml-module-qtquick-layouts
@ -203,7 +199,7 @@ guix environment nheko
```bash ```bash
brew update brew update
brew install qt5 lmdb cmake llvm libsodium spdlog boost cmark libolm brew install qt5 lmdb cmake llvm spdlog boost cmark libolm
``` ```
##### Windows ##### Windows

View File

@ -1,5 +1,5 @@
hunter_config( hunter_config(
Boost Boost
VERSION "1.70.0-p0" VERSION "1.70.0-p1"
CMAKE_ARGS IOSTREAMS_NO_BZIP2=1 CMAKE_ARGS IOSTREAMS_NO_BZIP2=1
) )

View File

@ -133,10 +133,14 @@ function(hunter_gate_self root version sha1 result)
string(SUBSTRING "${sha1}" 0 7 archive_id) string(SUBSTRING "${sha1}" 0 7 archive_id)
set( if(EXISTS "${root}/cmake/Hunter")
hunter_self set(hunter_self "${root}")
"${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked" else()
) set(
hunter_self
"${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
)
endif()
set("${result}" "${hunter_self}" PARENT_SCOPE) set("${result}" "${hunter_self}" PARENT_SCOPE)
endfunction() endfunction()
@ -490,37 +494,44 @@ macro(HunterGate)
) )
set(_master_location "${_hunter_self}/cmake/Hunter") set(_master_location "${_hunter_self}/cmake/Hunter")
get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE) if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter")
set(_done_location "${_archive_id_location}/DONE") # Hunter downloaded manually (e.g. by 'git clone')
set(_sha1_location "${_archive_id_location}/SHA1") set(_unused "xxxxxxxxxx")
set(HUNTER_GATE_SHA1 "${_unused}")
set(HUNTER_GATE_VERSION "${_unused}")
else()
get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
set(_done_location "${_archive_id_location}/DONE")
set(_sha1_location "${_archive_id_location}/SHA1")
# Check Hunter already downloaded by HunterGate # Check Hunter already downloaded by HunterGate
if(NOT EXISTS "${_done_location}") if(NOT EXISTS "${_done_location}")
hunter_gate_download("${_archive_id_location}") hunter_gate_download("${_archive_id_location}")
endif() endif()
if(NOT EXISTS "${_done_location}") if(NOT EXISTS "${_done_location}")
hunter_gate_internal_error("hunter_gate_download failed") hunter_gate_internal_error("hunter_gate_download failed")
endif() endif()
if(NOT EXISTS "${_sha1_location}") if(NOT EXISTS "${_sha1_location}")
hunter_gate_internal_error("${_sha1_location} not found") hunter_gate_internal_error("${_sha1_location} not found")
endif() endif()
file(READ "${_sha1_location}" _sha1_value) file(READ "${_sha1_location}" _sha1_value)
string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal) string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal)
if(NOT _is_equal) if(NOT _is_equal)
hunter_gate_internal_error( hunter_gate_internal_error(
"Short SHA1 collision:" "Short SHA1 collision:"
" ${_sha1_value} (from ${_sha1_location})" " ${_sha1_value} (from ${_sha1_location})"
" ${HUNTER_GATE_SHA1} (HunterGate)" " ${HUNTER_GATE_SHA1} (HunterGate)"
) )
endif() endif()
if(NOT EXISTS "${_master_location}") if(NOT EXISTS "${_master_location}")
hunter_gate_user_error( hunter_gate_user_error(
"Master file not found:" "Master file not found:"
" ${_master_location}" " ${_master_location}"
"try to update Hunter/HunterGate" "try to update Hunter/HunterGate"
) )
endif()
endif() endif()
include("${_master_location}") include("${_master_location}")
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES) set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)

View File

@ -21,7 +21,7 @@ if(NOT EXISTS ${_qrc})
endif() endif()
qt5_add_resources(LANG_QRC ${_qrc}) qt5_add_resources(LANG_QRC ${_qrc})
if(Qt5QuickCompiler_FOUND) if(Qt5QuickCompiler_FOUND AND COMPILE_QML)
qtquick_compiler_add_resources(QRC resources/res.qrc) qtquick_compiler_add_resources(QRC resources/res.qrc)
else() else()
qt5_add_resources(QRC resources/res.qrc) qt5_add_resources(QRC resources/res.qrc)

View File

@ -146,9 +146,9 @@
"name": "mtxclient", "name": "mtxclient",
"sources": [ "sources": [
{ {
"sha256": "e4899cc4ce87397de2aef865e94ea2cdb8d9cb86253727e7d90532b925ecc770", "sha256": "6334bb71821a0fde54fe24f02ad393cdb6836633557ffdd239b29c5d5108daaf",
"type": "archive", "type": "archive",
"url": "https://github.com/Nheko-Reborn/mtxclient/archive/v0.3.1.tar.gz" "url": "https://github.com/Nheko-Reborn/mtxclient/archive/eddd95a896fad0c51fc800741d82bbc43fc6d41e.tar.gz"
} }
] ]
}, },
@ -171,7 +171,8 @@
{ {
"config-opts": [ "config-opts": [
"-DCMAKE_BUILD_TYPE=Release", "-DCMAKE_BUILD_TYPE=Release",
"-DLMDBXX_INCLUDE_DIR=.deps/lmdbxx" "-DLMDBXX_INCLUDE_DIR=.deps/lmdbxx",
"-DCOMPILE_QML=ON"
], ],
"buildsystem": "cmake-ninja", "buildsystem": "cmake-ninja",
"name": "nheko", "name": "nheko",

View File

@ -16,7 +16,7 @@ TextEdit {
timelineManager.setHistoryView(match[1]) timelineManager.setHistoryView(match[1])
chat.positionViewAtIndex(chat.model.idToIndex(match[2]), ListView.Contain) chat.positionViewAtIndex(chat.model.idToIndex(match[2]), ListView.Contain)
} }
else Qt.openUrlExternally(link) else timelineManager.openLink(link)
} }
MouseArea MouseArea
{ {

View File

@ -589,8 +589,12 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
emit notificationsRetrieved(std::move(res)); emit notificationsRetrieved(std::move(res));
}); });
}); });
connect(this, &ChatPage::syncRoomlist, room_list_, &RoomList::sync); connect(this, &ChatPage::syncRoomlist, room_list_, &RoomList::sync, Qt::QueuedConnection);
connect(this, &ChatPage::syncTags, communitiesList_, &CommunitiesList::syncTags); connect(this,
&ChatPage::syncTags,
communitiesList_,
&CommunitiesList::syncTags,
Qt::QueuedConnection);
connect( connect(
this, &ChatPage::syncTopBar, this, [this](const std::map<QString, RoomInfo> &updates) { this, &ChatPage::syncTopBar, this, [this](const std::map<QString, RoomInfo> &updates) {
if (updates.find(currentRoom()) != updates.end()) if (updates.find(currentRoom()) != updates.end())
@ -605,11 +609,15 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
user_info_widget_->setDisplayName(name); user_info_widget_->setDisplayName(name);
}); });
connect(this, &ChatPage::tryInitialSyncCb, this, &ChatPage::tryInitialSync); connect(
connect(this, &ChatPage::trySyncCb, this, &ChatPage::trySync); this, &ChatPage::tryInitialSyncCb, this, &ChatPage::tryInitialSync, Qt::QueuedConnection);
connect(this, &ChatPage::tryDelayedSyncCb, this, [this]() { connect(this, &ChatPage::trySyncCb, this, &ChatPage::trySync, Qt::QueuedConnection);
QTimer::singleShot(RETRY_TIMEOUT, this, &ChatPage::trySync); connect(
}); this,
&ChatPage::tryDelayedSyncCb,
this,
[this]() { QTimer::singleShot(RETRY_TIMEOUT, this, &ChatPage::trySync); },
Qt::QueuedConnection);
connect(this, &ChatPage::dropToLoginPageCb, this, &ChatPage::dropToLoginPage); connect(this, &ChatPage::dropToLoginPageCb, this, &ChatPage::dropToLoginPage);

View File

@ -53,9 +53,9 @@ namespace strings {
const QString url_html = "<a href=\"\\1\">\\1</a>"; const QString url_html = "<a href=\"\\1\">\\1</a>";
const QRegularExpression url_regex( const QRegularExpression url_regex(
// match an URL, that is not quoted, i.e. // match an URL, that is not quoted, i.e.
// vvvvvv match quote via negative lookahead/lookbehind vv // vvvvvv match quote via negative lookahead/lookbehind vv
// vvvv atomic match url -> fail if there is a " before or after vvv // vvvv atomic match url -> fail if there is a " before or after vvv
R"((?<!")(?>((www\.(?!\.)|[a-z][a-z0-9+.-]*://)[^\s<>'"]+[^!,\.\s<>'"\]\)\:]))(?!"))"); R"((?<!["'])(?>((www\.(?!\.)|[a-z][a-z0-9+.-]*://)[^\s<>'"]+[^!,\.\s<>'"\]\)\:]))(?!["']))");
} }
// Window geometry. // Window geometry.

View File

@ -85,8 +85,10 @@ struct EventFormattedBody
template<class T> template<class T>
std::string operator()(const mtx::events::RoomEvent<T> &e) std::string operator()(const mtx::events::RoomEvent<T> &e)
{ {
if constexpr (is_detected<formatted_body_t, T>::value) if constexpr (is_detected<formatted_body_t, T>::value) {
return e.content.formatted_body; if (e.content.format == "org.matrix.custom.html")
return e.content.formatted_body;
}
return ""; return "";
} }
}; };

View File

@ -159,72 +159,96 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
, room_id_(room_id) , room_id_(room_id)
, manager_(manager) , manager_(manager)
{ {
connect(this,
&TimelineModel::oldMessagesRetrieved,
this,
&TimelineModel::addBackwardsEvents,
Qt::QueuedConnection);
connect( connect(
this, &TimelineModel::oldMessagesRetrieved, this, &TimelineModel::addBackwardsEvents); this,
connect(this, &TimelineModel::messageFailed, this, [this](QString txn_id) { &TimelineModel::messageFailed,
nhlog::ui()->error("Failed to send {}, retrying", txn_id.toStdString()); this,
[this](QString txn_id) {
QTimer::singleShot(5000, this, [this]() { emit nextPendingMessage(); }); nhlog::ui()->error("Failed to send {}, retrying", txn_id.toStdString());
});
connect(this, &TimelineModel::messageSent, this, [this](QString txn_id, QString event_id) {
pending.removeOne(txn_id);
auto ev = events.value(txn_id);
if (auto reaction =
std::get_if<mtx::events::RoomEvent<mtx::events::msg::Reaction>>(&ev)) {
QString reactedTo =
QString::fromStdString(reaction->content.relates_to.event_id);
auto &rModel = reactions[reactedTo];
rModel.removeReaction(*reaction);
auto rCopy = *reaction;
rCopy.event_id = event_id.toStdString();
rModel.addReaction(room_id_.toStdString(), rCopy);
}
int idx = idToIndex(txn_id);
if (idx < 0) {
// transaction already received via sync
return;
}
eventOrder[idx] = event_id;
ev = std::visit(
[event_id](const auto &e) -> mtx::events::collections::TimelineEvents {
auto eventCopy = e;
eventCopy.event_id = event_id.toStdString();
return eventCopy;
},
ev);
events.remove(txn_id);
events.insert(event_id, ev);
// mark our messages as read
readEvent(event_id.toStdString());
emit dataChanged(index(idx, 0), index(idx, 0));
if (pending.size() > 0)
emit nextPendingMessage();
});
connect(this, &TimelineModel::redactionFailed, this, [](const QString &msg) {
emit ChatPage::instance()->showNotification(msg);
});
QTimer::singleShot(5000, this, [this]() { emit nextPendingMessage(); });
},
Qt::QueuedConnection);
connect( connect(
this, &TimelineModel::nextPendingMessage, this, &TimelineModel::processOnePendingMessage); this,
connect(this, &TimelineModel::newMessageToSend, this, &TimelineModel::addPendingMessage); &TimelineModel::messageSent,
this,
[this](QString txn_id, QString event_id) {
pending.removeOne(txn_id);
auto ev = events.value(txn_id);
if (auto reaction =
std::get_if<mtx::events::RoomEvent<mtx::events::msg::Reaction>>(&ev)) {
QString reactedTo =
QString::fromStdString(reaction->content.relates_to.event_id);
auto &rModel = reactions[reactedTo];
rModel.removeReaction(*reaction);
auto rCopy = *reaction;
rCopy.event_id = event_id.toStdString();
rModel.addReaction(room_id_.toStdString(), rCopy);
}
int idx = idToIndex(txn_id);
if (idx < 0) {
// transaction already received via sync
return;
}
eventOrder[idx] = event_id;
ev = std::visit(
[event_id](const auto &e) -> mtx::events::collections::TimelineEvents {
auto eventCopy = e;
eventCopy.event_id = event_id.toStdString();
return eventCopy;
},
ev);
events.remove(txn_id);
events.insert(event_id, ev);
// mark our messages as read
readEvent(event_id.toStdString());
emit dataChanged(index(idx, 0), index(idx, 0));
if (pending.size() > 0)
emit nextPendingMessage();
},
Qt::QueuedConnection);
connect(
this,
&TimelineModel::redactionFailed,
this,
[](const QString &msg) { emit ChatPage::instance()->showNotification(msg); },
Qt::QueuedConnection);
connect(this, connect(this,
&TimelineModel::eventFetched, &TimelineModel::nextPendingMessage,
this, this,
[this](QString requestingEvent, mtx::events::collections::TimelineEvents event) { &TimelineModel::processOnePendingMessage,
events.insert(QString::fromStdString(mtx::accessors::event_id(event)), Qt::QueuedConnection);
event); connect(this,
auto idx = idToIndex(requestingEvent); &TimelineModel::newMessageToSend,
if (idx >= 0) this,
emit dataChanged(index(idx, 0), index(idx, 0)); &TimelineModel::addPendingMessage,
}); Qt::QueuedConnection);
connect(
this,
&TimelineModel::eventFetched,
this,
[this](QString requestingEvent, mtx::events::collections::TimelineEvents event) {
events.insert(QString::fromStdString(mtx::accessors::event_id(event)), event);
auto idx = idToIndex(requestingEvent);
if (idx >= 0)
emit dataChanged(index(idx, 0), index(idx, 0));
},
Qt::QueuedConnection);
} }
QHash<int, QByteArray> QHash<int, QByteArray>

View File

@ -1,5 +1,6 @@
#include "TimelineViewManager.h" #include "TimelineViewManager.h"
#include <QDesktopServices>
#include <QMetaType> #include <QMetaType>
#include <QPalette> #include <QPalette>
#include <QQmlContext> #include <QQmlContext>
@ -112,7 +113,10 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
container = view; container = view;
view->setResizeMode(QQuickWidget::SizeRootObjectToView); view->setResizeMode(QQuickWidget::SizeRootObjectToView);
container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
view->quickWindow()->setTextRenderType(QQuickWindow::NativeTextRendering); view->quickWindow()->setTextRenderType(QQuickWindow::NativeTextRendering);
#endif
connect(view, &QQuickWidget::statusChanged, this, [](QQuickWidget::Status status) { connect(view, &QQuickWidget::statusChanged, this, [](QQuickWidget::Status status) {
nhlog::ui()->debug("Status changed to {}", status); nhlog::ui()->debug("Status changed to {}", status);
@ -231,6 +235,12 @@ TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId) const
}); });
} }
void
TimelineViewManager::openLink(QString link) const
{
QDesktopServices::openUrl(link);
}
void void
TimelineViewManager::updateReadReceipts(const QString &room_id, TimelineViewManager::updateReadReceipts(const QString &room_id,
const std::vector<QString> &event_ids) const std::vector<QString> &event_ids)

View File

@ -50,6 +50,8 @@ public:
Q_INVOKABLE QString userPresence(QString id) const; Q_INVOKABLE QString userPresence(QString id) const;
Q_INVOKABLE QString userStatus(QString id) const; Q_INVOKABLE QString userStatus(QString id) const;
Q_INVOKABLE void openLink(QString link) const;
signals: signals:
void clearRoomMessageCount(QString roomid); void clearRoomMessageCount(QString roomid);
void updateRoomsLastMessage(QString roomid, const DescInfo &info); void updateRoomsLastMessage(QString roomid, const DescInfo &info);

View File

@ -63,7 +63,7 @@ SnackBar::hideMessage()
// Moving on to the next message. // Moving on to the next message.
messages_.pop_front(); messages_.pop_front();
// Reseting the starting position of the widget. // Resetting the starting position of the widget.
offset_ = STARTING_OFFSET; offset_ = STARTING_OFFSET;
if (!messages_.empty()) if (!messages_.empty())