mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-07 23:53:58 +02:00
Replaced voice record processing with VoiceRecordBar in ComposeControls.
This commit is contained in:
parent
112dea8594
commit
fd76b44dbd
2 changed files with 57 additions and 248 deletions
|
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
|
#include "history/view/controls/history_view_voice_record_bar.h"
|
||||||
#include "history/view/history_view_webpage_preview.h"
|
#include "history/view/history_view_webpage_preview.h"
|
||||||
#include "inline_bots/inline_results_widget.h"
|
#include "inline_bots/inline_results_widget.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
@ -57,6 +58,7 @@ using MessageToEdit = ComposeControls::MessageToEdit;
|
||||||
using VoiceToSend = ComposeControls::VoiceToSend;
|
using VoiceToSend = ComposeControls::VoiceToSend;
|
||||||
using SendActionUpdate = ComposeControls::SendActionUpdate;
|
using SendActionUpdate = ComposeControls::SendActionUpdate;
|
||||||
using SetHistoryArgs = ComposeControls::SetHistoryArgs;
|
using SetHistoryArgs = ComposeControls::SetHistoryArgs;
|
||||||
|
using VoiceRecordBar = HistoryView::Controls::VoiceRecordBar;
|
||||||
|
|
||||||
[[nodiscard]] auto ShowWebPagePreview(WebPageData *page) {
|
[[nodiscard]] auto ShowWebPagePreview(WebPageData *page) {
|
||||||
return page && (page->pendingTill >= 0);
|
return page && (page->pendingTill >= 0);
|
||||||
|
@ -500,7 +502,7 @@ ComposeControls::ComposeControls(
|
||||||
, _mode(mode)
|
, _mode(mode)
|
||||||
, _wrap(std::make_unique<Ui::RpWidget>(parent))
|
, _wrap(std::make_unique<Ui::RpWidget>(parent))
|
||||||
, _writeRestricted(std::make_unique<Ui::RpWidget>(parent))
|
, _writeRestricted(std::make_unique<Ui::RpWidget>(parent))
|
||||||
, _send(Ui::CreateChild<Ui::SendButton>(_wrap.get()))
|
, _send(std::make_shared<Ui::SendButton>(_wrap.get()))
|
||||||
, _attachToggle(Ui::CreateChild<Ui::IconButton>(
|
, _attachToggle(Ui::CreateChild<Ui::IconButton>(
|
||||||
_wrap.get(),
|
_wrap.get(),
|
||||||
st::historyAttach))
|
st::historyAttach))
|
||||||
|
@ -516,18 +518,16 @@ ComposeControls::ComposeControls(
|
||||||
, _header(std::make_unique<FieldHeader>(
|
, _header(std::make_unique<FieldHeader>(
|
||||||
_wrap.get(),
|
_wrap.get(),
|
||||||
&_window->session().data()))
|
&_window->session().data()))
|
||||||
, _textUpdateEvents(TextUpdateEvent::SendTyping)
|
, _voiceRecordBar(std::make_unique<VoiceRecordBar>(
|
||||||
, _recordCancelWidth(st::historyRecordFont->width(tr::lng_record_cancel(tr::now)))
|
_wrap.get(),
|
||||||
, _recordingAnimation([=](crl::time now) {
|
window,
|
||||||
return recordingAnimationCallback(now);
|
_send,
|
||||||
}) {
|
st::historySendSize.height()))
|
||||||
|
, _textUpdateEvents(TextUpdateEvent::SendTyping) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
ComposeControls::~ComposeControls() {
|
ComposeControls::~ComposeControls() {
|
||||||
if (_recording) {
|
|
||||||
stopRecording(false);
|
|
||||||
}
|
|
||||||
setTabbedPanel(nullptr);
|
setTabbedPanel(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,91 +579,13 @@ int ComposeControls::heightCurrent() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComposeControls::focus() {
|
bool ComposeControls::focus() {
|
||||||
if (_recording) {
|
if (_voiceRecordBar->isRecording()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_field->setFocus();
|
_field->setFocus();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::updateControlsVisibility() {
|
|
||||||
if (_recording) {
|
|
||||||
_field->hide();
|
|
||||||
_tabbedSelectorToggle->hide();
|
|
||||||
//_botKeyboardShow->hide();
|
|
||||||
//_botKeyboardHide->hide();
|
|
||||||
//_botCommandStart->hide();
|
|
||||||
_attachToggle->hide();
|
|
||||||
//if (_silent) {
|
|
||||||
// _silent->hide();
|
|
||||||
//}
|
|
||||||
//if (_scheduled) {
|
|
||||||
// _scheduled->hide();
|
|
||||||
//}
|
|
||||||
//if (_kbShown) {
|
|
||||||
// _kbScroll->show();
|
|
||||||
//} else {
|
|
||||||
// _kbScroll->hide();
|
|
||||||
//}
|
|
||||||
} else {
|
|
||||||
_field->show();
|
|
||||||
//if (_kbShown) {
|
|
||||||
// _kbScroll->show();
|
|
||||||
// _tabbedSelectorToggle->hide();
|
|
||||||
// _botKeyboardHide->show();
|
|
||||||
// _botKeyboardShow->hide();
|
|
||||||
// _botCommandStart->hide();
|
|
||||||
//} else if (_kbReplyTo) {
|
|
||||||
// _kbScroll->hide();
|
|
||||||
// _tabbedSelectorToggle->show();
|
|
||||||
// _botKeyboardHide->hide();
|
|
||||||
// _botKeyboardShow->hide();
|
|
||||||
// _botCommandStart->hide();
|
|
||||||
//} else {
|
|
||||||
// _kbScroll->hide();
|
|
||||||
// _tabbedSelectorToggle->show();
|
|
||||||
// _botKeyboardHide->hide();
|
|
||||||
// if (_keyboard->hasMarkup()) {
|
|
||||||
// _botKeyboardShow->show();
|
|
||||||
// _botCommandStart->hide();
|
|
||||||
// } else {
|
|
||||||
// _botKeyboardShow->hide();
|
|
||||||
// if (_cmdStartShown) {
|
|
||||||
// _botCommandStart->show();
|
|
||||||
// } else {
|
|
||||||
// _botCommandStart->hide();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
_tabbedSelectorToggle->show();
|
|
||||||
_attachToggle->show();
|
|
||||||
//if (_silent) {
|
|
||||||
// _silent->show();
|
|
||||||
//}
|
|
||||||
//if (_scheduled) {
|
|
||||||
// _scheduled->show();
|
|
||||||
//}
|
|
||||||
//updateFieldPlaceholder();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ComposeControls::recordingAnimationCallback(crl::time now) {
|
|
||||||
const auto dt = anim::Disabled()
|
|
||||||
? 1.
|
|
||||||
: ((now - _recordingAnimation.started())
|
|
||||||
/ float64(kRecordingUpdateDelta));
|
|
||||||
if (dt >= 1.) {
|
|
||||||
_recordingLevel.finish();
|
|
||||||
} else {
|
|
||||||
_recordingLevel.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
if (!anim::Disabled()) {
|
|
||||||
_wrap->update(_attachToggle->geometry());
|
|
||||||
}
|
|
||||||
return (dt < 1.);
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> ComposeControls::cancelRequests() const {
|
rpl::producer<> ComposeControls::cancelRequests() const {
|
||||||
return _cancelRequests.events();
|
return _cancelRequests.events();
|
||||||
}
|
}
|
||||||
|
@ -693,7 +615,7 @@ rpl::producer<> ComposeControls::sendRequests() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<VoiceToSend> ComposeControls::sendVoiceRequests() const {
|
rpl::producer<VoiceToSend> ComposeControls::sendVoiceRequests() const {
|
||||||
return _sendVoiceRequests.events();
|
return _voiceRecordBar->sendVoiceRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<MessageToEdit> ComposeControls::editRequests() const {
|
rpl::producer<MessageToEdit> ComposeControls::editRequests() const {
|
||||||
|
@ -792,6 +714,7 @@ void ComposeControls::init() {
|
||||||
initTabbedSelector();
|
initTabbedSelector();
|
||||||
initSendButton();
|
initSendButton();
|
||||||
initWriteRestriction();
|
initWriteRestriction();
|
||||||
|
initVoiceRecordBar();
|
||||||
|
|
||||||
_wrap->sizeValue(
|
_wrap->sizeValue(
|
||||||
) | rpl::start_with_next([=](QSize size) {
|
) | rpl::start_with_next([=](QSize size) {
|
||||||
|
@ -841,99 +764,12 @@ void ComposeControls::init() {
|
||||||
cancelEditMessage();
|
cancelEditMessage();
|
||||||
}, _wrap->lifetime());
|
}, _wrap->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
orderControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::recordDone(
|
void ComposeControls::orderControls() {
|
||||||
QByteArray result,
|
_send->raise();
|
||||||
VoiceWaveform waveform,
|
|
||||||
int samples) {
|
|
||||||
if (result.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Window::ActivateWindow(_window);
|
|
||||||
const auto duration = samples / ::Media::Player::kDefaultFrequency;
|
|
||||||
_sendVoiceRequests.fire({ result, waveform, duration });
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComposeControls::recordUpdated(quint16 level, int samples) {
|
|
||||||
if (!_recording) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_recordingLevel.start(level);
|
|
||||||
_recordingAnimation.start();
|
|
||||||
_recordingSamples = samples;
|
|
||||||
if (samples < 0 || samples >= ::Media::Player::kDefaultFrequency * AudioVoiceMsgMaxLength) {
|
|
||||||
stopRecording(samples > 0 && _inField);
|
|
||||||
}
|
|
||||||
Core::App().updateNonIdle();
|
|
||||||
_wrap->update();
|
|
||||||
_sendActionUpdates.fire({ Api::SendProgressType::RecordVoice });
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComposeControls::recordStartCallback() {
|
|
||||||
using namespace ::Media::Capture;
|
|
||||||
const auto error = _history
|
|
||||||
? Data::RestrictionError(_history->peer, ChatRestriction::f_send_media)
|
|
||||||
: std::nullopt;
|
|
||||||
if (error) {
|
|
||||||
Ui::show(Box<InformBox>(*error));
|
|
||||||
return;
|
|
||||||
} else if (_showSlowmodeError && _showSlowmodeError()) {
|
|
||||||
return;
|
|
||||||
} else if (!instance()->available()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance()->start();
|
|
||||||
instance()->updated(
|
|
||||||
) | rpl::start_with_next_error([=](const Update &update) {
|
|
||||||
recordUpdated(update.level, update.samples);
|
|
||||||
}, [=] {
|
|
||||||
stopRecording(false);
|
|
||||||
}, _recordingLifetime);
|
|
||||||
|
|
||||||
_recording = _inField = true;
|
|
||||||
updateControlsVisibility();
|
|
||||||
_window->widget()->setInnerFocus();
|
|
||||||
|
|
||||||
_wrap->update();
|
|
||||||
|
|
||||||
_send->setRecordActive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComposeControls::recordStopCallback(bool active) {
|
|
||||||
stopRecording(active);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComposeControls::recordUpdateCallback(QPoint globalPos) {
|
|
||||||
updateOverStates(_wrap->mapFromGlobal(globalPos));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComposeControls::stopRecording(bool send) {
|
|
||||||
if (send) {
|
|
||||||
::Media::Capture::instance()->stop(crl::guard(_wrap.get(), [=](
|
|
||||||
const ::Media::Capture::Result &result) {
|
|
||||||
recordDone(result.bytes, result.waveform, result.samples);
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
::Media::Capture::instance()->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
_recordingLevel = anim::value();
|
|
||||||
_recordingAnimation.stop();
|
|
||||||
|
|
||||||
_recordingLifetime.destroy();
|
|
||||||
_recording = false;
|
|
||||||
_recordingSamples = 0;
|
|
||||||
_sendActionUpdates.fire({ Api::SendProgressType::RecordVoice, -1 });
|
|
||||||
|
|
||||||
updateControlsVisibility();
|
|
||||||
_window->widget()->setInnerFocus();
|
|
||||||
|
|
||||||
_wrap->update();
|
|
||||||
_send->setRecordActive(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComposeControls::showRecordButton() const {
|
bool ComposeControls::showRecordButton() const {
|
||||||
|
@ -943,30 +779,6 @@ bool ComposeControls::showRecordButton() const {
|
||||||
&& !isEditingMessage();
|
&& !isEditingMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::drawRecording(Painter &p, float64 recordActive) {
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
p.setBrush(st::historyRecordSignalColor);
|
|
||||||
|
|
||||||
auto delta = qMin(_recordingLevel.current() / 0x4000, 1.);
|
|
||||||
auto d = 2 * qRound(st::historyRecordSignalMin + (delta * (st::historyRecordSignalMax - st::historyRecordSignalMin)));
|
|
||||||
{
|
|
||||||
PainterHighQualityEnabler hq(p);
|
|
||||||
p.drawEllipse(_attachToggle->x() + (_tabbedSelectorToggle->width() - d) / 2, _attachToggle->y() + (_attachToggle->height() - d) / 2, d, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto duration = Ui::FormatDurationText(_recordingSamples / ::Media::Player::kDefaultFrequency);
|
|
||||||
p.setFont(st::historyRecordFont);
|
|
||||||
|
|
||||||
p.setPen(st::historyRecordDurationFg);
|
|
||||||
p.drawText(_attachToggle->x() + _tabbedSelectorToggle->width(), _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, duration);
|
|
||||||
|
|
||||||
int32 left = _attachToggle->x() + _tabbedSelectorToggle->width() + st::historyRecordFont->width(duration) + ((_send->width() - st::historyRecordVoice.width()) / 2);
|
|
||||||
int32 right = _wrap->width() - _send->width();
|
|
||||||
|
|
||||||
p.setPen(anim::pen(st::historyRecordCancel, st::historyRecordCancelActive, 1. - recordActive));
|
|
||||||
p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, tr::lng_record_cancel(tr::now));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComposeControls::drawRestrictedWrite(Painter &p, const QString &error) {
|
void ComposeControls::drawRestrictedWrite(Painter &p, const QString &error) {
|
||||||
p.fillRect(_writeRestricted->rect(), st::historyReplyBg);
|
p.fillRect(_writeRestricted->rect(), st::historyReplyBg);
|
||||||
|
|
||||||
|
@ -1023,7 +835,9 @@ void ComposeControls::fieldChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<SendActionUpdate> ComposeControls::sendActionUpdates() const {
|
rpl::producer<SendActionUpdate> ComposeControls::sendActionUpdates() const {
|
||||||
return _sendActionUpdates.events();
|
return rpl::merge(
|
||||||
|
_sendActionUpdates.events(),
|
||||||
|
_voiceRecordBar->sendActionUpdates());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::initTabbedSelector() {
|
void ComposeControls::initTabbedSelector() {
|
||||||
|
@ -1093,6 +907,29 @@ void ComposeControls::initWriteRestriction() {
|
||||||
}, _wrap->lifetime());
|
}, _wrap->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ComposeControls::initVoiceRecordBar() {
|
||||||
|
_voiceRecordBar->recordingStateChanges(
|
||||||
|
) | rpl::start_with_next([=](bool active) {
|
||||||
|
_field->setVisible(!active);
|
||||||
|
}, _wrap->lifetime());
|
||||||
|
|
||||||
|
_voiceRecordBar->startRecordingRequests(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
const auto error = _history
|
||||||
|
? Data::RestrictionError(
|
||||||
|
_history->peer,
|
||||||
|
ChatRestriction::f_send_media)
|
||||||
|
: std::nullopt;
|
||||||
|
if (error) {
|
||||||
|
Ui::show(Box<InformBox>(*error));
|
||||||
|
return;
|
||||||
|
} else if (_showSlowmodeError && _showSlowmodeError()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_voiceRecordBar->startRecording();
|
||||||
|
}, _wrap->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
void ComposeControls::updateWrappingVisibility() {
|
void ComposeControls::updateWrappingVisibility() {
|
||||||
const auto restricted = _writeRestriction.current().has_value();
|
const auto restricted = _writeRestriction.current().has_value();
|
||||||
_writeRestricted->setVisible(restricted);
|
_writeRestricted->setVisible(restricted);
|
||||||
|
@ -1124,16 +961,11 @@ void ComposeControls::updateSendButtonType() {
|
||||||
_send->setSlowmodeDelay(delay);
|
_send->setSlowmodeDelay(delay);
|
||||||
_send->setDisabled(_sendDisabledBySlowmode.current()
|
_send->setDisabled(_sendDisabledBySlowmode.current()
|
||||||
&& (type == Type::Send || type == Type::Record));
|
&& (type == Type::Send || type == Type::Record));
|
||||||
|
|
||||||
_send->setRecordStartCallback([=] { recordStartCallback(); });
|
|
||||||
_send->setRecordStopCallback([=](bool active) { recordStopCallback(active); });
|
|
||||||
_send->setRecordUpdateCallback([=](QPoint globalPos) { recordUpdateCallback(globalPos); });
|
|
||||||
_send->setRecordAnimationCallback([=] { _wrap->update(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::finishAnimating() {
|
void ComposeControls::finishAnimating() {
|
||||||
_send->finishAnimating();
|
_send->finishAnimating();
|
||||||
_recordingAnimation.stop();
|
_voiceRecordBar->finishAnimating();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::updateControlsGeometry(QSize size) {
|
void ComposeControls::updateControlsGeometry(QSize size) {
|
||||||
|
@ -1165,6 +997,11 @@ void ComposeControls::updateControlsGeometry(QSize size) {
|
||||||
_send->moveToRight(right, buttonsTop);
|
_send->moveToRight(right, buttonsTop);
|
||||||
right += _send->width();
|
right += _send->width();
|
||||||
_tabbedSelectorToggle->moveToRight(right, buttonsTop);
|
_tabbedSelectorToggle->moveToRight(right, buttonsTop);
|
||||||
|
|
||||||
|
_voiceRecordBar->resizeToWidth(size.width());
|
||||||
|
_voiceRecordBar->moveToLeft(
|
||||||
|
0,
|
||||||
|
size.height() - _voiceRecordBar->height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::updateOuterGeometry(QRect rect) {
|
void ComposeControls::updateOuterGeometry(QRect rect) {
|
||||||
|
@ -1178,24 +1015,10 @@ void ComposeControls::updateOuterGeometry(QRect rect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::updateOverStates(QPoint pos) {
|
|
||||||
const auto inField = _wrap->rect().contains(pos);
|
|
||||||
if (inField != _inField && _recording) {
|
|
||||||
_inField = inField;
|
|
||||||
_send->setRecordActive(_inField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComposeControls::paintBackground(QRect clip) {
|
void ComposeControls::paintBackground(QRect clip) {
|
||||||
Painter p(_wrap.get());
|
Painter p(_wrap.get());
|
||||||
|
|
||||||
p.fillRect(clip, st::historyComposeAreaBg);
|
p.fillRect(clip, st::historyComposeAreaBg);
|
||||||
if (!_field->isHidden() || _recording) {
|
|
||||||
//drawField(p, clip);
|
|
||||||
if (!_send->isHidden() && _recording) {
|
|
||||||
drawRecording(p, _send->recordActiveRatio());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::escape() {
|
void ComposeControls::escape() {
|
||||||
|
|
|
@ -56,6 +56,10 @@ enum class SendProgressType;
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
|
namespace Controls {
|
||||||
|
class VoiceRecordBar;
|
||||||
|
} // namespace Controls
|
||||||
|
|
||||||
class FieldHeader;
|
class FieldHeader;
|
||||||
|
|
||||||
class ComposeControls final {
|
class ComposeControls final {
|
||||||
|
@ -145,6 +149,7 @@ private:
|
||||||
void initSendButton();
|
void initSendButton();
|
||||||
void initWebpageProcess();
|
void initWebpageProcess();
|
||||||
void initWriteRestriction();
|
void initWriteRestriction();
|
||||||
|
void initVoiceRecordBar();
|
||||||
void updateSendButtonType();
|
void updateSendButtonType();
|
||||||
void updateHeight();
|
void updateHeight();
|
||||||
void updateWrappingVisibility();
|
void updateWrappingVisibility();
|
||||||
|
@ -153,6 +158,8 @@ private:
|
||||||
void updateOuterGeometry(QRect rect);
|
void updateOuterGeometry(QRect rect);
|
||||||
void paintBackground(QRect clip);
|
void paintBackground(QRect clip);
|
||||||
|
|
||||||
|
void orderControls();
|
||||||
|
|
||||||
void escape();
|
void escape();
|
||||||
void fieldChanged();
|
void fieldChanged();
|
||||||
void toggleTabbedSelectorMode();
|
void toggleTabbedSelectorMode();
|
||||||
|
@ -161,18 +168,7 @@ private:
|
||||||
|
|
||||||
void setTextFromEditingMessage(not_null<HistoryItem*> item);
|
void setTextFromEditingMessage(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
void recordUpdated(quint16 level, int samples);
|
|
||||||
void recordDone(QByteArray result, VoiceWaveform waveform, int samples);
|
|
||||||
|
|
||||||
bool recordingAnimationCallback(crl::time now);
|
|
||||||
void stopRecording(bool send);
|
|
||||||
|
|
||||||
void recordStartCallback();
|
|
||||||
void recordStopCallback(bool active);
|
|
||||||
void recordUpdateCallback(QPoint globalPos);
|
|
||||||
|
|
||||||
bool showRecordButton() const;
|
bool showRecordButton() const;
|
||||||
void drawRecording(Painter &p, float64 recordActive);
|
|
||||||
void drawRestrictedWrite(Painter &p, const QString &error);
|
void drawRestrictedWrite(Painter &p, const QString &error);
|
||||||
void updateOverStates(QPoint pos);
|
void updateOverStates(QPoint pos);
|
||||||
|
|
||||||
|
@ -188,7 +184,7 @@ private:
|
||||||
const std::unique_ptr<Ui::RpWidget> _wrap;
|
const std::unique_ptr<Ui::RpWidget> _wrap;
|
||||||
const std::unique_ptr<Ui::RpWidget> _writeRestricted;
|
const std::unique_ptr<Ui::RpWidget> _writeRestricted;
|
||||||
|
|
||||||
const not_null<Ui::SendButton*> _send;
|
const std::shared_ptr<Ui::SendButton> _send;
|
||||||
const not_null<Ui::IconButton*> _attachToggle;
|
const not_null<Ui::IconButton*> _attachToggle;
|
||||||
const not_null<Ui::EmojiButton*> _tabbedSelectorToggle;
|
const not_null<Ui::EmojiButton*> _tabbedSelectorToggle;
|
||||||
const not_null<Ui::InputField*> _field;
|
const not_null<Ui::InputField*> _field;
|
||||||
|
@ -197,32 +193,22 @@ private:
|
||||||
|
|
||||||
friend class FieldHeader;
|
friend class FieldHeader;
|
||||||
const std::unique_ptr<FieldHeader> _header;
|
const std::unique_ptr<FieldHeader> _header;
|
||||||
|
const std::unique_ptr<Controls::VoiceRecordBar> _voiceRecordBar;
|
||||||
|
|
||||||
rpl::event_stream<> _cancelRequests;
|
rpl::event_stream<> _cancelRequests;
|
||||||
rpl::event_stream<FileChosen> _fileChosen;
|
rpl::event_stream<FileChosen> _fileChosen;
|
||||||
rpl::event_stream<PhotoChosen> _photoChosen;
|
rpl::event_stream<PhotoChosen> _photoChosen;
|
||||||
rpl::event_stream<ChatHelpers::TabbedSelector::InlineChosen> _inlineResultChosen;
|
rpl::event_stream<ChatHelpers::TabbedSelector::InlineChosen> _inlineResultChosen;
|
||||||
rpl::event_stream<SendActionUpdate> _sendActionUpdates;
|
rpl::event_stream<SendActionUpdate> _sendActionUpdates;
|
||||||
rpl::event_stream<VoiceToSend> _sendVoiceRequests;
|
|
||||||
|
|
||||||
TextWithTags _localSavedText;
|
TextWithTags _localSavedText;
|
||||||
TextUpdateEvents _textUpdateEvents;
|
TextUpdateEvents _textUpdateEvents;
|
||||||
|
|
||||||
bool _recording = false;
|
|
||||||
bool _inField = false;
|
|
||||||
//bool _inReplyEditForward = false;
|
//bool _inReplyEditForward = false;
|
||||||
//bool _inClickable = false;
|
//bool _inClickable = false;
|
||||||
int _recordingSamples = 0;
|
|
||||||
int _recordCancelWidth;
|
|
||||||
rpl::lifetime _recordingLifetime;
|
|
||||||
|
|
||||||
rpl::lifetime _uploaderSubscriptions;
|
rpl::lifetime _uploaderSubscriptions;
|
||||||
|
|
||||||
// This can animate for a very long time (like in music playing),
|
|
||||||
// so it should be a Basic, not a Simple animation.
|
|
||||||
Ui::Animations::Basic _recordingAnimation;
|
|
||||||
anim::value _recordingLevel;
|
|
||||||
|
|
||||||
Fn<void()> _raiseEmojiSuggestions;
|
Fn<void()> _raiseEmojiSuggestions;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue