Skip to content

Commit

Permalink
Send preprocessed reactions to html
Browse files Browse the repository at this point in the history
  • Loading branch information
Ri0n committed Jun 23, 2024
1 parent fee9191 commit 3e56fd1
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 122 deletions.
2 changes: 1 addition & 1 deletion iris
125 changes: 100 additions & 25 deletions src/chatview_webkit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,11 +618,101 @@ bool ChatView::handleCopyEvent(QObject *object, QEvent *event, ChatEdit *chatEdi
// input point of all messages
void ChatView::dispatchMessage(const MessageView &mv)
{
QVariantMap vm = mv.toVariantMap(d->isMuc_, true);
if (!mv.reactionsId().isEmpty()) {
sendJsObject(vm);
return;
static QHash<MessageView::Type, QString> types;
if (types.isEmpty()) {
types.insert(MessageView::Message, "message");
types.insert(MessageView::System, "system");
types.insert(MessageView::Status, "status");
types.insert(MessageView::Subject, "subject");
types.insert(MessageView::Urls, "urls");
types.insert(MessageView::MUCJoin, "join");
types.insert(MessageView::MUCPart, "part");
types.insert(MessageView::FileTransferRequest, "ftreq");
types.insert(MessageView::FileTransferFinished, "ftfin");
types.insert(MessageView::NickChange, "newnick");
types.insert(MessageView::Reactions, "reactions");
}
QVariantMap m;
m["time"] = mv.dateTime();
m["type"] = types.value(mv.type());
switch (mv.type()) {
case MessageView::Message:
m["message"] = d->prepareShares(ChatViewPrivate::closeIconTags(mv.formattedText()));
m["emote"] = mv.isEmote();
m["local"] = mv.isLocal();
m["sender"] = mv.nick();
m["userid"] = mv.userId();
m["spooled"] = mv.isSpooled();
m["id"] = mv.messageId();
if (d->isMuc_) { // maybe w/o conditions ?
m["alert"] = mv.isAlert();
} else {
m["awaitingReceipt"] = mv.isAwaitingReceipt();
}
if (mv.references().count()) {
QVariantMap rvm;
for (auto const &r : mv.references()) {
auto md = r->metaData();
md.insert("type", r->mimeType());
rvm.insert(r->sums()[0].toString(), md);
}
m["references"] = rvm;
}
break;
case MessageView::NickChange:
m["sender"] = mv.nick();
m["newnick"] = mv.userText();
m["message"] = ChatViewPrivate::closeIconTags(mv.text());
break;
case MessageView::MUCJoin: {
Jid j = d->jid_.withResource(mv.nick());
m["avatar"] = ChatViewJSObject::avatarUrl(d->account_->avatarFactory()->userHashes(j).avatar);
m["nickcolor"] = getMucNickColor(mv.nick(), mv.isLocal());
}
case MessageView::MUCPart:
m["nopartjoin"] = mv.isJoinLeaveHidden();
PSI_FALLSTHROUGH; // falls through
case MessageView::Status:
m["sender"] = mv.nick();
m["status"] = mv.status();
m["priority"] = mv.statusPriority();
m["message"] = ChatViewPrivate::closeIconTags(mv.text());
m["usertext"] = ChatViewPrivate::closeIconTags(mv.formattedUserText());
m["nostatus"] = mv.isStatusChangeHidden(); // looks strange? but chatview can use status for something anyway
break;
case MessageView::System:
case MessageView::Subject:
m["message"] = ChatViewPrivate::closeIconTags(mv.formattedText());
m["usertext"] = ChatViewPrivate::closeIconTags(mv.formattedUserText());
break;
case MessageView::Urls: {
QVariantMap vmUrls;
for (auto it = mv.urls().constBegin(); it != mv.urls().constEnd(); ++it) {
vmUrls.insert(it.key(), it.value());
}
m["urls"] = vmUrls;
break;
}
case MessageView::Reactions:
m["sender"] = mv.nick();
m["messageid"] = mv.reactionsId();
{
auto r = updateReactions(mv.nick(), mv.reactionsId(), mv.reactions());
auto vmr = QVariantMap();

QMapIterator<QString, QStringList> it(r);
while (it.hasNext()) {
it.next();
vmr[it.key()] = it.value();
}
m["reactions"] = vmr;
}
break;
case MessageView::FileTransferRequest:
case MessageView::FileTransferFinished:
break;
}

QString replaceId = mv.replaceId();
if (replaceId.isEmpty() && (mv.type() == MessageView::Message || mv.type() == MessageView::Subject)
&& updateLastMsgTime(mv.dateTime())) {
Expand All @@ -633,30 +723,15 @@ void ChatView::dispatchMessage(const MessageView &mv)
sendJsObject(m);
}

if (mv.type() == MessageView::MUCJoin) {
Jid j = d->jid_.withResource(mv.nick());
vm["avatar"] = ChatViewJSObject::avatarUrl(d->account_->avatarFactory()->userHashes(j).avatar);
vm["nickcolor"] = getMucNickColor(mv.nick(), mv.isLocal());
}
auto it = vm.find(QLatin1String("usertext"));
if (it != vm.end()) {
*it = ChatViewPrivate::closeIconTags(it.value().toString());
}
it = vm.find(QLatin1String("message"));
if (it != vm.end()) {
*it = d->prepareShares(it.value().toString());
*it = ChatViewPrivate::closeIconTags(it.value().toString());
}

vm["encrypted"] = d->isEncryptionEnabled_;
m["encrypted"] = d->isEncryptionEnabled_;
if (!replaceId.isEmpty()) {
vm["type"] = "replace";
vm["replaceId"] = replaceId;
m["type"] = "replace";
m["replaceId"] = replaceId;
} else {
vm["mtype"] = vm["type"];
vm["type"] = "message";
m["mtype"] = m["type"];
m["type"] = "message";
}
sendJsObject(vm);
sendJsObject(m);
}

void ChatView::sendJsCode(const QString &js)
Expand Down
37 changes: 37 additions & 0 deletions src/chatviewcommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ QString ChatViewCommon::getMucNickColor(const QString &nick, bool isSelf)
return QLatin1String("#000000"); // FIXME it's bad for fallback color
}

void ChatViewCommon::addUser(const QString &nickname) { }

void ChatViewCommon::removeUser(const QString &nickname) { }

void ChatViewCommon::renameUser(const QString &oldNickname, const QString &newNickname) { }

QList<QColor> &ChatViewCommon::generatePalette()
{
static QColor bg;
Expand Down Expand Up @@ -121,3 +127,34 @@ bool ChatViewCommon::compatibleColors(const QColor &c1, const QColor &c2)

return !((dC < 80. && dV > 100) || (dC < 110. && dV <= 100 && dV > 10) || (dC < 125. && dV <= 10));
}

const QMap<QString, QStringList> &
ChatViewCommon::updateReactions(const QString &senderNickname, const QString &messageId, const QSet<QString> &reactions)
{
auto msgIt = _reactions.find(messageId);
QSet<QString> toAdd = reactions;
QSet<QString> toRemove;

QHash<QString, QSet<QString>>::Iterator userIt;
if (msgIt != _reactions.end()) {
auto &sotredReactions = msgIt.value();
userIt = sotredReactions.perUser.find(senderNickname);
if (userIt != sotredReactions.perUser.end()) {
toAdd = reactions - userIt.value();
toRemove = userIt.value() - reactions;
} else {
userIt = sotredReactions.perUser.insert(senderNickname, {});
}
} else {
msgIt = _reactions.insert(messageId, {});
userIt = msgIt.value().perUser.insert(senderNickname, {});
}
*userIt = reactions;
for (auto const &v : toAdd) {
msgIt.value().total[v].append(senderNickname);
}
for (auto const &v : toRemove) {
msgIt.value().total[v].removeOne(senderNickname);
}
return msgIt.value().total;
}
22 changes: 18 additions & 4 deletions src/chatviewcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,28 @@ class ChatViewCommon {
QString getMucNickColor(const QString &, bool);
QList<QColor> getPalette();

protected:
struct Reactions {
QMap<QString, QStringList> total; // unicode reaction => nicknames
QHash<QString, QSet<QString>> perUser; // nickname => unicode reactions
};

void addUser(const QString &nickname);
void removeUser(const QString &nickname);
void renameUser(const QString &oldNickname, const QString &newNickname);

const QMap<QString, QStringList> &updateReactions(const QString &senderNickname, const QString &messageId,
const QSet<QString> &reactions);

protected:
QDateTime _lastMsgTime;

private:
QList<QColor> &generatePalette();
bool compatibleColors(const QColor &, const QColor &);
int _nickNumber;
QMap<QString, int> _nicks;
QList<QColor> &generatePalette();
bool compatibleColors(const QColor &, const QColor &);
int _nickNumber;
QMap<QString, int> _nicks;
QHash<QString, Reactions> _reactions; // messageId -> reactions
};

#endif // CHATVIEWBASE_H
87 changes: 1 addition & 86 deletions src/messageview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ MessageView MessageView::nickChangeMessage(const QString &nick, const QString &n
}

MessageView MessageView::reactionsMessage(const QString &nick, const QString &targetMessageId,
const QStringList &reactions)
const QSet<QString> &reactions)
{
MessageView mv(Reactions);
mv.setNick(nick);
Expand Down Expand Up @@ -173,88 +173,3 @@ QString MessageView::formattedUserText() const
}

bool MessageView::hasStatus() const { return _type == Status || _type == MUCJoin; }

QVariantMap MessageView::toVariantMap(bool isMuc, bool formatted) const
{
static QHash<Type, QString> types;
if (types.isEmpty()) {
types.insert(Message, "message");
types.insert(System, "system");
types.insert(Status, "status");
types.insert(Subject, "subject");
types.insert(Urls, "urls");
types.insert(MUCJoin, "join");
types.insert(MUCPart, "part");
types.insert(FileTransferRequest, "ftreq");
types.insert(FileTransferFinished, "ftfin");
types.insert(NickChange, "newnick");
types.insert(Reactions, "reactions");
}
QVariantMap m;
m["time"] = _dateTime;
m["type"] = types.value(_type);
switch (_type) {
case Message:
m["message"] = formatted ? formattedText() : _text;
m["emote"] = isEmote();
m["local"] = isLocal();
m["sender"] = _nick;
m["userid"] = _userId;
m["spooled"] = isSpooled();
m["id"] = _messageId;
if (isMuc) { // maybe w/o conditions ?
m["alert"] = isAlert();
} else {
m["awaitingReceipt"] = isAwaitingReceipt();
}
if (_references.count()) {
QVariantMap rvm;
for (auto const &r : _references) {
auto md = r->metaData();
md.insert("type", r->mimeType());
rvm.insert(r->sums()[0].toString(), md);
}
m["references"] = rvm;
}
break;
case NickChange:
m["sender"] = _nick;
m["newnick"] = _userText;
m["message"] = _text;
break;
case MUCJoin:
case MUCPart:
m["nopartjoin"] = isJoinLeaveHidden();
PSI_FALLSTHROUGH; // falls through
case Status:
m["sender"] = _nick;
m["status"] = _status;
m["priority"] = _statusPriority;
m["message"] = _text;
m["usertext"] = formatted ? formattedUserText() : _userText;
m["nostatus"] = isStatusChangeHidden(); // looks strange? but chatview can use status for something anyway
break;
case System:
case Subject:
m["message"] = formatted ? formattedText() : _text;
m["usertext"] = formatted ? formattedUserText() : _userText;
break;
case Urls: {
QVariantMap vmUrls;
for (auto it = _urls.constBegin(); it != _urls.constEnd(); ++it) {
vmUrls.insert(it.key(), it.value());
}
m["urls"] = vmUrls;
break;
}
case Reactions:
m["sender"] = _nick;
m["reactions"] = _reactions;
m["targetid"] = _reactionsId;
break;
case FileTransferRequest:
case FileTransferFinished:
break;
}
return m;
}
10 changes: 4 additions & 6 deletions src/messageview.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class MessageView {
const QString &statusText = QString());
static MessageView nickChangeMessage(const QString &nick, const QString &newNick);
static MessageView reactionsMessage(const QString &nick, const QString &targetMessageId,
const QStringList &reactions);
const QSet<QString> &reactions);

inline Type type() const { return _type; }
inline const QString &text() const { return _text; }
Expand Down Expand Up @@ -128,10 +128,8 @@ class MessageView {
inline XMPP::Message::CarbonDir carbonDirection() const { return _carbon; }
inline void addReference(FileSharingItem *fsi) { _references.append(fsi); }
inline const QList<FileSharingItem *> &references() const { return _references; }
inline void setReactions(const QStringList &r) { _reactions = r; }
inline const QStringList &reactions() const { return _reactions; }

QVariantMap toVariantMap(bool isMuc, bool formatted = false) const;
inline void setReactions(const QSet<QString> &r) { _reactions = r; }
inline const QSet<QString> &reactions() const { return _reactions; }

private:
Type _type;
Expand All @@ -150,7 +148,7 @@ class MessageView {
QString _reactionsId;
XMPP::Message::CarbonDir _carbon;
QList<FileSharingItem *> _references;
QStringList _reactions;
QSet<QString> _reactions;
};

Q_DECLARE_OPERATORS_FOR_FLAGS(MessageView::Flags)
Expand Down

0 comments on commit 3e56fd1

Please sign in to comment.