Browse Source

Share bounded thumbnail workers and keep PM downloads in DM transport

master
evgeny 3 days ago
parent
commit
203ae61eda
  1. 1
      tools/chatgui/src/inputbar.h
  2. 42
      tools/chatgui/src/messagelist.cpp
  3. 6
      tools/chatgui/src/messagelist.h

1
tools/chatgui/src/inputbar.h

@ -67,7 +67,6 @@ private:
QPushButton *m_attachClearBtn = nullptr;
bool m_pttActive = false;
bool m_dmMode = false;
QString m_voiceFilePath;
QString m_mediaDirBase;
QString m_channelIdForRecord;
QString m_recordTarget;

42
tools/chatgui/src/messagelist.cpp

@ -965,23 +965,27 @@ void MessageList::onAttachmentDownloaded(const QString& chId, int64_t msgId) {
}
}
if (m.contentType == "video/mp4") {
QString fp = item->data(MsgVoiceFileRole).toString();
QString thumbPath = fp + ".jpg";
if (!fp.isEmpty() && QFile::exists(fp) && !QFile::exists(thumbPath)) {
QPointer<MessageList> self(this);
std::thread([self, fp, thumbPath]() {
int rc = video_extract_thumbnail(fp.toUtf8().constData(),
thumbPath.toUtf8().constData(), 320);
DEBUG_DEBUG(DEBUG_CATEGORY_VIDEO, "MessageList: thumbnail %s rc=%d",
qPrintable(thumbPath), rc);
if (self) {
QMetaObject::invokeMethod(self, [self]() { self->m_view->viewport()->update(); },
Qt::QueuedConnection);
}
}).detach();
}
}
if (m.contentType == "video/mp4") prepareVideoThumbnail(item->data(MsgVoiceFileRole).toString());
}
/* Общие превью для каналов/PM; не более двух decoder workers, без запуска из paint. */
void MessageList::prepareVideoThumbnail(const QString& path) {
if (path.isEmpty() || m_thumbnailJobs.contains(path) || !QFile::exists(path) || QFile::exists(path + ".jpg")) return;
m_thumbnailPool.setMaxThreadCount(2);
m_thumbnailJobs.insert(path);
QPointer<MessageList> self(this);
QObject* dispatcher = QCoreApplication::instance();
m_thumbnailPool.start([self, dispatcher, path]() {
QString output = path + ".jpg";
int rc = video_extract_thumbnail(path.toUtf8().constData(), output.toUtf8().constData(), 320);
if (rc) DEBUG_WARN(DEBUG_CATEGORY_VIDEO, "thumbnail failed path=%s error=%d", qPrintable(path), rc);
else DEBUG_DEBUG(DEBUG_CATEGORY_VIDEO, "thumbnail ready path=%s", qPrintable(output));
QMetaObject::invokeMethod(dispatcher, [self, path]() {
if (!self) return;
self->m_thumbnailJobs.remove(path);
self->m_view->viewport()->update();
}, Qt::QueuedConnection);
});
}
void MessageList::onMessageContextMenu(const QPoint& pos) {
@ -992,6 +996,7 @@ void MessageList::onMessageContextMenu(const QPoint& pos) {
bool isVideo = (ct == "video/mp4");
bool isImage = ct.startsWith("image/");
bool isDmFile = isDmChannel(idx.data(MsgChannelIdRole).toString()) && ct == "application/octet-stream";
bool isDm = isDmChannel(idx.data(MsgChannelIdRole).toString());
if (!isVideo && !isImage && !isDmFile) return;
QString filePath = idx.data(MsgVoiceFileRole).toString();
@ -1002,7 +1007,7 @@ void MessageList::onMessageContextMenu(const QPoint& pos) {
QAction* saveAct = menu.addAction(QString::fromUtf8("Сохранить в файл"));
saveAct->setEnabled(downloaded);
QAction* dlAct = nullptr;
if (!downloaded && !isDmFile) dlAct = menu.addAction(QString::fromUtf8("Скачать"));
if (!downloaded && !isDm) dlAct = menu.addAction(QString::fromUtf8("Скачать"));
QAction* chosen = menu.exec(m_view->viewport()->mapToGlobal(pos));
@ -1137,6 +1142,7 @@ void MessageList::onDmMessages(const uint8_t* data, int len) {
item->setData(duration, MsgVideoDurationMsRole);
item->setData(message.value("width").toInt(), MsgVideoWidthRole);
item->setData(message.value("height").toInt(), MsgVideoHeightRole);
prepareVideoThumbnail(path);
}
}
m_model->appendRow(item);

6
tools/chatgui/src/messagelist.h

@ -4,10 +4,11 @@
#include <QStandardItemModel>
#include <QHash>
#include <QTimer>
#include <QSet>
#include <QThreadPool>
class ChatView;
class InputBar;
class InputBar;
class EmojiPanel;
class DbManager;
class ChannelList;
@ -60,12 +61,15 @@ private:
QPushButton* m_radioBtn = nullptr; /* шапка: переключатель рации */
QPushButton* m_pttBtn = nullptr; /* плавающая кнопка PTT поверх чата */
bool m_radioOn = false;
QThreadPool m_thumbnailPool;
QSet<QString> m_thumbnailJobs;
QString authorName(quint64 nodeId) const;
void restoreScrollPosition(const QString& channelId);
void updateReadPosition();
void onMessageContextMenu(const QPoint& pos);
void requestDmMessages(const QString& channelId);
void prepareVideoThumbnail(const QString& path);
void onRadioToggled(bool on);
void updateRadioUi();
void layoutPttButton();

Loading…
Cancel
Save