|
|
|
|
@ -30,6 +30,7 @@ extern "C" {
|
|
|
|
|
#include "call_audio_engine.h" |
|
|
|
|
#include "radio_audio_engine.h" |
|
|
|
|
#include "ptt_hotkey_manager.h" |
|
|
|
|
#include "message_notification.h" |
|
|
|
|
|
|
|
|
|
extern "C" { |
|
|
|
|
#include "../../lib/audio_compressor.h" |
|
|
|
|
@ -92,9 +93,9 @@ static void saveLastChannelId(const QString& channelId) {
|
|
|
|
|
postUiStateKv("last_channel_id", channelId); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void onMsgReceivedCallback(const char* ch_id, int ch_id_len, uint64_t author) { |
|
|
|
|
static void onMsgReceivedCallback(const char* ch_id, int ch_id_len, uint64_t author, int initial_sync) { |
|
|
|
|
if (s_mainWindow) |
|
|
|
|
s_mainWindow->onMessageReceived(ch_id, ch_id_len, author); |
|
|
|
|
s_mainWindow->onMessageReceived(ch_id, ch_id_len, author, initial_sync != 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void onChannelUpdatedCallback(const char* ch_id, int ch_id_len) { |
|
|
|
|
@ -181,6 +182,7 @@ MainWindow::MainWindow(QWidget *parent, DbManager* db, const QString& cfgPath,
|
|
|
|
|
|
|
|
|
|
MainWindow::~MainWindow() { |
|
|
|
|
s_mainWindow = nullptr; |
|
|
|
|
if (m_messageNotification) m_messageNotification->dismiss("shutdown"); |
|
|
|
|
delete AvatarManager::instance(); |
|
|
|
|
delete GroupAvatarManager::instance(); |
|
|
|
|
gui_bridge_set_group_avatar_result_cb(nullptr); |
|
|
|
|
@ -799,6 +801,7 @@ void MainWindow::onMessageLinkActivated(const QString& link) {
|
|
|
|
|
|
|
|
|
|
void MainWindow::onDmMsgReceived(const QString& convId, quint64 author) { |
|
|
|
|
QString key = QStringLiteral("dm:") + convId; |
|
|
|
|
showIncomingMessageNotification(key, author); |
|
|
|
|
if (m_currentChannelId == key) { |
|
|
|
|
m_messageList->refresh(); |
|
|
|
|
return; |
|
|
|
|
@ -813,6 +816,18 @@ void MainWindow::setupTray() {
|
|
|
|
|
m_trayIcon->setIcon(QIcon(":/icons/app_icon.png")); |
|
|
|
|
m_trayIcon->setToolTip("vibechat"); |
|
|
|
|
|
|
|
|
|
m_messageNotification = new MessageNotification(this); |
|
|
|
|
connect(m_messageNotification, &MessageNotification::activated, this, [this](const QString& target) { |
|
|
|
|
if (isMinimized()) setWindowState(windowState() & ~Qt::WindowMinimized); |
|
|
|
|
show(); |
|
|
|
|
raise(); |
|
|
|
|
activateWindow(); |
|
|
|
|
reloadChannels(); |
|
|
|
|
m_channelList->selectChannel(target); |
|
|
|
|
if (m_currentChannelId != target) GUI_WARN("notification: target no longer available target=%s", qPrintable(target)); |
|
|
|
|
else GUI_INFO("notification: opened chat target=%s", qPrintable(target)); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
m_trayMenu = new QMenu(this); |
|
|
|
|
QAction *settingsAction = m_trayMenu->addAction(QCoreApplication::translate("ChatGui", "Settings")); |
|
|
|
|
connect(settingsAction, &QAction::triggered, this, &MainWindow::showSettings); |
|
|
|
|
@ -837,6 +852,30 @@ void MainWindow::setupTray() {
|
|
|
|
|
m_trayIcon->show(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::showIncomingMessageNotification(const QString& target, quint64 author) { |
|
|
|
|
if (!m_db || !m_db->isOpen() || !m_messageNotification) { |
|
|
|
|
GUI_WARN("notification: GUI not ready target=%s author=%llu", qPrintable(target), (unsigned long long)author); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (author == m_db->myNodeId() || isActiveWindow()) { |
|
|
|
|
GUI_DEBUG("notification: skipped target=%s own=%d window_active=%d", |
|
|
|
|
qPrintable(target), int(author == m_db->myNodeId()), int(isActiveWindow())); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
QString channel; |
|
|
|
|
if (target.startsWith(QStringLiteral("dm:"))) channel = QCoreApplication::translate("ChatGui", "Direct messages"); |
|
|
|
|
else { |
|
|
|
|
for (const auto& row : m_db->getChannels()) { |
|
|
|
|
if (row.channelId == target) { channel = row.name.isEmpty() ? target : row.name; break; } |
|
|
|
|
} |
|
|
|
|
if (channel.isEmpty()) { |
|
|
|
|
GUI_WARN("notification: channel no longer available target=%s", qPrintable(target)); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
m_messageNotification->showMessage(target, m_db->getDisplayName(author), channel, m_trayIcon->geometry()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event) { |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_GENERAL, "MainWindow: closeEvent — hiding to tray"); |
|
|
|
|
saveWindowGeometry(); |
|
|
|
|
@ -848,6 +887,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
|
|
|
|
|
|
|
|
|
void MainWindow::requestShutdown() { |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_GENERAL, "MainWindow: requestShutdown — saving geometry and stopping node"); |
|
|
|
|
if (m_messageNotification) m_messageNotification->dismiss("shutdown"); |
|
|
|
|
saveWindowGeometry(); |
|
|
|
|
if (m_node) m_node->requestStop(); |
|
|
|
|
} |
|
|
|
|
@ -951,8 +991,9 @@ void MainWindow::openImage(const QString& filePath) {
|
|
|
|
|
m_imageViewer->showFullScreen(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::onMessageReceived(const char* ch_id, int ch_id_len, uint64_t author) { |
|
|
|
|
void MainWindow::onMessageReceived(const char* ch_id, int ch_id_len, uint64_t author, bool initialSync) { |
|
|
|
|
QString cid = QString::fromUtf8(ch_id, ch_id_len); |
|
|
|
|
if (!initialSync) showIncomingMessageNotification(cid, author); |
|
|
|
|
if (m_db && author != m_db->myNodeId() |
|
|
|
|
&& m_db->getUiStateInt(QStringLiteral("ch_%1_sound_on_message").arg(cid), 1)) |
|
|
|
|
SoundManager::instance()->play("msg_incoming"); |
|
|
|
|
|