aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Rusakov <Kitsune-Ral@users.sf.net>2021-11-11 08:27:42 +0100
committerAlexey Rusakov <Kitsune-Ral@users.sf.net>2021-11-11 08:27:42 +0100
commit766410a6c9e928915ece112f4f4f4a4317789e5f (patch)
tree95cb911222a51718fd27c788c0a83805c75aa33f
parent5c0346f3a700e6af31463490b7af3382b86e09d5 (diff)
parent65bb0b5fcf029df7a9bfa0b7b7b7e3203fd7862f (diff)
downloadlibquotient-766410a6c9e928915ece112f4f4f4a4317789e5f.tar.gz
libquotient-766410a6c9e928915ece112f4f4f4a4317789e5f.zip
Merge branch 'dev' into kitsune-fix-read-receipts-and-markers
-rw-r--r--CMakeLists.txt14
-rw-r--r--lib/connection.cpp11
-rw-r--r--lib/connection.h22
-rw-r--r--lib/events/event.h3
-rw-r--r--lib/events/roommemberevent.cpp14
-rw-r--r--lib/jobs/basejob.h6
-rw-r--r--lib/logging.h4
-rw-r--r--lib/quotient_common.h25
-rw-r--r--lib/room.cpp11
-rw-r--r--lib/room.h16
-rw-r--r--lib/util.h30
11 files changed, 107 insertions, 49 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bae833c3..34200548 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -179,8 +179,12 @@ set(FULL_CSAPI_DIR lib/${CSAPI_DIR})
set(ASAPI_DEF_DIR application-service/definitions)
set(ISAPI_DEF_DIR identity/definitions)
+set(API_GENERATION_ENABLED 0)
+set(API_FORMATTING_ENABLED 0)
if (GTAD_PATH AND MATRIX_DOC_PATH)
- get_filename_component(ABS_GTAD_PATH "${GTAD_PATH}" PROGRAM PROGRAM_ARGS GTAD_ARGS)
+ # REALPATH resolves ~ (home directory) while PROGRAM doesn't
+ get_filename_component(ABS_GTAD_PATH "${GTAD_PATH}" REALPATH)
+ get_filename_component(ABS_GTAD_PATH "${ABS_GTAD_PATH}" PROGRAM PROGRAM_ARGS GTAD_ARGS)
if (EXISTS ${ABS_GTAD_PATH})
get_filename_component(ABS_API_DEF_PATH "${MATRIX_DOC_PATH}/data/api" REALPATH)
if (NOT IS_DIRECTORY ${ABS_API_DEF_PATH})
@@ -193,7 +197,7 @@ if (GTAD_PATH AND MATRIX_DOC_PATH)
message( WARNING "${MATRIX_DOC_PATH} doesn't seem to point to a valid matrix-doc repo; disabling API stubs generation")
endif ()
else (EXISTS ${ABS_GTAD_PATH})
- message( WARNING "${GTAD_PATH} doesn't exist; disabling API stubs generation")
+ message( WARNING "${GTAD_PATH} is not executable; disabling API stubs generation")
endif ()
endif ()
if (API_GENERATION_ENABLED)
@@ -264,8 +268,10 @@ if (API_GENERATION_ENABLED)
endif()
add_feature_info(EnableApiCodeGeneration "${API_GENERATION_ENABLED}"
"build target update-api")
-add_feature_info(EnableApiFormatting "${API_FORMATTING_ENABLED}"
- "formatting of generated API files with clang-format")
+if (API_GENERATION_ENABLED)
+ add_feature_info(EnableApiFormatting "${API_FORMATTING_ENABLED}"
+ "formatting of generated API files with clang-format")
+endif()
# Make no mistake: CMake cannot run gtad first and then populate the list of
# resulting api_SRCS files. In other words, placing the below statement after
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 1fe0d2d0..75966731 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -77,8 +77,6 @@ public:
explicit Private(std::unique_ptr<ConnectionData>&& connection)
: data(move(connection))
{}
- Q_DISABLE_COPY(Private)
- DISABLE_MOVE(Private)
Connection* q = nullptr;
std::unique_ptr<ConnectionData> data;
@@ -316,10 +314,6 @@ void Connection::resolveServer(const QString& mxid)
setHomeserver(maybeBaseUrl);
}
Q_ASSERT(d->loginFlowsJob != nullptr); // Ensured by setHomeserver()
- connect(d->loginFlowsJob, &BaseJob::failure, this, [this] {
- qCWarning(MAIN) << "Homeserver base URL sanity check failed";
- emit resolveError(tr("The homeserver doesn't seem to be working"));
- });
});
}
@@ -478,10 +472,11 @@ void Connection::Private::checkAndConnect(const QString& userId,
connectFn();
else
emit q->loginError(
+ tr("Unsupported login flow"),
tr("The homeserver at %1 does not support"
" the login flow '%2'")
- .arg(data->baseUrl().toDisplayString()),
- flow->type);
+ .arg(data->baseUrl().toDisplayString(),
+ flow->type));
});
else
connectSingleShot(q, &Connection::homeserverChanged, q, connectFn);
diff --git a/lib/connection.h b/lib/connection.h
index 1a6ca9b0..05a3bb7f 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -479,10 +479,23 @@ public:
}
public Q_SLOTS:
- /** Set the homeserver base URL */
+ /// \brief Set the homeserver base URL and retrieve its login flows
+ ///
+ /// \sa LoginFlowsJob, loginFlows, loginFlowsChanged, homeserverChanged
void setHomeserver(const QUrl& baseUrl);
- /** Determine and set the homeserver from MXID */
+ /// \brief Determine and set the homeserver from MXID
+ ///
+ /// This attempts to resolve the homeserver by requesting
+ /// .well-known/matrix/client record from the server taken from the MXID
+ /// serverpart. If there is no record found, the serverpart itself is
+ /// attempted as the homeserver base URL; if the record is there but
+ /// is malformed (e.g., the homeserver base URL cannot be found in it)
+ /// resolveError() is emitted and further processing stops. Otherwise,
+ /// setHomeserver is called, preparing the Connection object for the login
+ /// attempt.
+ /// \param mxid user Matrix ID, such as @someone:example.org
+ /// \sa setHomeserver, homeserverChanged, loginFlowsChanged, resolveError
void resolveServer(const QString& mxid);
/** \brief Log in using a username and password pair
@@ -638,6 +651,11 @@ public Q_SLOTS:
virtual LeaveRoomJob* leaveRoom(Room* room);
Q_SIGNALS:
+ /// \brief Initial server resolution has failed
+ ///
+ /// This signal is emitted when resolveServer() did not manage to resolve
+ /// the homeserver using its .well-known/client record or otherwise.
+ /// \sa resolveServer
void resolveError(QString error);
void homeserverChanged(QUrl baseUrl);
diff --git a/lib/events/event.h b/lib/events/event.h
index f8f8311d..78853ced 100644
--- a/lib/events/event.h
+++ b/lib/events/event.h
@@ -76,8 +76,7 @@ public:
private:
EventTypeRegistry() = default;
- Q_DISABLE_COPY(EventTypeRegistry)
- DISABLE_MOVE(EventTypeRegistry)
+ Q_DISABLE_COPY_MOVE(EventTypeRegistry)
static EventTypeRegistry& get()
{
diff --git a/lib/events/roommemberevent.cpp b/lib/events/roommemberevent.cpp
index 8a6bddd8..469dbb32 100644
--- a/lib/events/roommemberevent.cpp
+++ b/lib/events/roommemberevent.cpp
@@ -103,16 +103,14 @@ bool RoomMemberEvent::isUnban() const
bool RoomMemberEvent::isRename() const
{
- auto prevName = prevContent() && prevContent()->displayName
- ? *prevContent()->displayName
- : QString();
- return newDisplayName() != prevName;
+ return prevContent() && prevContent()->displayName
+ ? newDisplayName() != *prevContent()->displayName
+ : newDisplayName().has_value();
}
bool RoomMemberEvent::isAvatarUpdate() const
{
- auto prevAvatarUrl = prevContent() && prevContent()->avatarUrl
- ? *prevContent()->avatarUrl
- : QUrl();
- return newAvatarUrl() != prevAvatarUrl;
+ return prevContent() && prevContent()->avatarUrl
+ ? newAvatarUrl() != *prevContent()->avatarUrl
+ : newAvatarUrl().has_value();
}
diff --git a/lib/jobs/basejob.h b/lib/jobs/basejob.h
index 119d7cce..ddf243ed 100644
--- a/lib/jobs/basejob.h
+++ b/lib/jobs/basejob.h
@@ -7,6 +7,7 @@
#include "requestdata.h"
#include "../logging.h"
#include "../converters.h"
+#include "../quotient_common.h"
#include <QtCore/QObject>
#include <QtCore/QStringBuilder>
@@ -33,9 +34,8 @@ class BaseJob : public QObject {
}
public:
-#define WITH_DEPRECATED_ERROR_VERSION(Recommended) \
- Recommended, Recommended##Error Q_DECL_ENUMERATOR_DEPRECATED_X( \
- "Use " #Recommended) = Recommended
+#define WITH_DEPRECATED_ERROR_VERSION(Recommended) \
+ Recommended, DECL_DEPRECATED_ENUMERATOR(Recommended##Error, Recommended)
/*! The status code of a job
*
diff --git a/lib/logging.h b/lib/logging.h
index 7e0da975..5a3ef6ea 100644
--- a/lib/logging.h
+++ b/lib/logging.h
@@ -37,11 +37,7 @@ using QDebugManip = QDebug (*)(QDebug);
*/
inline QDebug formatJson(QDebug debug_object)
{
-#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
- return debug_object;
-#else
return debug_object.noquote();
-#endif
}
/**
diff --git a/lib/quotient_common.h b/lib/quotient_common.h
index 13bf7246..3d8ace67 100644
--- a/lib/quotient_common.h
+++ b/lib/quotient_common.h
@@ -7,6 +7,25 @@
#include <array>
+// See https://bugreports.qt.io/browse/QTBUG-82295 - despite the comment that
+// Q_FLAG[_NS] "should" be applied to the enum only, Qt doesn't allow to wrap
+// a flag type into a QVariant then. The macros below define Q_FLAG_NS and on
+// top of that add a part of Q_ENUM() that enables the metatype data but goes
+// under the moc radar to avoid double registration of the same data in the map
+// defined in moc_*.cpp
+#define QUO_DECLARE_FLAGS(Flags, Enum) \
+ Q_DECLARE_FLAGS(Flags, Enum) \
+ Q_ENUM_IMPL(Enum) \
+ Q_FLAG(Flags)
+
+#define QUO_DECLARE_FLAGS_NS(Flags, Enum) \
+ Q_DECLARE_FLAGS(Flags, Enum) \
+ Q_ENUM_NS_IMPL(Enum) \
+ Q_FLAG_NS(Flags)
+
+#define DECL_DEPRECATED_ENUMERATOR(Deprecated, Recommended) \
+ Deprecated Q_DECL_ENUMERATOR_DEPRECATED_X("Use " #Recommended) = Recommended
+
namespace Quotient {
Q_NAMESPACE
@@ -41,8 +60,7 @@ enum class Membership : unsigned int {
Ban = 0x10,
Undefined = Invalid
};
-Q_DECLARE_FLAGS(MembershipMask, Membership)
-Q_FLAG_NS(MembershipMask)
+QUO_DECLARE_FLAGS_NS(MembershipMask, Membership)
constexpr inline auto MembershipStrings = make_array(
// The order MUST be the same as the order in the original enum
@@ -60,8 +78,7 @@ enum class JoinState : std::underlying_type_t<Membership> {
Invite = std::underlying_type_t<Membership>(Membership::Invite),
Knock = std::underlying_type_t<Membership>(Membership::Knock),
};
-Q_DECLARE_FLAGS(JoinStates, JoinState)
-Q_FLAG_NS(JoinStates)
+QUO_DECLARE_FLAGS_NS(JoinStates, JoinState)
constexpr inline auto JoinStateStrings = make_array(
MembershipStrings[0], MembershipStrings[1], MembershipStrings[2],
diff --git a/lib/room.cpp b/lib/room.cpp
index ea8df286..ceb8d111 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -54,7 +54,6 @@
#include <QtCore/QDir>
#include <QtCore/QHash>
-#include <QtCore/QMimeDatabase>
#include <QtCore/QPointer>
#include <QtCore/QRegularExpression>
#include <QtCore/QStringBuilder> // for efficient string concats (operator%)
@@ -2309,8 +2308,13 @@ bool Room::Private::processRedaction(const RedactionEvent& redaction)
RoomEventPtr makeReplaced(const RoomEvent& target,
const RoomMessageEvent& replacement)
{
+ const auto &targetReply = target.contentJson()["m.relates_to"].toObject();
+ auto newContent = replacement.contentJson().value("m.new_content"_ls).toObject();
+ if (!targetReply.empty()) {
+ newContent["m.relates_to"] = targetReply;
+ }
auto originalJson = target.originalJsonObject();
- originalJson[ContentKeyL] = replacement.contentJson().value("m.new_content"_ls);
+ originalJson[ContentKeyL] = newContent;
auto unsignedData = originalJson.take(UnsignedKeyL).toObject();
auto relations = unsignedData.take("m.relations"_ls).toObject();
@@ -2853,7 +2857,8 @@ Room::Changes Room::processAccountDataEvent(EventPtr&& event)
qCDebug(STATE) << "Updated account data of type"
<< currentData->matrixType();
emit accountDataChanged(currentData->matrixType());
- changes |= Change::AccountDataChange;
+ // TODO: Drop AccountDataChange in 0.8
+ QT_IGNORE_DEPRECATIONS(changes |= AccountDataChange|OtherChange);
}
return changes;
}
diff --git a/lib/room.h b/lib/room.h
index 73f28a6e..260510e6 100644
--- a/lib/room.h
+++ b/lib/room.h
@@ -169,14 +169,16 @@ public:
TagsChange = 0x40,
MembersChange = 0x80,
/* = 0x100, */
- AccountDataChange = 0x200,
+ AccountDataChange Q_DECL_ENUMERATOR_DEPRECATED_X(
+ "AccountDataChange will be merged into OtherChange in 0.8") = 0x200,
SummaryChange = 0x400,
- ReadMarkerChange = 0x800,
+ ReadMarkerChange Q_DECL_ENUMERATOR_DEPRECATED_X(
+ "ReadMarkerChange will be merged into OtherChange in 0.8") = 0x800,
OtherChange = 0x8000,
+ OtherChanges = OtherChange,
AnyChange = 0xFFFF
};
- Q_DECLARE_FLAGS(Changes, Change)
- Q_FLAG(Changes)
+ QUO_DECLARE_FLAGS(Changes, Change)
Room(Connection* connection, QString id, JoinState initialJoinState);
~Room() override;
@@ -720,11 +722,11 @@ Q_SIGNALS:
*/
void baseStateLoaded();
void eventsHistoryJobChanged();
- void aboutToAddHistoricalMessages(RoomEventsRange events);
- void aboutToAddNewMessages(RoomEventsRange events);
+ void aboutToAddHistoricalMessages(Quotient::RoomEventsRange events);
+ void aboutToAddNewMessages(Quotient::RoomEventsRange events);
void addedMessages(int fromIndex, int toIndex);
/// The event is about to be appended to the list of pending events
- void pendingEventAboutToAdd(RoomEvent* event);
+ void pendingEventAboutToAdd(Quotient::RoomEvent* event);
/// An event has been appended to the list of pending events
void pendingEventAdded();
/// The remote echo has arrived with the sync and will be merged
diff --git a/lib/util.h b/lib/util.h
index c6171b91..13efb94b 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -12,10 +12,30 @@
#include <unordered_map>
#include <optional>
-// Along the lines of Q_DISABLE_COPY - the upstream version comes in Qt 5.13
-#define DISABLE_MOVE(_ClassName) \
- _ClassName(_ClassName&&) Q_DECL_EQ_DELETE; \
- _ClassName& operator=(_ClassName&&) Q_DECL_EQ_DELETE;
+#ifndef Q_DISABLE_MOVE
+// Q_DISABLE_MOVE was introduced in Q_VERSION_CHECK(5,13,0)
+# define Q_DISABLE_MOVE(_ClassName) \
+ _ClassName(_ClassName&&) Q_DECL_EQ_DELETE; \
+ _ClassName& operator=(_ClassName&&) Q_DECL_EQ_DELETE;
+#endif
+
+#ifndef Q_DISABLE_COPY_MOVE
+#define Q_DISABLE_COPY_MOVE(Class) \
+ Q_DISABLE_COPY(Class) \
+ Q_DISABLE_MOVE(Class)
+#endif
+
+#define DISABLE_MOVE(_ClassName) \
+static_assert(false, "Use Q_DISABLE_MOVE instead; Quotient enables it across all used versions of Qt");
+
+#ifndef QT_IGNORE_DEPRECATIONS
+// QT_IGNORE_DEPRECATIONS was introduced in Q_VERSION_CHECK(5,15,0)
+# define QT_IGNORE_DEPRECATIONS(statement) \
+ QT_WARNING_PUSH \
+ QT_WARNING_DISABLE_DEPRECATED \
+ statement \
+ QT_WARNING_POP
+#endif
namespace Quotient {
/// An equivalent of std::hash for QTypes to enable std::unordered_map<QType, ...>
@@ -138,6 +158,8 @@ public:
const value_type& operator*() const& { return base_type::operator*(); }
value_type& operator*() && { return base_type::operator*(); }
};
+template <typename T>
+Omittable(T&&) -> Omittable<T>;
namespace _impl {
template <typename T>