mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
refactor(core): strong type message receipt and row ID
Avoid implicit casting and invalid arithmetic.
This commit is contained in:
parent
8422c09f6a
commit
edf6b67313
|
@ -28,6 +28,7 @@
|
|||
#include "src/model/groupinvite.h"
|
||||
#include "src/nexus.h"
|
||||
#include "src/persistence/profile.h"
|
||||
#include "src/util/strongtype.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QRegularExpression>
|
||||
|
@ -579,7 +580,7 @@ void Core::onGroupTitleChange(Tox*, uint32_t groupId, uint32_t peerId, const uin
|
|||
|
||||
void Core::onReadReceiptCallback(Tox*, uint32_t friendId, uint32_t receipt, void* core)
|
||||
{
|
||||
emit static_cast<Core*>(core)->receiptRecieved(friendId, receipt);
|
||||
emit static_cast<Core*>(core)->receiptRecieved(friendId, ReceiptNum{receipt});
|
||||
}
|
||||
|
||||
void Core::acceptFriendRequest(const ToxPk& friendPk)
|
||||
|
@ -652,33 +653,35 @@ void Core::requestFriendship(const ToxId& friendId, const QString& message)
|
|||
emit saveRequest();
|
||||
}
|
||||
|
||||
int Core::sendMessageWithType(uint32_t friendId, const QString& message, Tox_Message_Type type)
|
||||
bool Core::sendMessageWithType(uint32_t friendId, const QString& message, Tox_Message_Type type, ReceiptNum& receipt)
|
||||
{
|
||||
int size = message.toUtf8().size();
|
||||
auto maxSize = tox_max_message_length();
|
||||
if (size > maxSize) {
|
||||
qCritical() << "Core::sendMessageWithType called with message of size:" << size << "when max is:" << maxSize <<". Ignoring.";
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
ToxString cMessage(message);
|
||||
Tox_Err_Friend_Send_Message error;
|
||||
int receipt = tox_friend_send_message(tox.get(), friendId, type,
|
||||
cMessage.data(), cMessage.size(), &error);
|
||||
parseFriendSendMessageError(error);
|
||||
return receipt;
|
||||
receipt = ReceiptNum{tox_friend_send_message(tox.get(), friendId, type,
|
||||
cMessage.data(), cMessage.size(), &error)};
|
||||
if (parseFriendSendMessageError(error)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int Core::sendMessage(uint32_t friendId, const QString& message)
|
||||
bool Core::sendMessage(uint32_t friendId, const QString& message, ReceiptNum& receipt)
|
||||
{
|
||||
QMutexLocker ml(coreLoopLock.get());
|
||||
return sendMessageWithType(friendId, message, TOX_MESSAGE_TYPE_NORMAL);
|
||||
return sendMessageWithType(friendId, message, TOX_MESSAGE_TYPE_NORMAL, receipt);
|
||||
}
|
||||
|
||||
int Core::sendAction(uint32_t friendId, const QString& action)
|
||||
bool Core::sendAction(uint32_t friendId, const QString& action, ReceiptNum& receipt)
|
||||
{
|
||||
QMutexLocker ml(coreLoopLock.get());
|
||||
return sendMessageWithType(friendId, action, TOX_MESSAGE_TYPE_ACTION);
|
||||
return sendMessageWithType(friendId, action, TOX_MESSAGE_TYPE_ACTION, receipt);
|
||||
}
|
||||
|
||||
void Core::sendTyping(uint32_t friendId, bool typing)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "toxid.h"
|
||||
|
||||
#include "src/core/dhtserver.h"
|
||||
#include "src/util/strongtype.h"
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include <QMutex>
|
||||
|
@ -51,6 +52,8 @@ enum class Status
|
|||
class Core;
|
||||
|
||||
using ToxCorePtr = std::unique_ptr<Core>;
|
||||
using ReceiptNum = NamedType<uint32_t, struct ReceiptNumTag>;
|
||||
Q_DECLARE_METATYPE(ReceiptNum);
|
||||
|
||||
class Core : public QObject
|
||||
{
|
||||
|
@ -118,11 +121,11 @@ public slots:
|
|||
void setUsername(const QString& username);
|
||||
void setStatusMessage(const QString& message);
|
||||
|
||||
int sendMessage(uint32_t friendId, const QString& message);
|
||||
bool sendMessage(uint32_t friendId, const QString& message, ReceiptNum& receipt);
|
||||
void sendGroupMessage(int groupId, const QString& message);
|
||||
void sendGroupAction(int groupId, const QString& message);
|
||||
void changeGroupTitle(int groupId, const QString& title);
|
||||
int sendAction(uint32_t friendId, const QString& action);
|
||||
bool sendAction(uint32_t friendId, const QString& action, ReceiptNum& receipt);
|
||||
void sendTyping(uint32_t friendId, bool typing);
|
||||
|
||||
void sendAvatarFile(uint32_t friendId, const QByteArray& data);
|
||||
|
@ -200,7 +203,7 @@ signals:
|
|||
void groupSentFailed(int groupId);
|
||||
void actionSentResult(uint32_t friendId, const QString& action, int success);
|
||||
|
||||
void receiptRecieved(int friedId, int receipt);
|
||||
void receiptRecieved(int friedId, ReceiptNum receipt);
|
||||
|
||||
void failedToRemoveFriend(uint32_t friendId);
|
||||
|
||||
|
@ -234,7 +237,7 @@ private:
|
|||
static void onReadReceiptCallback(Tox* tox, uint32_t friendId, uint32_t receipt, void* core);
|
||||
|
||||
void sendGroupMessageWithType(int groupId, const QString& message, Tox_Message_Type type);
|
||||
int sendMessageWithType(uint32_t friendId, const QString& message, Tox_Message_Type type);
|
||||
bool sendMessageWithType(uint32_t friendId, const QString& message, Tox_Message_Type type, ReceiptNum& receipt);
|
||||
bool parsePeerQueryError(Tox_Err_Conference_Peer_Query error) const;
|
||||
bool parseConferenceJoinError(Tox_Err_Conference_Join error) const;
|
||||
bool checkConnection();
|
||||
|
|
|
@ -365,6 +365,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
QObject::connect(a.get(), &QApplication::aboutToQuit, cleanup);
|
||||
|
||||
qRegisterMetaType<ReceiptNum>();
|
||||
// Run
|
||||
int errorcode = a->exec();
|
||||
|
||||
|
|
|
@ -645,7 +645,7 @@ void RawDatabase::process()
|
|||
}
|
||||
|
||||
if (query.insertCallback)
|
||||
query.insertCallback(sqlite3_last_insert_rowid(sqlite));
|
||||
query.insertCallback(RowId{sqlite3_last_insert_rowid(sqlite)});
|
||||
}
|
||||
|
||||
if (trans.success != nullptr)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "src/util/strongtype.h"
|
||||
|
||||
/// The two following defines are required to use SQLCipher
|
||||
/// They are used by the sqlite3.h header
|
||||
|
@ -21,6 +22,8 @@
|
|||
|
||||
#include <sqlite3.h>
|
||||
|
||||
using RowId = NamedType<int64_t, struct RowIdTag>;
|
||||
Q_DECLARE_METATYPE(RowId);
|
||||
|
||||
class RawDatabase : QObject
|
||||
{
|
||||
|
@ -31,13 +34,13 @@ public:
|
|||
{
|
||||
public:
|
||||
Query(QString query, QVector<QByteArray> blobs = {},
|
||||
const std::function<void(int64_t)>& insertCallback = {})
|
||||
const std::function<void(RowId)>& insertCallback = {})
|
||||
: query{query.toUtf8()}
|
||||
, blobs{blobs}
|
||||
, insertCallback{insertCallback}
|
||||
{
|
||||
}
|
||||
Query(QString query, const std::function<void(int64_t)>& insertCallback)
|
||||
Query(QString query, const std::function<void(RowId)>& insertCallback)
|
||||
: query{query.toUtf8()}
|
||||
, insertCallback{insertCallback}
|
||||
{
|
||||
|
@ -52,7 +55,7 @@ public:
|
|||
private:
|
||||
QByteArray query;
|
||||
QVector<QByteArray> blobs;
|
||||
std::function<void(int64_t)> insertCallback;
|
||||
std::function<void(RowId)> insertCallback;
|
||||
std::function<void(const QVector<QVariant>&)> rowCallback;
|
||||
QVector<sqlite3_stmt*> statements;
|
||||
|
||||
|
|
|
@ -199,7 +199,7 @@ void History::removeFriendHistory(const QString& friendPk)
|
|||
QVector<RawDatabase::Query>
|
||||
History::generateNewMessageQueries(const QString& friendPk, const QString& message,
|
||||
const QString& sender, const QDateTime& time, bool isSent,
|
||||
QString dispName, std::function<void(int64_t)> insertIdCallback)
|
||||
QString dispName, std::function<void(RowId)> insertIdCallback)
|
||||
{
|
||||
QVector<RawDatabase::Query> queries;
|
||||
|
||||
|
@ -288,7 +288,7 @@ void History::onFileInsertionReady(FileDbInsertionData data)
|
|||
.arg(static_cast<int>(data.direction))
|
||||
.arg(ToxFile::CANCELED),
|
||||
{data.fileId.toUtf8(), data.filePath.toUtf8(), data.fileName.toUtf8(), QByteArray()},
|
||||
[weakThis, fileId](int64_t id) {
|
||||
[weakThis, fileId](RowId id) {
|
||||
auto pThis = weakThis.lock();
|
||||
if (pThis) {
|
||||
emit pThis->fileInserted(id, fileId);
|
||||
|
@ -299,12 +299,12 @@ void History::onFileInsertionReady(FileDbInsertionData data)
|
|||
queries += RawDatabase::Query(QStringLiteral("UPDATE history "
|
||||
"SET file_id = (last_insert_rowid()) "
|
||||
"WHERE id = %1")
|
||||
.arg(data.historyId));
|
||||
.arg(data.historyId.get()));
|
||||
|
||||
db->execLater(queries);
|
||||
}
|
||||
|
||||
void History::onFileInserted(int64_t dbId, QString fileId)
|
||||
void History::onFileInserted(RowId dbId, QString fileId)
|
||||
{
|
||||
auto& fileInfo = fileInfos[fileId];
|
||||
if (fileInfo.finished) {
|
||||
|
@ -317,7 +317,7 @@ void History::onFileInserted(int64_t dbId, QString fileId)
|
|||
}
|
||||
}
|
||||
|
||||
RawDatabase::Query History::generateFileFinished(int64_t id, bool success, const QString& filePath,
|
||||
RawDatabase::Query History::generateFileFinished(RowId id, bool success, const QString& filePath,
|
||||
const QByteArray& fileHash)
|
||||
{
|
||||
auto file_state = success ? ToxFile::FINISHED : ToxFile::CANCELED;
|
||||
|
@ -326,14 +326,14 @@ RawDatabase::Query History::generateFileFinished(int64_t id, bool success, const
|
|||
"SET file_state = %1, file_path = ?, file_hash = ?"
|
||||
"WHERE id = %2")
|
||||
.arg(file_state)
|
||||
.arg(id),
|
||||
.arg(id.get()),
|
||||
{filePath.toUtf8(), fileHash});
|
||||
} else {
|
||||
return RawDatabase::Query(QStringLiteral("UPDATE file_transfers "
|
||||
"SET finished = %1 "
|
||||
"WHERE id = %2")
|
||||
.arg(file_state)
|
||||
.arg(id));
|
||||
.arg(id.get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,7 +370,7 @@ void History::addNewFileMessage(const QString& friendPk, const QString& fileId,
|
|||
insertionData.size = size;
|
||||
insertionData.direction = direction;
|
||||
|
||||
auto insertFileTransferFn = [weakThis, insertionData](int64_t messageId) {
|
||||
auto insertFileTransferFn = [weakThis, insertionData](RowId messageId) {
|
||||
auto insertionDataRw = std::move(insertionData);
|
||||
|
||||
insertionDataRw.historyId = messageId;
|
||||
|
@ -395,7 +395,7 @@ void History::addNewFileMessage(const QString& friendPk, const QString& fileId,
|
|||
*/
|
||||
void History::addNewMessage(const QString& friendPk, const QString& message, const QString& sender,
|
||||
const QDateTime& time, bool isSent, QString dispName,
|
||||
const std::function<void(int64_t)>& insertIdCallback)
|
||||
const std::function<void(RowId)>& insertIdCallback)
|
||||
{
|
||||
if (!Settings::getInstance().getEnableLogging()) {
|
||||
qWarning() << "Blocked a message from being added to database while history is disabled";
|
||||
|
@ -413,7 +413,7 @@ void History::setFileFinished(const QString& fileId, bool success, const QString
|
|||
const QByteArray& fileHash)
|
||||
{
|
||||
auto& fileInfo = fileInfos[fileId];
|
||||
if (fileInfo.fileId == -1) {
|
||||
if (fileInfo.fileId.get() == -1) {
|
||||
fileInfo.finished = true;
|
||||
fileInfo.success = success;
|
||||
fileInfo.filePath = filePath;
|
||||
|
@ -616,13 +616,13 @@ QDateTime History::getStartDateChatHistory(const QString& friendPk)
|
|||
*
|
||||
* @param id Message ID.
|
||||
*/
|
||||
void History::markAsSent(qint64 messageId)
|
||||
void History::markAsSent(RowId messageId)
|
||||
{
|
||||
if (!isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
db->execLater(QString("DELETE FROM faux_offline_pending WHERE id=%1;").arg(messageId));
|
||||
db->execLater(QString("DELETE FROM faux_offline_pending WHERE id=%1;").arg(messageId.get()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -642,7 +642,7 @@ QList<History::HistMessage> History::getChatHistory(const QString& friendPk, con
|
|||
auto rowCallback = [&messages](const QVector<QVariant>& row) {
|
||||
// dispName and message could have null bytes, QString::fromUtf8
|
||||
// truncates on null bytes so we strip them
|
||||
auto id = row[0].toLongLong();
|
||||
auto id = RowId{row[0].toLongLong()};
|
||||
auto isOfflineMessage = row[1].isNull();
|
||||
auto timestamp = QDateTime::fromMSecsSinceEpoch(row[2].toLongLong());
|
||||
auto friend_key = row[3].toString();
|
||||
|
|
|
@ -95,7 +95,7 @@ struct FileDbInsertionData
|
|||
{
|
||||
FileDbInsertionData();
|
||||
|
||||
int64_t historyId;
|
||||
RowId historyId;
|
||||
QString friendPk;
|
||||
QString fileId;
|
||||
QString fileName;
|
||||
|
@ -111,7 +111,7 @@ class History : public QObject, public std::enable_shared_from_this<History>
|
|||
public:
|
||||
struct HistMessage
|
||||
{
|
||||
HistMessage(qint64 id, bool isSent, QDateTime timestamp, QString chat, QString dispName,
|
||||
HistMessage(RowId id, bool isSent, QDateTime timestamp, QString chat, QString dispName,
|
||||
QString sender, QString message)
|
||||
: chat{chat}
|
||||
, sender{sender}
|
||||
|
@ -122,7 +122,7 @@ public:
|
|||
, content(std::move(message))
|
||||
{}
|
||||
|
||||
HistMessage(qint64 id, bool isSent, QDateTime timestamp, QString chat, QString dispName,
|
||||
HistMessage(RowId id, bool isSent, QDateTime timestamp, QString chat, QString dispName,
|
||||
QString sender, ToxFile file)
|
||||
: chat{chat}
|
||||
, sender{sender}
|
||||
|
@ -138,7 +138,7 @@ public:
|
|||
QString sender;
|
||||
QString dispName;
|
||||
QDateTime timestamp;
|
||||
qint64 id;
|
||||
RowId id;
|
||||
bool isSent;
|
||||
HistMessageContent content;
|
||||
};
|
||||
|
@ -161,7 +161,7 @@ public:
|
|||
void removeFriendHistory(const QString& friendPk);
|
||||
void addNewMessage(const QString& friendPk, const QString& message, const QString& sender,
|
||||
const QDateTime& time, bool isSent, QString dispName,
|
||||
const std::function<void(int64_t)>& insertIdCallback = {});
|
||||
const std::function<void(RowId)>& insertIdCallback = {});
|
||||
|
||||
void addNewFileMessage(const QString& friendPk, const QString& fileId,
|
||||
const QString& fileName, const QString& filePath, int64_t size,
|
||||
|
@ -177,27 +177,27 @@ public:
|
|||
const ParameterSearch& parameter);
|
||||
QDateTime getStartDateChatHistory(const QString& friendPk);
|
||||
|
||||
void markAsSent(qint64 messageId);
|
||||
void markAsSent(RowId messageId);
|
||||
|
||||
protected:
|
||||
QVector<RawDatabase::Query>
|
||||
generateNewMessageQueries(const QString& friendPk, const QString& message,
|
||||
const QString& sender, const QDateTime& time, bool isSent,
|
||||
QString dispName, std::function<void(int64_t)> insertIdCallback = {});
|
||||
QString dispName, std::function<void(RowId)> insertIdCallback = {});
|
||||
|
||||
signals:
|
||||
void fileInsertionReady(FileDbInsertionData data);
|
||||
void fileInserted(int64_t dbId, QString fileId);
|
||||
void fileInserted(RowId dbId, QString fileId);
|
||||
|
||||
private slots:
|
||||
void onFileInsertionReady(FileDbInsertionData data);
|
||||
void onFileInserted(int64_t dbId, QString fileId);
|
||||
void onFileInserted(RowId dbId, QString fileId);
|
||||
|
||||
private:
|
||||
QList<HistMessage> getChatHistory(const QString& friendPk, const QDateTime& from,
|
||||
const QDateTime& to, int numMessages);
|
||||
|
||||
static RawDatabase::Query generateFileFinished(int64_t fileId, bool success,
|
||||
static RawDatabase::Query generateFileFinished(RowId fileId, bool success,
|
||||
const QString& filePath, const QByteArray& fileHash);
|
||||
void dbSchemaUpgrade();
|
||||
|
||||
|
@ -211,7 +211,7 @@ private:
|
|||
bool success = false;
|
||||
QString filePath;
|
||||
QByteArray fileHash;
|
||||
int64_t fileId = -1;
|
||||
RowId fileId{-1};
|
||||
};
|
||||
|
||||
// This needs to be a shared pointer to avoid callback lifetime issues
|
||||
|
|
|
@ -33,7 +33,7 @@ OfflineMsgEngine::OfflineMsgEngine(Friend* frnd)
|
|||
{
|
||||
}
|
||||
|
||||
void OfflineMsgEngine::dischargeReceipt(int receipt)
|
||||
void OfflineMsgEngine::dischargeReceipt(ReceiptNum receipt)
|
||||
{
|
||||
QMutexLocker ml(&mutex);
|
||||
|
||||
|
@ -47,14 +47,14 @@ void OfflineMsgEngine::dischargeReceipt(int receipt)
|
|||
processReceipt(receipt);
|
||||
}
|
||||
|
||||
void OfflineMsgEngine::registerReceipt(int receipt, int64_t messageID, ChatMessage::Ptr msg)
|
||||
void OfflineMsgEngine::registerReceipt(ReceiptNum receipt, RowId messageID, ChatMessage::Ptr msg)
|
||||
{
|
||||
QMutexLocker ml(&mutex);
|
||||
|
||||
auto it = receipts.find(receipt);
|
||||
if (it == receipts.end()) {
|
||||
it = receipts.insert(receipt, Receipt());
|
||||
} else if (it->bRowValid && receipt != 0 /* offline receipt */) {
|
||||
} else if (it->bRowValid && receipt.get() != 0 /* offline receipt */) {
|
||||
qWarning() << "Received duplicate registration of receipt";
|
||||
}
|
||||
it->rowId = messageID;
|
||||
|
@ -76,7 +76,7 @@ void OfflineMsgEngine::deliverOfflineMsgs()
|
|||
if (undeliveredMsgs.size() == 0)
|
||||
return;
|
||||
|
||||
QMap<int64_t, MsgPtr> msgs = undeliveredMsgs;
|
||||
QMap<RowId, MsgPtr> msgs = undeliveredMsgs;
|
||||
removeAllReceipts();
|
||||
undeliveredMsgs.clear();
|
||||
|
||||
|
@ -84,11 +84,11 @@ void OfflineMsgEngine::deliverOfflineMsgs()
|
|||
auto val = iter.value();
|
||||
auto key = iter.key();
|
||||
QString messageText = val.msg->toString();
|
||||
int rec;
|
||||
ReceiptNum rec;
|
||||
if (val.msg->isAction()) {
|
||||
rec = Core::getInstance()->sendAction(f->getId(), messageText);
|
||||
Core::getInstance()->sendAction(f->getId(), messageText, rec);
|
||||
} else {
|
||||
rec = Core::getInstance()->sendMessage(f->getId(), messageText);
|
||||
Core::getInstance()->sendMessage(f->getId(), messageText, rec);
|
||||
}
|
||||
|
||||
registerReceipt(rec, key, val.msg);
|
||||
|
@ -102,7 +102,7 @@ void OfflineMsgEngine::removeAllReceipts()
|
|||
receipts.clear();
|
||||
}
|
||||
|
||||
void OfflineMsgEngine::updateTimestamp(int receiptId)
|
||||
void OfflineMsgEngine::updateTimestamp(ReceiptNum receiptId)
|
||||
{
|
||||
QMutexLocker ml(&mutex);
|
||||
|
||||
|
@ -118,7 +118,7 @@ void OfflineMsgEngine::updateTimestamp(int receiptId)
|
|||
receipts.erase(receipt);
|
||||
}
|
||||
|
||||
void OfflineMsgEngine::processReceipt(int receiptId)
|
||||
void OfflineMsgEngine::processReceipt(ReceiptNum receiptId)
|
||||
{
|
||||
const auto receipt = receipts.constFind(receiptId);
|
||||
if (receipt == receipts.end()) {
|
||||
|
@ -138,6 +138,6 @@ void OfflineMsgEngine::processReceipt(int receiptId)
|
|||
if (QThread::currentThread() == QCoreApplication::instance()->thread()) {
|
||||
updateTimestamp(receiptId);
|
||||
} else {
|
||||
QMetaObject::invokeMethod(this, "updateTimestamp", Qt::QueuedConnection, Q_ARG(int, receiptId));
|
||||
QMetaObject::invokeMethod(this, "updateTimestamp", Qt::QueuedConnection, Q_ARG(ReceiptNum, receiptId));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#define OFFLINEMSGENGINE_H
|
||||
|
||||
#include "src/chatlog/chatmessage.h"
|
||||
#include "src/core/core.h"
|
||||
#include "src/persistence/db/rawdatabase.h"
|
||||
#include <QDateTime>
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
|
@ -36,32 +38,32 @@ public:
|
|||
explicit OfflineMsgEngine(Friend*);
|
||||
virtual ~OfflineMsgEngine() = default;
|
||||
|
||||
void dischargeReceipt(int receipt);
|
||||
void registerReceipt(int receipt, int64_t messageID, ChatMessage::Ptr msg);
|
||||
void dischargeReceipt(ReceiptNum receipt);
|
||||
void registerReceipt(ReceiptNum receipt, RowId messageID, ChatMessage::Ptr msg);
|
||||
void deliverOfflineMsgs();
|
||||
|
||||
public slots:
|
||||
void removeAllReceipts();
|
||||
void updateTimestamp(int receiptId);
|
||||
void updateTimestamp(ReceiptNum receiptId);
|
||||
|
||||
private:
|
||||
void processReceipt(int receiptId);
|
||||
void processReceipt(ReceiptNum receiptId);
|
||||
struct Receipt
|
||||
{
|
||||
bool bRowValid{false};
|
||||
int64_t rowId{0};
|
||||
RowId rowId{0};
|
||||
bool bRecepitReceived{false};
|
||||
};
|
||||
|
||||
struct MsgPtr
|
||||
{
|
||||
ChatMessage::Ptr msg;
|
||||
int receipt;
|
||||
ReceiptNum receipt;
|
||||
};
|
||||
QMutex mutex;
|
||||
Friend* f;
|
||||
QHash<int, Receipt> receipts;
|
||||
QMap<int64_t, MsgPtr> undeliveredMsgs;
|
||||
QHash<ReceiptNum, Receipt> receipts;
|
||||
QMap<RowId, MsgPtr> undeliveredMsgs;
|
||||
|
||||
static const int offlineTimeout;
|
||||
};
|
||||
|
|
55
src/util/strongtype.h
Normal file
55
src/util/strongtype.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright © 2019 by The qTox Project Contributors
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
qTox is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef STORNGTYPE_H
|
||||
#define STORNGTYPE_H
|
||||
|
||||
#include <QHash>
|
||||
|
||||
/* This class facilitates creating a named class which wraps underlying POD,
|
||||
* avoiding implict casts and arithmetic of the underlying data.
|
||||
* Usage: Declare named type with arbitrary tag, then hook up Qt metatype for use
|
||||
* in signals/slots. For queued connections, registering the metatype is also
|
||||
* required before the type is used.
|
||||
* using ReceiptNum = NamedType<uint32_t, struct ReceiptNumTag>;
|
||||
* Q_DECLARE_METATYPE(ReceiptNum);
|
||||
* qRegisterMetaType<ReceiptNum>();
|
||||
*/
|
||||
|
||||
template <typename T, typename Parameter>
|
||||
class NamedType
|
||||
{
|
||||
public:
|
||||
NamedType() {}
|
||||
explicit NamedType(T const& value) : value_(value) {}
|
||||
T& get() { return value_; }
|
||||
T const& get() const {return value_; }
|
||||
bool operator==(const NamedType& rhs) const { return value_ == rhs.value_; }
|
||||
bool operator<(const NamedType& rhs) const { return value_ < rhs.value_; }
|
||||
bool operator>(const NamedType& rhs) const { return value_ > rhs.value_; }
|
||||
|
||||
private:
|
||||
T value_;
|
||||
};
|
||||
|
||||
template <typename T, typename Parameter>
|
||||
inline uint qHash(const NamedType<T,Parameter> &key, uint seed = 0) {
|
||||
return qHash(key.get(), seed);
|
||||
}
|
||||
#endif // STORNGTYPE_H
|
|
@ -686,7 +686,7 @@ void ChatForm::onStatusMessage(const QString& message)
|
|||
}
|
||||
}
|
||||
|
||||
void ChatForm::onReceiptReceived(quint32 friendId, int receipt)
|
||||
void ChatForm::onReceiptReceived(quint32 friendId, ReceiptNum receipt)
|
||||
{
|
||||
if (friendId == f->getId()) {
|
||||
offlineEngine->dischargeReceipt(receipt);
|
||||
|
@ -885,7 +885,7 @@ ChatForm::MessageMetadata ChatForm::getMessageMetadata(History::HistMessage cons
|
|||
const bool isAction =
|
||||
histMessage.content.getType() == HistMessageContentType::message
|
||||
&& histMessage.content.asMessage().startsWith(ACTION_PREFIX, Qt::CaseInsensitive);
|
||||
const qint64 id = histMessage.id;
|
||||
const RowId id = histMessage.id;
|
||||
return {isSelf, needSending, isAction, id, authorPk, msgDateTime};
|
||||
}
|
||||
|
||||
|
@ -931,13 +931,13 @@ void ChatForm::sendLoadedMessage(ChatMessage::Ptr chatMsg, MessageMetadata const
|
|||
return;
|
||||
}
|
||||
|
||||
int receipt = 0;
|
||||
ReceiptNum receipt{0};
|
||||
if (f->getStatus() != Status::Offline) {
|
||||
Core* core = Core::getInstance();
|
||||
uint32_t friendId = f->getId();
|
||||
QString stringMsg = chatMsg->toString();
|
||||
receipt = metadata.isAction ? core->sendAction(friendId, stringMsg)
|
||||
: core->sendMessage(friendId, stringMsg);
|
||||
metadata.isAction ? core->sendAction(friendId, stringMsg, receipt)
|
||||
: core->sendMessage(friendId, stringMsg, receipt);
|
||||
}
|
||||
getOfflineMsgEngine()->registerReceipt(receipt, metadata.id, chatMsg);
|
||||
}
|
||||
|
@ -1122,11 +1122,11 @@ void ChatForm::SendMessageStr(QString msg)
|
|||
historyPart = ACTION_PREFIX + part;
|
||||
}
|
||||
|
||||
int rec = 0;
|
||||
ReceiptNum receipt{0};
|
||||
if (f->getStatus() != Status::Offline) {
|
||||
Core* core = Core::getInstance();
|
||||
uint32_t friendId = f->getId();
|
||||
rec = isAction ? core->sendAction(friendId, part) : core->sendMessage(friendId, part);
|
||||
isAction ? core->sendAction(friendId, part, receipt) : core->sendMessage(friendId, part, receipt);
|
||||
}
|
||||
|
||||
ChatMessage::Ptr ma = createSelfMessage(part, timestamp, isAction, false);
|
||||
|
@ -1138,8 +1138,8 @@ void ChatForm::SendMessageStr(QString msg)
|
|||
QString name = Core::getInstance()->getUsername();
|
||||
bool isSent = !Settings::getInstance().getFauxOfflineMessaging();
|
||||
history->addNewMessage(pk, historyPart, selfPk, timestamp, isSent, name,
|
||||
[offMsgEngine, rec, ma](int64_t id) {
|
||||
offMsgEngine->registerReceipt(rec, id, ma);
|
||||
[offMsgEngine, receipt, ma](RowId id) {
|
||||
offMsgEngine->registerReceipt(receipt, id, ma);
|
||||
});
|
||||
} else {
|
||||
// TODO: Make faux-offline messaging work partially with the history disabled
|
||||
|
|
|
@ -103,7 +103,7 @@ private slots:
|
|||
void onFriendNameChanged(const QString& name);
|
||||
void onFriendMessageReceived(quint32 friendId, const QString& message, bool isAction);
|
||||
void onStatusMessage(const QString& message);
|
||||
void onReceiptReceived(quint32 friendId, int receipt);
|
||||
void onReceiptReceived(quint32 friendId, ReceiptNum receipt);
|
||||
void onLoadHistory();
|
||||
void onUpdateTime();
|
||||
void sendImage(const QPixmap& pixmap);
|
||||
|
@ -117,10 +117,10 @@ private:
|
|||
const bool isSelf;
|
||||
const bool needSending;
|
||||
const bool isAction;
|
||||
const qint64 id;
|
||||
const RowId id;
|
||||
const ToxPk authorPk;
|
||||
const QDateTime msgDateTime;
|
||||
MessageMetadata(bool isSelf, bool needSending, bool isAction, qint64 id, ToxPk authorPk,
|
||||
MessageMetadata(bool isSelf, bool needSending, bool isAction, RowId id, ToxPk authorPk,
|
||||
QDateTime msgDateTime)
|
||||
: isSelf{isSelf}
|
||||
, needSending{needSending}
|
||||
|
|
|
@ -240,7 +240,7 @@ void Widget::init()
|
|||
connect(updateCheck.get(), &UpdateCheck::updateAvailable, this, &Widget::onUpdateAvailable);
|
||||
#endif
|
||||
settingsWidget = new SettingsWidget(updateCheck.get(), this);
|
||||
#if UPDATE_CHECK_ENABLED
|
||||
#if UPDATE_CHECK_ENABLED
|
||||
updateCheck->checkForUpdate();
|
||||
#endif
|
||||
|
||||
|
@ -1013,7 +1013,7 @@ void Widget::addFriend(uint32_t friendId, const ToxPk& friendPk)
|
|||
connect(widget, &FriendWidget::copyFriendIdToClipboard, this, &Widget::copyFriendIdToClipboard);
|
||||
connect(widget, &FriendWidget::contextMenuCalled, widget, &FriendWidget::onContextMenuCalled);
|
||||
connect(widget, SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int)));
|
||||
|
||||
|
||||
Profile* profile = Nexus::getProfile();
|
||||
connect(profile, &Profile::friendAvatarSet, widget, &FriendWidget::onAvatarSet);
|
||||
connect(profile, &Profile::friendAvatarRemoved, widget, &FriendWidget::onAvatarRemoved);
|
||||
|
@ -1218,7 +1218,7 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message, bool
|
|||
newFriendMessageAlert(friendId);
|
||||
}
|
||||
|
||||
void Widget::onReceiptRecieved(int friendId, int receipt)
|
||||
void Widget::onReceiptRecieved(int friendId, ReceiptNum receipt)
|
||||
{
|
||||
Friend* f = FriendList::findFriend(friendId);
|
||||
if (!f) {
|
||||
|
|
|
@ -167,7 +167,7 @@ public slots:
|
|||
void onFriendMessageReceived(int friendId, const QString& message, bool isAction);
|
||||
void onFriendRequestReceived(const ToxPk& friendPk, const QString& message);
|
||||
void updateFriendActivity(const Friend* frnd);
|
||||
void onReceiptRecieved(int friendId, int receipt);
|
||||
void onReceiptRecieved(int friendId, ReceiptNum receipt);
|
||||
void onEmptyGroupCreated(int groupId, const QString& title);
|
||||
void onGroupInviteReceived(const GroupInvite& inviteInfo);
|
||||
void onGroupInviteAccepted(const GroupInvite& inviteInfo);
|
||||
|
|
Loading…
Reference in New Issue
Block a user