|
|
|
@ -1,5 +1,7 @@ |
|
|
|
#include "inputbar.h" |
|
|
|
#include "inputbar.h" |
|
|
|
#include "emojipanel.h" |
|
|
|
#include "emojipanel.h" |
|
|
|
|
|
|
|
#include "audiorecorder.h" |
|
|
|
|
|
|
|
#include "voicemessageencoder.h" |
|
|
|
#include "debug_ui.h" |
|
|
|
#include "debug_ui.h" |
|
|
|
#include <QDebug> |
|
|
|
#include <QDebug> |
|
|
|
#include <QTextEdit> |
|
|
|
#include <QTextEdit> |
|
|
|
@ -11,6 +13,8 @@ |
|
|
|
#include <QFontMetrics> |
|
|
|
#include <QFontMetrics> |
|
|
|
#include <QScrollBar> |
|
|
|
#include <QScrollBar> |
|
|
|
#include <QApplication> |
|
|
|
#include <QApplication> |
|
|
|
|
|
|
|
#include <QLabel> |
|
|
|
|
|
|
|
#include <QResizeEvent> |
|
|
|
|
|
|
|
|
|
|
|
static QPushButton *makeIconBtn(const QString &text, const QString &tooltip, QWidget *parent) { |
|
|
|
static QPushButton *makeIconBtn(const QString &text, const QString &tooltip, QWidget *parent) { |
|
|
|
auto *btn = new QPushButton(text, parent); |
|
|
|
auto *btn = new QPushButton(text, parent); |
|
|
|
@ -99,6 +103,33 @@ InputBar::InputBar(EmojiPanel *emojiPanel, AudioRecorder *recorder, QWidget *par |
|
|
|
m_input->setFocus(); |
|
|
|
m_input->setFocus(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Recording overlay — appears over the text input during recording */ |
|
|
|
|
|
|
|
m_recordOverlay = new QWidget(this); |
|
|
|
|
|
|
|
m_recordOverlay->setStyleSheet("background: rgba(231, 76, 60, 0.88); border-radius: 6px;"); |
|
|
|
|
|
|
|
m_recordOverlay->hide(); |
|
|
|
|
|
|
|
auto* roLayout = new QHBoxLayout(m_recordOverlay); |
|
|
|
|
|
|
|
roLayout->setContentsMargins(12, 0, 8, 0); |
|
|
|
|
|
|
|
roLayout->setSpacing(6); |
|
|
|
|
|
|
|
m_recordLabel = new QLabel(m_recordOverlay); |
|
|
|
|
|
|
|
m_recordLabel->setStyleSheet("color: white; font-size: 14px; font-weight: bold; background: transparent;"); |
|
|
|
|
|
|
|
roLayout->addWidget(m_recordLabel); |
|
|
|
|
|
|
|
roLayout->addStretch(); |
|
|
|
|
|
|
|
m_cancelRecBtn = new QPushButton(QString::fromUtf8("\xE2\x9C\x95"), m_recordOverlay); |
|
|
|
|
|
|
|
m_cancelRecBtn->setFixedSize(24, 24); |
|
|
|
|
|
|
|
m_cancelRecBtn->setStyleSheet( |
|
|
|
|
|
|
|
"QPushButton { border: none; color: white; font-size: 16px; background: transparent; }" |
|
|
|
|
|
|
|
"QPushButton:hover { color: #fdd; }"); |
|
|
|
|
|
|
|
connect(m_cancelRecBtn, &QPushButton::clicked, this, [this]() { |
|
|
|
|
|
|
|
if (m_recorder && m_recorder->isRecording()) m_recorder->stopRecording(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
roLayout->addWidget(m_cancelRecBtn); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (recorder) { |
|
|
|
|
|
|
|
connect(recorder, &AudioRecorder::recordingStarted, this, &InputBar::showRecordOverlay); |
|
|
|
|
|
|
|
connect(recorder, &AudioRecorder::recordingStopped, this, [this](int) { hideRecordOverlay(); }); |
|
|
|
|
|
|
|
connect(recorder, &AudioRecorder::durationChanged, this, &InputBar::updateRecordingUI); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool InputBar::eventFilter(QObject *obj, QEvent *event) { |
|
|
|
bool InputBar::eventFilter(QObject *obj, QEvent *event) { |
|
|
|
@ -151,9 +182,6 @@ void InputBar::onSendClicked() { |
|
|
|
m_input->setFocus(); |
|
|
|
m_input->setFocus(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#include "audiorecorder.h" |
|
|
|
|
|
|
|
#include "voicemessageencoder.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void InputBar::setRecordingContext(const QString& mediaDirBase, const QString& channelId) { |
|
|
|
void InputBar::setRecordingContext(const QString& mediaDirBase, const QString& channelId) { |
|
|
|
m_mediaDirBase = mediaDirBase; |
|
|
|
m_mediaDirBase = mediaDirBase; |
|
|
|
m_channelIdForRecord = channelId; |
|
|
|
m_channelIdForRecord = channelId; |
|
|
|
@ -197,3 +225,34 @@ void InputBar::onPttReleased() { |
|
|
|
emit sendVoiceMessage(filePath, durationMs); |
|
|
|
emit sendVoiceMessage(filePath, durationMs); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void InputBar::resizeEvent(QResizeEvent* event) { |
|
|
|
|
|
|
|
QWidget::resizeEvent(event); |
|
|
|
|
|
|
|
if (m_recordOverlay) { |
|
|
|
|
|
|
|
QRect r = m_input->geometry(); |
|
|
|
|
|
|
|
int margin = 4; |
|
|
|
|
|
|
|
m_recordOverlay->setGeometry(r.adjusted(margin, margin, -margin, -margin)); |
|
|
|
|
|
|
|
m_recordOverlay->raise(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void InputBar::showRecordOverlay() { |
|
|
|
|
|
|
|
if (m_recordOverlay) { |
|
|
|
|
|
|
|
m_recordOverlay->setGeometry(m_input->geometry().adjusted(4, 4, -4, -4)); |
|
|
|
|
|
|
|
m_recordOverlay->show(); |
|
|
|
|
|
|
|
m_recordOverlay->raise(); |
|
|
|
|
|
|
|
m_recordLabel->setText(QString::fromUtf8("\xF0\x9F\x94\xB4 Recording 0:00")); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void InputBar::hideRecordOverlay() { |
|
|
|
|
|
|
|
if (m_recordOverlay) m_recordOverlay->hide(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void InputBar::updateRecordingUI(int ms) { |
|
|
|
|
|
|
|
if (m_recordLabel) { |
|
|
|
|
|
|
|
int secs = ms / 1000; |
|
|
|
|
|
|
|
m_recordLabel->setText(QString::fromUtf8("\xF0\x9F\x94\xB4 Recording %1:%2") |
|
|
|
|
|
|
|
.arg(secs / 60).arg(secs % 60, 2, 10, QChar('0'))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|