|
|
|
@ -1054,21 +1054,40 @@ void MessageList::onMessageContextMenu(const QPoint& pos) { |
|
|
|
bool isImage = ct.startsWith("image/"); |
|
|
|
bool isImage = ct.startsWith("image/"); |
|
|
|
bool isDmFile = isDmChannel(idx.data(MsgChannelIdRole).toString()) && ct == "application/octet-stream"; |
|
|
|
bool isDmFile = isDmChannel(idx.data(MsgChannelIdRole).toString()) && ct == "application/octet-stream"; |
|
|
|
bool isDm = isDmChannel(idx.data(MsgChannelIdRole).toString()); |
|
|
|
bool isDm = isDmChannel(idx.data(MsgChannelIdRole).toString()); |
|
|
|
if (!isVideo && !isImage && !isDmFile) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString filePath = idx.data(MsgVoiceFileRole).toString(); |
|
|
|
QString filePath = idx.data(MsgVoiceFileRole).toString(); |
|
|
|
QString displayName = idx.data(MsgFileDisplayNameRole).toString(); |
|
|
|
QString displayName = idx.data(MsgFileDisplayNameRole).toString(); |
|
|
|
bool downloaded = !filePath.isEmpty() && QFile::exists(filePath); |
|
|
|
bool downloaded = !filePath.isEmpty() && QFile::exists(filePath); |
|
|
|
|
|
|
|
|
|
|
|
QMenu menu(m_view); |
|
|
|
QMenu menu(m_view); |
|
|
|
QAction* saveAct = menu.addAction(QCoreApplication::translate("ChatGui", "Save to file")); |
|
|
|
QString messageId = idx.data(MsgMessageKeyRole).toString(); |
|
|
|
saveAct->setEnabled(downloaded); |
|
|
|
if (!isDm && messageId.size() == 64) { |
|
|
|
|
|
|
|
if (ct == "poll") connect(menu.addAction(QCoreApplication::translate("ChatGui", "Vote / results")), &QAction::triggered, |
|
|
|
|
|
|
|
this, [this, messageId]() { showPoll(messageId); }); |
|
|
|
|
|
|
|
auto* reactions = menu.addMenu(QCoreApplication::translate("ChatGui", "React")); |
|
|
|
|
|
|
|
QSet<int> mine; |
|
|
|
|
|
|
|
for (const auto& value : m_feedback.value(messageId).value("reactions").toArray()) |
|
|
|
|
|
|
|
if (value.toObject().value("mine").toBool()) mine.insert(value.toObject().value("id").toInt()); |
|
|
|
|
|
|
|
for (unsigned i = 0; i < CHAT_REACTION_COUNT; i++) { |
|
|
|
|
|
|
|
auto* action = reactions->addAction(QString::fromUtf8(chat_reaction_emoji(i))); |
|
|
|
|
|
|
|
action->setCheckable(true); action->setChecked(mine.contains(i)); |
|
|
|
|
|
|
|
connect(action, &QAction::triggered, this, [this, messageId, i]() { |
|
|
|
|
|
|
|
sendFeedback({{"cmd", "react"}, {"message_id", messageId}, {"emoji", (int)i}}); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
connect(menu.addAction(QCoreApplication::translate("ChatGui", "Clear reactions")), &QAction::triggered, |
|
|
|
|
|
|
|
this, [this, messageId]() { sendFeedback({{"cmd", "react"}, {"message_id", messageId}, {"clear", true}}); }); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
QAction* saveAct = nullptr; |
|
|
|
|
|
|
|
if (isVideo || isImage || isDmFile) { |
|
|
|
|
|
|
|
saveAct = menu.addAction(QCoreApplication::translate("ChatGui", "Save to file")); saveAct->setEnabled(downloaded); |
|
|
|
|
|
|
|
} |
|
|
|
QAction* dlAct = nullptr; |
|
|
|
QAction* dlAct = nullptr; |
|
|
|
if (!downloaded && !isDm) dlAct = menu.addAction(QCoreApplication::translate("ChatGui", "Download")); |
|
|
|
if ((isVideo || isImage) && !downloaded && !isDm) dlAct = menu.addAction(QCoreApplication::translate("ChatGui", "Download")); |
|
|
|
|
|
|
|
|
|
|
|
QAction* chosen = menu.exec(m_view->viewport()->mapToGlobal(pos)); |
|
|
|
QAction* chosen = menu.exec(m_view->viewport()->mapToGlobal(pos)); |
|
|
|
|
|
|
|
|
|
|
|
if (chosen == saveAct) { |
|
|
|
if (saveAct && chosen == saveAct) { |
|
|
|
QString base = displayName; |
|
|
|
QString base = displayName; |
|
|
|
if (base.isEmpty()) base = QFileInfo(filePath).fileName(); |
|
|
|
if (base.isEmpty()) base = QFileInfo(filePath).fileName(); |
|
|
|
QString dest = QFileDialog::getSaveFileName(this, QCoreApplication::translate("ChatGui", "Save file"), base); |
|
|
|
QString dest = QFileDialog::getSaveFileName(this, QCoreApplication::translate("ChatGui", "Save file"), base); |
|
|
|
|