mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Use Tox IDs internally as message author ID
Instead of names. Fixes #603 Groupchats still use names internally, since there's currently no way to get a chat member's public key throught the toxcore API
This commit is contained in:
parent
5bdbc3d6d0
commit
98f15af670
32
src/core.cpp
32
src/core.cpp
|
@ -991,7 +991,7 @@ void Core::removeGroup(int groupId)
|
|||
tox_del_groupchat(tox, groupId);
|
||||
}
|
||||
|
||||
QString Core::getUsername()
|
||||
QString Core::getUsername() const
|
||||
{
|
||||
QString sname;
|
||||
int size = tox_get_self_name_size(tox);
|
||||
|
@ -1034,21 +1034,21 @@ void Core::setAvatar(uint8_t format, const QByteArray& data)
|
|||
tox_send_avatar_info(tox, i);
|
||||
}
|
||||
|
||||
ToxID Core::getSelfId()
|
||||
ToxID Core::getSelfId() const
|
||||
{
|
||||
uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(tox, friendAddress);
|
||||
return ToxID::fromString(CFriendAddress::toString(friendAddress));
|
||||
}
|
||||
|
||||
QString Core::getIDString()
|
||||
QString Core::getIDString() const
|
||||
{
|
||||
return getSelfId().toString().left(12);
|
||||
// 12 is the smallest multiple of four such that
|
||||
// 16^n > 10^10 (which is roughly the planet's population)
|
||||
}
|
||||
|
||||
QString Core::getStatusMessage()
|
||||
QString Core::getStatusMessage() const
|
||||
{
|
||||
QString sname;
|
||||
int size = tox_get_self_status_message_size(tox);
|
||||
|
@ -1715,3 +1715,27 @@ bool Core::isPasswordSet(PasswordType passtype)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString Core::getPeerName(const ToxID& id) const
|
||||
{
|
||||
uint8_t cname[TOX_MAX_NAME_LENGTH];
|
||||
QString name;
|
||||
CUserId cid(id.toString());
|
||||
|
||||
int friendId = tox_get_friend_number(tox, (uint8_t*)cid.data());
|
||||
if (friendId < 0)
|
||||
{
|
||||
qWarning() << "Core::getPeerName: No such peer "+id.toString();
|
||||
return name;
|
||||
}
|
||||
|
||||
int nameSize = tox_get_name(tox, friendId, cname);
|
||||
if (nameSize < 0)
|
||||
{
|
||||
qWarning() << "Core::getPeerName: Can't get name of friend "+QString().setNum(friendId)+" ("+id.toString()+")";
|
||||
return name;
|
||||
}
|
||||
|
||||
name = name.fromLocal8Bit((char*)cname, nameSize);
|
||||
return name;
|
||||
}
|
||||
|
|
10
src/core.h
10
src/core.h
|
@ -46,6 +46,8 @@ public:
|
|||
static const QString CONFIG_FILE_NAME;
|
||||
static QString sanitize(QString name);
|
||||
|
||||
QString getPeerName(const ToxID& id) const;
|
||||
|
||||
int getGroupNumberPeers(int groupId) const; ///< Return the number of peers in the group chat on success, or -1 on failure
|
||||
QString getGroupPeerName(int groupId, int peerId) const; ///< Get the name of a peer of a group
|
||||
QList<QString> getGroupPeerNames(int groupId) const; ///< Get the names of the peers of a group
|
||||
|
@ -57,11 +59,11 @@ public:
|
|||
void saveConfiguration();
|
||||
void saveConfiguration(const QString& path);
|
||||
|
||||
QString getIDString(); ///< Get the 12 first characters of our Tox ID
|
||||
QString getIDString() const; ///< Get the 12 first characters of our Tox ID
|
||||
|
||||
QString getUsername(); ///< Returns our username, or an empty string on failure
|
||||
QString getStatusMessage(); ///< Returns our status message, or an empty string on failure
|
||||
ToxID getSelfId(); ///< Returns our Tox ID
|
||||
QString getUsername() const; ///< Returns our username, or an empty string on failure
|
||||
QString getStatusMessage() const; ///< Returns our status message, or an empty string on failure
|
||||
ToxID getSelfId() const; ///< Returns our Tox ID
|
||||
|
||||
VideoSource* getVideoSourceFromCall(int callNumber); ///< Get a call's video source
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "corestructs.h"
|
||||
#include "src/corestructs.h"
|
||||
#include "src/core.h"
|
||||
#include <QFile>
|
||||
|
||||
ToxFile::ToxFile(int FileNum, int FriendId, QByteArray FileName, QString FilePath, FileDirection Direction)
|
||||
|
@ -17,3 +18,33 @@ bool ToxFile::open(bool write)
|
|||
{
|
||||
return write ? file->open(QIODevice::ReadWrite) : file->open(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
QString ToxID::toString() const
|
||||
{
|
||||
return publicKey + noSpam + checkSum;
|
||||
}
|
||||
|
||||
ToxID ToxID::fromString(QString id)
|
||||
{
|
||||
ToxID toxID;
|
||||
toxID.publicKey = id.left(TOX_ID_PUBLIC_KEY_LENGTH);
|
||||
toxID.noSpam = id.mid(TOX_ID_PUBLIC_KEY_LENGTH, TOX_ID_NO_SPAM_LENGTH);
|
||||
toxID.checkSum = id.right(TOX_ID_CHECKSUM_LENGTH);
|
||||
return toxID;
|
||||
}
|
||||
|
||||
|
||||
bool ToxID::operator==(const ToxID& other) const
|
||||
{
|
||||
return publicKey == other.publicKey;
|
||||
}
|
||||
|
||||
bool ToxID::operator!=(const ToxID& other) const
|
||||
{
|
||||
return publicKey != other.publicKey;
|
||||
}
|
||||
|
||||
bool ToxID::isMine() const
|
||||
{
|
||||
return *this == Core::getInstance()->getSelfId();
|
||||
}
|
||||
|
|
|
@ -20,20 +20,12 @@ struct ToxID
|
|||
QString noSpam;
|
||||
QString checkSum;
|
||||
|
||||
QString toString() const
|
||||
{
|
||||
return publicKey + noSpam + checkSum;
|
||||
}
|
||||
|
||||
ToxID static fromString(QString id)
|
||||
{
|
||||
ToxID toxID;
|
||||
toxID.publicKey = id.left(TOX_ID_PUBLIC_KEY_LENGTH);
|
||||
toxID.noSpam = id.mid(TOX_ID_PUBLIC_KEY_LENGTH, TOX_ID_NO_SPAM_LENGTH);
|
||||
toxID.checkSum = id.right(TOX_ID_CHECKSUM_LENGTH);
|
||||
return toxID;
|
||||
}
|
||||
QString toString() const;
|
||||
ToxID static fromString(QString id);
|
||||
|
||||
bool operator==(const ToxID& other) const;
|
||||
bool operator!=(const ToxID& other) const;
|
||||
bool isMine() const;
|
||||
};
|
||||
|
||||
struct DhtServer
|
||||
|
|
|
@ -46,7 +46,12 @@ void Friend::setStatusMessage(QString message)
|
|||
chatForm->setStatusMessage(message);
|
||||
}
|
||||
|
||||
QString Friend::getName()
|
||||
QString Friend::getName() const
|
||||
{
|
||||
return widget->getName();
|
||||
}
|
||||
|
||||
ToxID Friend::getToxID() const
|
||||
{
|
||||
return ToxID::fromString(userId);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ public:
|
|||
~Friend();
|
||||
void setName(QString name);
|
||||
void setStatusMessage(QString message);
|
||||
QString getName();
|
||||
QString getName() const;
|
||||
ToxID getToxID() const;
|
||||
|
||||
public:
|
||||
FriendWidget* widget;
|
||||
|
|
|
@ -92,19 +92,19 @@ void ChatForm::onSendTriggered()
|
|||
QString msg = msgEdit->toPlainText();
|
||||
if (msg.isEmpty())
|
||||
return;
|
||||
QString name = Widget::getInstance()->getUsername();
|
||||
|
||||
QDateTime timestamp = QDateTime::currentDateTime();
|
||||
HistoryKeeper::getInstance()->addChatEntry(f->userId, msg, Core::getInstance()->getSelfId().publicKey, timestamp);
|
||||
|
||||
if (msg.startsWith("/me "))
|
||||
{
|
||||
msg = msg.right(msg.length() - 4);
|
||||
addMessage(name, msg, true, timestamp);
|
||||
addSelfMessage(msg, true, timestamp);
|
||||
emit sendAction(f->friendId, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
addMessage(name, msg, false, timestamp);
|
||||
addSelfMessage(msg, false, timestamp);
|
||||
emit sendMessage(f->friendId, msg);
|
||||
}
|
||||
msgEdit->clear();
|
||||
|
@ -150,10 +150,13 @@ void ChatForm::startFileSend(ToxFile file)
|
|||
connect(Core::getInstance(), SIGNAL(fileTransferRemotePausedUnpaused(ToxFile,bool)), fileTrans, SLOT(onFileTransferRemotePausedUnpaused(ToxFile,bool)));
|
||||
connect(Core::getInstance(), SIGNAL(fileTransferBrokenUnbroken(ToxFile, bool)), fileTrans, SLOT(onFileTransferBrokenUnbroken(ToxFile, bool)));
|
||||
|
||||
QString name = Widget::getInstance()->getUsername();
|
||||
if (name == previousName)
|
||||
name = "";
|
||||
previousName = Widget::getInstance()->getUsername();
|
||||
QString name;
|
||||
if (!previousId.isMine())
|
||||
{
|
||||
Core* core = Core::getInstance();
|
||||
name = core->getUsername();
|
||||
previousId = core->getSelfId();
|
||||
}
|
||||
|
||||
chatWidget->insertMessage(ChatActionPtr(new FileTransferAction(fileTrans, getElidedName(name),
|
||||
QTime::currentTime().toString("hh:mm"), true)));
|
||||
|
@ -183,10 +186,13 @@ void ChatForm::onFileRecvRequest(ToxFile file)
|
|||
f->widget->updateStatusLight();
|
||||
}
|
||||
|
||||
QString name = f->getName();
|
||||
if (name == previousName)
|
||||
name = "";
|
||||
previousName = f->getName();
|
||||
QString name;
|
||||
ToxID friendId = f->getToxID();
|
||||
if (friendId != previousId)
|
||||
{
|
||||
name = f->getName();
|
||||
previousId = friendId;
|
||||
}
|
||||
|
||||
chatWidget->insertMessage(ChatActionPtr(new FileTransferAction(fileTrans, getElidedName(name),
|
||||
QTime::currentTime().toString("hh:mm"), false)));
|
||||
|
@ -655,20 +661,16 @@ void ChatForm::onLoadHistory()
|
|||
|
||||
auto msgs = HistoryKeeper::getInstance()->getChatHistory(HistoryKeeper::ctSingle, f->userId, fromTime, toTime);
|
||||
|
||||
QString storedPrevName = previousName;
|
||||
previousName = "";
|
||||
ToxID storedPrevId;
|
||||
std::swap(storedPrevId, previousId);
|
||||
QList<ChatActionPtr> historyMessages;
|
||||
|
||||
for (const auto &it : msgs)
|
||||
{
|
||||
QString name = f->getName();
|
||||
if (it.sender == Core::getInstance()->getSelfId().publicKey)
|
||||
name = Core::getInstance()->getUsername();
|
||||
|
||||
ChatActionPtr ca = genMessageActionAction(name, it.message, false, it.timestamp.toLocalTime());
|
||||
ChatActionPtr ca = genMessageActionAction(ToxID::fromString(it.sender), it.message, false, it.timestamp.toLocalTime());
|
||||
historyMessages.append(ca);
|
||||
}
|
||||
previousName = storedPrevName;
|
||||
std::swap(storedPrevId, previousId);
|
||||
|
||||
int savedSliderPos = chatWidget->verticalScrollBar()->maximum() - chatWidget->verticalScrollBar()->value();
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "src/widget/chatareawidget.h"
|
||||
#include "src/widget/tool/chattextedit.h"
|
||||
#include "src/widget/maskablepixmapwidget.h"
|
||||
#include "src/core.h"
|
||||
|
||||
GenericChatForm::GenericChatForm(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
|
@ -191,17 +192,42 @@ void GenericChatForm::onSaveLogClicked()
|
|||
file.close();
|
||||
}
|
||||
|
||||
void GenericChatForm::addMessage(const QString &author, const QString &message, bool isAction, const QDateTime &datetime)
|
||||
/// THIS FUNCTION IS DEPRECATED
|
||||
/// The only reason it's still alive is because the groupchat API is a bit limited
|
||||
void GenericChatForm::addMessage(const QString& author, const QString &message, bool isAction, const QDateTime &datetime)
|
||||
{
|
||||
ChatActionPtr ca = genMessageActionAction(author, message, isAction, datetime);
|
||||
chatWidget->insertMessage(ca);
|
||||
}
|
||||
|
||||
void GenericChatForm::addAlertMessage(QString author, QString message, QDateTime datetime)
|
||||
void GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime)
|
||||
{
|
||||
ChatActionPtr ca = genMessageActionAction(author, message, isAction, datetime);
|
||||
chatWidget->insertMessage(ca);
|
||||
}
|
||||
|
||||
void GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime)
|
||||
{
|
||||
ChatActionPtr ca = genSelfActionAction(message, isAction, datetime);
|
||||
chatWidget->insertMessage(ca);
|
||||
}
|
||||
|
||||
/// THIS FUNCTION IS DEPRECATED
|
||||
/// The only reason it's still alive is because the groupchat API is a bit limited
|
||||
void GenericChatForm::addAlertMessage(const QString& author, QString message, QDateTime datetime)
|
||||
{
|
||||
QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
|
||||
chatWidget->insertMessage(ChatActionPtr(new AlertAction(author, message, date)));
|
||||
previousName = author;
|
||||
|
||||
previousId.publicKey = author;
|
||||
}
|
||||
|
||||
void GenericChatForm::addAlertMessage(const ToxID &author, QString message, QDateTime datetime)
|
||||
{
|
||||
QString authorStr = Core::getInstance()->getPeerName(author);
|
||||
QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
|
||||
chatWidget->insertMessage(ChatActionPtr(new AlertAction(authorStr, message, date)));
|
||||
previousId = author;
|
||||
}
|
||||
|
||||
void GenericChatForm::onEmoteButtonClicked()
|
||||
|
@ -253,7 +279,7 @@ QString GenericChatForm::getElidedName(const QString& name)
|
|||
void GenericChatForm::clearChatArea(bool notinform)
|
||||
{
|
||||
chatWidget->clearChatArea();
|
||||
previousName = "";
|
||||
previousId = ToxID();
|
||||
|
||||
if (!notinform)
|
||||
addSystemInfoMessage(tr("Cleared"), "white", QDateTime::currentDateTime());
|
||||
|
@ -265,6 +291,8 @@ void GenericChatForm::clearChatArea(bool notinform)
|
|||
}
|
||||
}
|
||||
|
||||
/// THIS FUNCTION IS DEPRECATED
|
||||
/// The only reason it's still alive is because the groupchat API is a bit limited
|
||||
ChatActionPtr GenericChatForm::genMessageActionAction(const QString &author, QString message, bool isAction, const QDateTime &datetime)
|
||||
{
|
||||
if (earliestMessage == nullptr)
|
||||
|
@ -283,23 +311,99 @@ ChatActionPtr GenericChatForm::genMessageActionAction(const QString &author, QSt
|
|||
|
||||
if (isAction)
|
||||
{
|
||||
previousName = ""; // next msg has a name regardless
|
||||
previousId = ToxID(); // next msg has a name regardless
|
||||
return ChatActionPtr(new ActionAction (getElidedName(author), message, date, isMe));
|
||||
}
|
||||
|
||||
ChatActionPtr res;
|
||||
if (previousName == author)
|
||||
res = ChatActionPtr(new MessageAction("", message, date, isMe));
|
||||
if (previousId.publicKey == author)
|
||||
res = ChatActionPtr(new MessageAction(QString(), message, date, isMe));
|
||||
else
|
||||
res = ChatActionPtr(new MessageAction(getElidedName(author), message, date, isMe));
|
||||
|
||||
previousName = author;
|
||||
previousId.publicKey = author;
|
||||
return res;
|
||||
}
|
||||
|
||||
ChatActionPtr GenericChatForm::genMessageActionAction(const ToxID& author, QString message, bool isAction, const QDateTime &datetime)
|
||||
{
|
||||
if (earliestMessage == nullptr)
|
||||
{
|
||||
earliestMessage = new QDateTime(datetime);
|
||||
}
|
||||
|
||||
const Core* core = Core::getInstance();
|
||||
|
||||
QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
|
||||
bool isMe = (author == core->getSelfId());
|
||||
QString authorStr;
|
||||
if (isMe)
|
||||
authorStr = core->getUsername();
|
||||
else
|
||||
authorStr = core->getPeerName(author);
|
||||
|
||||
if (authorStr.isEmpty()) // Fallback if we can't find a username
|
||||
authorStr = author.toString();
|
||||
|
||||
if (!isAction && message.startsWith("/me "))
|
||||
{ // always render actions regardless of what core thinks
|
||||
isAction = true;
|
||||
message = message.right(message.length()-4);
|
||||
}
|
||||
|
||||
if (isAction)
|
||||
{
|
||||
previousId = ToxID(); // next msg has a name regardless
|
||||
return ChatActionPtr(new ActionAction (getElidedName(authorStr), message, date, isMe));
|
||||
}
|
||||
|
||||
ChatActionPtr res;
|
||||
if (previousId == author)
|
||||
res = ChatActionPtr(new MessageAction(QString(), message, date, isMe));
|
||||
else
|
||||
res = ChatActionPtr(new MessageAction(getElidedName(authorStr), message, date, isMe));
|
||||
|
||||
previousId = author;
|
||||
return res;
|
||||
}
|
||||
|
||||
ChatActionPtr GenericChatForm::genSelfActionAction(QString message, bool isAction, const QDateTime &datetime)
|
||||
{
|
||||
if (earliestMessage == nullptr)
|
||||
{
|
||||
earliestMessage = new QDateTime(datetime);
|
||||
}
|
||||
|
||||
const Core* core = Core::getInstance();
|
||||
|
||||
QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
|
||||
QString author = core->getUsername();;
|
||||
|
||||
if (!isAction && message.startsWith("/me "))
|
||||
{ // always render actions regardless of what core thinks
|
||||
isAction = true;
|
||||
message = message.right(message.length()-4);
|
||||
}
|
||||
|
||||
if (isAction)
|
||||
{
|
||||
previousId = ToxID(); // next msg has a name regardless
|
||||
return ChatActionPtr(new ActionAction (getElidedName(author), message, date, true));
|
||||
}
|
||||
|
||||
ChatActionPtr res;
|
||||
if (previousId.isMine())
|
||||
res = ChatActionPtr(new MessageAction(QString(), message, date, true));
|
||||
else
|
||||
res = ChatActionPtr(new MessageAction(getElidedName(author), message, date, true));
|
||||
|
||||
previousId = Core::getInstance()->getSelfId();
|
||||
return res;
|
||||
}
|
||||
|
||||
ChatActionPtr GenericChatForm::genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime)
|
||||
{
|
||||
previousName = "";
|
||||
previousId = ToxID();
|
||||
QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
|
||||
|
||||
return ChatActionPtr(new SystemMessageAction(message, type, date));
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <QDateTime>
|
||||
#include <QMenu>
|
||||
#include "src/widget/tool/chatactions/chataction.h"
|
||||
#include "src/corestructs.h"
|
||||
|
||||
// Spacing in px inserted when the author of the last message changes
|
||||
#define AUTHOR_CHANGE_SPACING 5 // why the hell is this a thing? surely the different font is enough?
|
||||
|
@ -33,6 +34,7 @@ class CroppingLabel;
|
|||
class ChatTextEdit;
|
||||
class ChatAreaWidget;
|
||||
class MaskablePixmapWidget;
|
||||
struct ToxID;
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
|
@ -46,9 +48,12 @@ public:
|
|||
|
||||
virtual void setName(const QString &newName);
|
||||
virtual void show(Ui::MainWindow &ui);
|
||||
void addMessage(const QString &author, const QString &message, bool isAction, const QDateTime &datetime);
|
||||
void addMessage(const QString& author, const QString &message, bool isAction, const QDateTime &datetime); ///< Deprecated
|
||||
void addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime);
|
||||
void addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime);
|
||||
void addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime);
|
||||
void addAlertMessage(QString author, QString message, QDateTime datetime);
|
||||
void addAlertMessage(const QString& author, QString message, QDateTime datetime); ///< Deprecated
|
||||
void addAlertMessage(const ToxID& author, QString message, QDateTime datetime);
|
||||
int getNumberOfMessages();
|
||||
|
||||
signals:
|
||||
|
@ -67,10 +72,14 @@ protected slots:
|
|||
|
||||
protected:
|
||||
QString getElidedName(const QString& name);
|
||||
ChatActionPtr genMessageActionAction(const QString &author, QString message, bool isAction, const QDateTime &datetime);
|
||||
ChatActionPtr genMessageActionAction(const QString& author, QString message, bool isAction, const QDateTime &datetime); ///< Deprecated
|
||||
ChatActionPtr genMessageActionAction(const ToxID& author, QString message, bool isAction, const QDateTime &datetime);
|
||||
ChatActionPtr genSelfActionAction(QString message, bool isAction, const QDateTime &datetime);
|
||||
ChatActionPtr genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime);
|
||||
|
||||
ToxID previousId;
|
||||
QMenu menu;
|
||||
int curRow;
|
||||
CroppingLabel *nameLabel;
|
||||
MaskablePixmapWidget *avatar;
|
||||
QWidget *headWidget;
|
||||
|
@ -78,9 +87,7 @@ protected:
|
|||
QVBoxLayout *headTextLayout;
|
||||
ChatTextEdit *msgEdit;
|
||||
QPushButton *sendButton;
|
||||
QString previousName;
|
||||
ChatAreaWidget *chatWidget;
|
||||
int curRow;
|
||||
QDateTime *earliestMessage;
|
||||
};
|
||||
|
||||
|
|
|
@ -721,7 +721,7 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message, bool
|
|||
return;
|
||||
|
||||
QDateTime timestamp = QDateTime::currentDateTime();
|
||||
f->chatForm->addMessage(f->getName(), message, isAction, timestamp);
|
||||
f->chatForm->addMessage(f->getToxID(), message, isAction, timestamp);
|
||||
|
||||
if (isAction)
|
||||
HistoryKeeper::getInstance()->addChatEntry(f->userId, "/me " + message, f->userId, timestamp);
|
||||
|
|
Loading…
Reference in New Issue
Block a user