Merge remote-tracking branch 'upstream/master' into voip
This commit is contained in:
commit
c73cfe1810
@ -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
|
||||||
|
@ -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()
|
||||||
|
12
README.md
12
README.md
@ -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
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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 "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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>
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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())
|
||||||
|
Loading…
Reference in New Issue
Block a user