Centralize owned attachment downloads and key auto-play by channel and row
This commit is contained in:
1 parent
0d6fd63e8f
commit
6adfe5cf13
3 files changed
+34
-6
No files matched your search
@@ -30,12 +30,12 @@ class CallAudioEngine;
|
||||
class MemberFileBrowser;
|
||||
class MessageNotification;
|
||||
class QMessageBox;
|
||||
struct MessageRow;
|
||||
|
||||
struct AutoPlayItem {
|
||||
QString channelId;
|
||||
qint64 msgId = 0;
|
||||
bool downloadStarted = false;
|
||||
float durationSec = 0.0f;
|
||||
QString channelId; // Канал снимка; msgId уникален только внутри него.
|
||||
qint64 msgId = 0; // Локальный rowid сообщения.
|
||||
bool downloadStarted = false; // Команда загрузки принята очередью; false допускает первую попытку.
|
||||
};
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
@@ -108,8 +108,9 @@ private:
|
||||
void setupBridgeCallbacks();
|
||||
void setupConnects();
|
||||
void onShutdownCheck();
|
||||
void autoPlayCheckNewMessage(const QString& channelId);
|
||||
void autoPlayCheckNewMessage(const QString& channelId, qint64 msgId = 0);
|
||||
QString autoPlayMediaDir() const;
|
||||
QString autoPlayFilePath(const QString& channelId, const MessageRow& message) const;
|
||||
void showMemberFiles(const QString& channel, quint64 owner = 0);
|
||||
void showStreamPublisher(quint64 group, StreamGridWindow* returnTo = nullptr); // Управление; закрытие возвращает фокус сетке.
|
||||
|
||||
@@ -145,7 +146,8 @@ private:
|
||||
QTimer* m_cpuLoadTimer = nullptr;
|
||||
bool m_cpuLoadPending = false;
|
||||
QTimer* m_shutdownTimer = nullptr;
|
||||
QSet<int64_t> m_autoPlayDownloading; /* msgIds with download in progress */
|
||||
QSet<QPair<QString, qint64>> m_autoPlayDownloading; // (channel,rowid) ожидающей загрузки.
|
||||
QHash<QString, qint64> m_lastAutoPlayId; // Подавляет повторное добавление последнего сообщения канала.
|
||||
|
||||
QHash<quint64, CallWindow*> m_activeCalls; /* call_id → окно звонка */
|
||||
QPointer<QMessageBox> m_radioCallWindow;
|
||||
|
||||
@@ -98,6 +98,9 @@ int gui_bridge_post_uasync_owned_fn(void (*fn)(void*), void* arg);
|
||||
* 0 передаёт владение: fn освобождает arg после исполнения, мост — при отмене.
|
||||
* -1 оставляет блок вызывающему для u_free; вложенные ресурсы этим API не поддерживаются. */
|
||||
int gui_bridge_post_bound_fn(void (*fn)(void*), void* arg, struct UTUN_INSTANCE** binding);
|
||||
/* Скачать вложение канала: десятичный непустой channel (до 63 байт), msg_id>0.
|
||||
* Копия/привязка/владение принадлежат мосту. 0 — запрос принят, -1 — отказ с логом без heap-обязательств GUI. */
|
||||
int gui_bridge_download_attachment(const char* channel, int64_t msg_id);
|
||||
|
||||
/* Команды обычного звонка: GUI не передаёт instance или heap-аргументы.
|
||||
* Под mutex моста копируют данные, привязываются к живому running-ядру и передают владение очереди.
|
||||
|
||||
@@ -789,6 +789,29 @@ int gui_bridge_post_bound_fn(void (*fn)(void*), void* arg, struct UTUN_INSTANCE*
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Общий путь загрузки для delegate, контекстного меню и auto-play. */
|
||||
int gui_bridge_download_attachment(const char* channel, int64_t msg_id) {
|
||||
const size_t length = channel ? strnlen(channel, sizeof(attachment_dl_req::channel_id)) : 0;
|
||||
if (!length || length == sizeof(attachment_dl_req::channel_id) || strspn(channel, "0123456789") != length || msg_id <= 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment download rejected: invalid channel/id length=%zu id=%lld", length, (long long)msg_id);
|
||||
return -1;
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(bridge_mutex);
|
||||
if (!g_inst || !g_ua || !uasync_is_running(g_ua)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "attachment download rejected: core unavailable channel=%s id=%lld", channel, (long long)msg_id);
|
||||
return -1;
|
||||
}
|
||||
auto* request = static_cast<attachment_dl_req*>(u_calloc(1, sizeof(attachment_dl_req)));
|
||||
if (!request) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment download allocation failed"); return -1; }
|
||||
request->inst = g_inst; request->msg_id = msg_id; memcpy(request->channel_id, channel, length + 1);
|
||||
if (post_command(chat_core_attachment_download_trampoline, request, true) < 0) {
|
||||
u_free(request); DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment download queue failed channel=%s id=%lld", channel, (long long)msg_id);
|
||||
return -1;
|
||||
}
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_MEDIA, "attachment download queued channel=%s id=%lld", channel, (long long)msg_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Создание payload и enqueue атомарны относительно detach; GUI не читает заимствованный instance. */
|
||||
int gui_bridge_call_start(const char* channel, uint64_t peer, uint64_t call_id) {
|
||||
const size_t length = channel ? strnlen(channel, sizeof(call_start_arg::ch_id)) : 0;
|
||||
|
||||
Reference in new issue
Block a user