|
|
|
|
@ -49,6 +49,7 @@ void chat_core_save_ui_state_trampoline(void* arg);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#include "radio_audio_engine.h" |
|
|
|
|
#include "radiopanel.h" |
|
|
|
|
#include <QLabel> |
|
|
|
|
#include <QPushButton> |
|
|
|
|
#include <QHBoxLayout> |
|
|
|
|
@ -393,6 +394,10 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
|
|
|
|
layout->addWidget(header); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
m_radioPanel = new RadioPanel(this); |
|
|
|
|
m_radioPanel->hide(); |
|
|
|
|
layout->addWidget(m_radioPanel); |
|
|
|
|
|
|
|
|
|
m_view->setModel(m_model); |
|
|
|
|
auto* msgDelegate = new MessageDelegate(this); |
|
|
|
|
msgDelegate->setVideoOpenCallback([this](const QString& path) { |
|
|
|
|
@ -424,24 +429,6 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
|
|
|
|
m_view->setBackgroundImage("../resources/bg.png"); |
|
|
|
|
layout->addWidget(m_view, 1); |
|
|
|
|
|
|
|
|
|
/* ── плавающая PTT-кнопка поверх чата (видна при включённой рации) ── */ |
|
|
|
|
m_pttBtn = new QPushButton(QString::fromUtf8("\xF0\x9F\x8E\xA4"), this); |
|
|
|
|
m_pttBtn->setFixedSize(96, 96); |
|
|
|
|
m_pttBtn->setCursor(Qt::PointingHandCursor); |
|
|
|
|
m_pttBtn->setToolTip(QStringLiteral("Держите и говорите")); |
|
|
|
|
m_pttBtn->setStyleSheet( |
|
|
|
|
"QPushButton { border: 3px solid white; border-radius: 48px; background: #e74c3c; color: white; font-size: 36px; }" |
|
|
|
|
"QPushButton[transmitting=\"true\"] { background: #27ae60; }"); |
|
|
|
|
m_pttBtn->setProperty("transmitting", false); |
|
|
|
|
m_pttBtn->hide(); |
|
|
|
|
connect(RadioAudioEngine::instance(), &RadioAudioEngine::talkingChanged, this, [this](bool) { updateRadioUi(); }); |
|
|
|
|
connect(m_pttBtn, &QPushButton::pressed, this, []() { |
|
|
|
|
RadioAudioEngine::instance()->talkBegin(); |
|
|
|
|
}); |
|
|
|
|
connect(m_pttBtn, &QPushButton::released, this, []() { |
|
|
|
|
RadioAudioEngine::instance()->talkEnd(); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
if (s_icons.empty()) { |
|
|
|
|
for (const auto &cat : builtinEmojiSet()) { |
|
|
|
|
for (const auto &e : cat.items) { |
|
|
|
|
@ -1226,49 +1213,38 @@ void MessageList::onRadioToggled(bool on) {
|
|
|
|
|
if (groupId == 0) return; |
|
|
|
|
|
|
|
|
|
struct radio_set_active_arg* a = (struct radio_set_active_arg*)u_malloc(sizeof(*a)); |
|
|
|
|
if (!a) return; |
|
|
|
|
if (!a) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "RadioPanel: active request allocation failed group=%016llx", (unsigned long long)groupId); |
|
|
|
|
QSignalBlocker blocker(m_radioBtn); |
|
|
|
|
m_radioBtn->setChecked(m_radioOn); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
a->inst = gui_bridge_get_inst(); |
|
|
|
|
a->group_id = groupId; |
|
|
|
|
a->on = on ? 1 : 0; |
|
|
|
|
gui_bridge_post_uasync_fn(radio_set_active_trampoline, a); |
|
|
|
|
|
|
|
|
|
m_radioOn = on; |
|
|
|
|
if (on) { |
|
|
|
|
RadioAudioEngine::instance()->start(groupId); |
|
|
|
|
if (RadioAudioEngine::instance()->start(groupId) != 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "RadioPanel: radio start failed group=%016llx", (unsigned long long)groupId); |
|
|
|
|
auto* undo = static_cast<radio_set_active_arg*>(u_calloc(1, sizeof(radio_set_active_arg))); |
|
|
|
|
if (undo) { |
|
|
|
|
undo->inst = gui_bridge_get_inst(); undo->group_id = groupId; |
|
|
|
|
gui_bridge_post_uasync_fn(radio_set_active_trampoline, undo); |
|
|
|
|
} else DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "RadioPanel: cannot cancel failed radio subscription"); |
|
|
|
|
QSignalBlocker blocker(m_radioBtn); |
|
|
|
|
m_radioBtn->setChecked(false); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
RadioAudioEngine::instance()->stop(); |
|
|
|
|
m_talkingLabel->hide(); |
|
|
|
|
} |
|
|
|
|
m_radioOn = on; |
|
|
|
|
updateRadioUi(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MessageList::updateRadioUi() { |
|
|
|
|
if (!m_pttBtn) return; |
|
|
|
|
auto* audio = RadioAudioEngine::instance(); |
|
|
|
|
bool transmitting = audio->isTalking() && audio->groupId() == m_currentChannelId.toULongLong(); |
|
|
|
|
if (m_pttBtn->property("transmitting").toBool() != transmitting) { |
|
|
|
|
m_pttBtn->setProperty("transmitting", transmitting); |
|
|
|
|
m_pttBtn->style()->unpolish(m_pttBtn); |
|
|
|
|
m_pttBtn->style()->polish(m_pttBtn); |
|
|
|
|
m_pttBtn->update(); |
|
|
|
|
} |
|
|
|
|
bool show = m_radioOn && !isDmChannel(m_currentChannelId); |
|
|
|
|
m_pttBtn->setVisible(show); |
|
|
|
|
if (show) { |
|
|
|
|
m_pttBtn->raise(); |
|
|
|
|
layoutPttButton(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MessageList::layoutPttButton() { |
|
|
|
|
if (!m_pttBtn || !m_pttBtn->isVisible()) return; |
|
|
|
|
int w = width(); |
|
|
|
|
int x = (w - m_pttBtn->width()) / 2; |
|
|
|
|
int y = 48; /* под шапкой, поверх списка сообщений */ |
|
|
|
|
m_pttBtn->move(x, y); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MessageList::resizeEvent(QResizeEvent* event) { |
|
|
|
|
QWidget::resizeEvent(event); |
|
|
|
|
layoutPttButton(); |
|
|
|
|
m_radioPanel->setVisible(show); |
|
|
|
|
} |
|
|
|
|
|