Replaced voice record processing with VoiceRecordBar in HistoryWidget.
This commit is contained in:
parent
fd76b44dbd
commit
db564ca486
4 changed files with 103 additions and 242 deletions
|
@ -29,9 +29,6 @@ enum {
|
|||
LinksOverviewPerPage = 12,
|
||||
MediaOverviewStartPerPage = 5,
|
||||
|
||||
AudioVoiceMsgMaxLength = 100 * 60, // 100 minutes
|
||||
AudioVoiceMsgChannels = 2, // stereo
|
||||
|
||||
PreloadHeightsCount = 3, // when 3 screens to scroll left make a preload request
|
||||
|
||||
SearchPeopleLimit = 5,
|
||||
|
|
|
@ -62,6 +62,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history_inner_widget.h"
|
||||
#include "history/history_item_components.h"
|
||||
//#include "history/feed/history_feed_section.h" // #feed
|
||||
#include "history/view/controls/history_view_voice_record_bar.h"
|
||||
#include "history/view/history_view_service_message.h"
|
||||
#include "history/view/history_view_element.h"
|
||||
#include "history/view/history_view_scheduled_section.h"
|
||||
|
@ -176,7 +177,7 @@ HistoryWidget::HistoryWidget(
|
|||
, _supportAutocomplete(session().supportMode()
|
||||
? object_ptr<Support::Autocomplete>(this, &session())
|
||||
: nullptr)
|
||||
, _send(this)
|
||||
, _send(std::make_shared<Ui::SendButton>(this))
|
||||
, _unblock(this, tr::lng_unblock_button(tr::now).toUpper(), st::historyUnblock)
|
||||
, _botStart(this, tr::lng_bot_start(tr::now).toUpper(), st::historyComposeButton)
|
||||
, _joinChannel(
|
||||
|
@ -192,15 +193,16 @@ HistoryWidget::HistoryWidget(
|
|||
, _botKeyboardShow(this, st::historyBotKeyboardShow)
|
||||
, _botKeyboardHide(this, st::historyBotKeyboardHide)
|
||||
, _botCommandStart(this, st::historyBotCommandStart)
|
||||
, _voiceRecordBar(std::make_unique<HistoryWidget::VoiceRecordBar>(
|
||||
this,
|
||||
controller,
|
||||
_send,
|
||||
st::historySendSize.height()))
|
||||
, _field(
|
||||
this,
|
||||
st::historyComposeField,
|
||||
Ui::InputField::Mode::MultiLine,
|
||||
tr::lng_message_ph())
|
||||
, _recordCancelWidth(st::historyRecordFont->width(tr::lng_record_cancel(tr::now)))
|
||||
, _recordingAnimation([=](crl::time now) {
|
||||
return recordingAnimationCallback(now);
|
||||
})
|
||||
, _kbScroll(this, st::botKbScroll)
|
||||
, _topShadow(this) {
|
||||
setAcceptDrops(true);
|
||||
|
@ -217,7 +219,7 @@ HistoryWidget::HistoryWidget(
|
|||
_send->addClickHandler([=] { sendButtonClicked(); });
|
||||
|
||||
SendMenu::SetupMenuAndShortcuts(
|
||||
_send,
|
||||
_send.get(),
|
||||
[=] { return sendButtonMenuType(); },
|
||||
[=] { sendSilent(); },
|
||||
[=] { sendScheduled(); });
|
||||
|
@ -349,10 +351,7 @@ HistoryWidget::HistoryWidget(
|
|||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
|
||||
_send->setRecordStartCallback([this] { recordStartCallback(); });
|
||||
_send->setRecordStopCallback([this](bool active) { recordStopCallback(active); });
|
||||
_send->setRecordUpdateCallback([this](QPoint globalPos) { recordUpdateCallback(globalPos); });
|
||||
_send->setRecordAnimationCallback([this] { updateField(); });
|
||||
initVoiceRecordBar();
|
||||
|
||||
_attachToggle->hide();
|
||||
_tabbedSelectorToggle->hide();
|
||||
|
@ -717,6 +716,48 @@ void HistoryWidget::refreshTabbedPanel() {
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::initVoiceRecordBar() {
|
||||
_voiceRecordBar->startRecordingRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto error = _peer
|
||||
? Data::RestrictionError(_peer, ChatRestriction::f_send_media)
|
||||
: std::nullopt;
|
||||
if (error) {
|
||||
Ui::show(Box<InformBox>(*error));
|
||||
return;
|
||||
} else if (showSlowmodeError()) {
|
||||
return;
|
||||
}
|
||||
_voiceRecordBar->startRecording();
|
||||
}, lifetime());
|
||||
|
||||
_voiceRecordBar->sendActionUpdates(
|
||||
) | rpl::start_with_next([=](const auto &data) {
|
||||
if (!_history) {
|
||||
return;
|
||||
}
|
||||
session().sendProgressManager().update(
|
||||
_history,
|
||||
data.type,
|
||||
data.progress);
|
||||
}, lifetime());
|
||||
|
||||
_voiceRecordBar->sendVoiceRequests(
|
||||
) | rpl::start_with_next([=](const auto &data) {
|
||||
if (!canWriteMessage() || data.bytes.isEmpty() || !_history) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto action = Api::SendAction(_history);
|
||||
action.replyTo = replyToId();
|
||||
session().api().sendVoiceMessage(
|
||||
data.bytes,
|
||||
data.waveform,
|
||||
data.duration,
|
||||
action);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void HistoryWidget::initTabbedSelector() {
|
||||
refreshTabbedPanel();
|
||||
|
||||
|
@ -1145,6 +1186,7 @@ void HistoryWidget::applyInlineBotQuery(UserData *bot, const QString &query) {
|
|||
}
|
||||
|
||||
void HistoryWidget::orderWidgets() {
|
||||
_send->raise();
|
||||
if (_contactStatus) {
|
||||
_contactStatus->raise();
|
||||
}
|
||||
|
@ -1343,6 +1385,10 @@ void HistoryWidget::writeDrafts(Data::Draft **localDraft, Data::Draft **editDraf
|
|||
}
|
||||
}
|
||||
|
||||
bool HistoryWidget::isRecording() const {
|
||||
return _voiceRecordBar->isRecording();
|
||||
}
|
||||
|
||||
void HistoryWidget::activate() {
|
||||
if (_history) {
|
||||
if (!_historyInited) {
|
||||
|
@ -1360,7 +1406,7 @@ void HistoryWidget::setInnerFocus() {
|
|||
} else if (_list) {
|
||||
if (_nonEmptySelection
|
||||
|| (_list && _list->wasSelectedText())
|
||||
|| _recording
|
||||
|| isRecording()
|
||||
|| isBotStart()
|
||||
|| isBlocked()
|
||||
|| !_canSendMessages) {
|
||||
|
@ -1371,41 +1417,6 @@ void HistoryWidget::setInnerFocus() {
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::recordDone(
|
||||
QByteArray result,
|
||||
VoiceWaveform waveform,
|
||||
int samples) {
|
||||
if (!canWriteMessage() || result.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Window::ActivateWindow(controller());
|
||||
const auto duration = samples / Media::Player::kDefaultFrequency;
|
||||
auto action = Api::SendAction(_history);
|
||||
action.replyTo = replyToId();
|
||||
session().api().sendVoiceMessage(result, waveform, duration, action);
|
||||
}
|
||||
|
||||
void HistoryWidget::recordUpdate(ushort level, int samples) {
|
||||
if (!_recording) {
|
||||
return;
|
||||
}
|
||||
|
||||
_recordingLevel.start(level);
|
||||
_recordingAnimation.start();
|
||||
_recordingSamples = samples;
|
||||
if (samples < 0 || samples >= Media::Player::kDefaultFrequency * AudioVoiceMsgMaxLength) {
|
||||
stopRecording(_peer && samples > 0 && _inField);
|
||||
}
|
||||
Core::App().updateNonIdle();
|
||||
updateField();
|
||||
if (_history) {
|
||||
session().sendProgressManager().update(
|
||||
_history,
|
||||
Api::SendProgressType::RecordVoice);
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query, UserData *samePeerBot, MsgId samePeerReplyTo) {
|
||||
if (samePeerBot) {
|
||||
if (_history) {
|
||||
|
@ -2125,63 +2136,45 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_muteUnmute->hide();
|
||||
_send->show();
|
||||
updateSendButtonType();
|
||||
if (_recording) {
|
||||
_field->hide();
|
||||
|
||||
_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();
|
||||
_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();
|
||||
_kbScroll->hide();
|
||||
_tabbedSelectorToggle->show();
|
||||
_botKeyboardHide->hide();
|
||||
if (_keyboard->hasMarkup()) {
|
||||
_botKeyboardShow->show();
|
||||
_botCommandStart->hide();
|
||||
} else {
|
||||
_kbScroll->hide();
|
||||
_tabbedSelectorToggle->show();
|
||||
_botKeyboardHide->hide();
|
||||
if (_keyboard->hasMarkup()) {
|
||||
_botKeyboardShow->show();
|
||||
_botCommandStart->hide();
|
||||
_botKeyboardShow->hide();
|
||||
if (_cmdStartShown) {
|
||||
_botCommandStart->show();
|
||||
} else {
|
||||
_botKeyboardShow->hide();
|
||||
if (_cmdStartShown) {
|
||||
_botCommandStart->show();
|
||||
} else {
|
||||
_botCommandStart->hide();
|
||||
}
|
||||
_botCommandStart->hide();
|
||||
}
|
||||
}
|
||||
_attachToggle->show();
|
||||
if (_silent) {
|
||||
_silent->show();
|
||||
}
|
||||
if (_scheduled) {
|
||||
_scheduled->show();
|
||||
}
|
||||
updateFieldPlaceholder();
|
||||
}
|
||||
_attachToggle->show();
|
||||
if (_silent) {
|
||||
_silent->show();
|
||||
}
|
||||
if (_scheduled) {
|
||||
_scheduled->show();
|
||||
}
|
||||
updateFieldPlaceholder();
|
||||
|
||||
if (_editMsgId || _replyToId || readyToForward() || (_previewData && _previewData->pendingTill >= 0) || _kbReplyTo) {
|
||||
if (_fieldBarCancel->isHidden()) {
|
||||
_fieldBarCancel->show();
|
||||
|
@ -3275,22 +3268,6 @@ void HistoryWidget::unreadMentionsAnimationFinish() {
|
|||
updateUnreadMentionsPosition();
|
||||
}
|
||||
|
||||
bool HistoryWidget::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()) {
|
||||
update(_attachToggle->geometry());
|
||||
}
|
||||
return (dt < 1.);
|
||||
}
|
||||
|
||||
void HistoryWidget::chooseAttach() {
|
||||
if (_editMsgId) {
|
||||
Ui::show(Box<InformBox>(tr::lng_edit_caption_attach(tr::now)));
|
||||
|
@ -3362,13 +3339,8 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
void HistoryWidget::updateOverStates(QPoint pos) {
|
||||
auto inField = pos.y() >= (_scroll->y() + _scroll->height()) && pos.y() < height() && pos.x() >= 0 && pos.x() < width();
|
||||
auto inReplyEditForward = QRect(st::historyReplySkip, _field->y() - st::historySendPadding - st::historyReplyHeight, width() - st::historyReplySkip - _fieldBarCancel->width(), st::historyReplyHeight).contains(pos) && (_editMsgId || replyToId() || readyToForward());
|
||||
auto inClickable = inReplyEditForward;
|
||||
if (inField != _inField && _recording) {
|
||||
_inField = inField;
|
||||
_send->setRecordActive(_inField);
|
||||
}
|
||||
_inReplyEditForward = inReplyEditForward;
|
||||
if (inClickable != _inClickable) {
|
||||
_inClickable = inClickable;
|
||||
|
@ -3382,85 +3354,11 @@ void HistoryWidget::leaveToChildEvent(QEvent *e, QWidget *child) { // e -- from
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::recordStartCallback() {
|
||||
using namespace Media::Capture;
|
||||
|
||||
const auto error = _peer
|
||||
? Data::RestrictionError(_peer, ChatRestriction::f_send_media)
|
||||
: std::nullopt;
|
||||
if (error) {
|
||||
Ui::show(Box<InformBox>(*error));
|
||||
return;
|
||||
} else if (showSlowmodeError()) {
|
||||
return;
|
||||
} else if (!instance()->available()) {
|
||||
return;
|
||||
}
|
||||
|
||||
instance()->start();
|
||||
instance()->updated(
|
||||
) | rpl::start_with_next_error([=](const Update &update) {
|
||||
recordUpdate(update.level, update.samples);
|
||||
}, [=] {
|
||||
stopRecording(false);
|
||||
}, _recordingLifetime);
|
||||
|
||||
_recording = _inField = true;
|
||||
updateControlsVisibility();
|
||||
activate();
|
||||
|
||||
updateField();
|
||||
|
||||
_send->setRecordActive(true);
|
||||
}
|
||||
|
||||
void HistoryWidget::recordStopCallback(bool active) {
|
||||
stopRecording(_peer && active);
|
||||
}
|
||||
|
||||
void HistoryWidget::recordUpdateCallback(QPoint globalPos) {
|
||||
updateOverStates(mapFromGlobal(globalPos));
|
||||
}
|
||||
|
||||
void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (_replyForwardPressed) {
|
||||
_replyForwardPressed = false;
|
||||
update(0, _field->y() - st::historySendPadding - st::historyReplyHeight, width(), st::historyReplyHeight);
|
||||
}
|
||||
if (_recording) {
|
||||
stopRecording(_peer && _inField);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::stopRecording(bool send) {
|
||||
if (send) {
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
Media::Capture::instance()->stop(crl::guard(this, [=](
|
||||
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;
|
||||
if (_history) {
|
||||
session().sendProgressManager().update(
|
||||
_history,
|
||||
Api::SendProgressType::RecordVoice,
|
||||
-1);
|
||||
}
|
||||
|
||||
updateControlsVisibility();
|
||||
activate();
|
||||
|
||||
updateField();
|
||||
_send->setRecordActive(false);
|
||||
}
|
||||
|
||||
void HistoryWidget::sendBotCommand(
|
||||
|
@ -3971,6 +3869,7 @@ void HistoryWidget::moveFieldControls() {
|
|||
_field->moveToLeft(left, bottom - _field->height() - st::historySendPadding);
|
||||
auto right = st::historySendRight;
|
||||
_send->moveToRight(right, buttonsBottom); right += _send->width();
|
||||
_voiceRecordBar->moveToLeft(0, bottom - _voiceRecordBar->height());
|
||||
_tabbedSelectorToggle->moveToRight(right, buttonsBottom);
|
||||
_botKeyboardHide->moveToRight(right, buttonsBottom); right += _botKeyboardHide->width();
|
||||
_botKeyboardShow->moveToRight(right, buttonsBottom);
|
||||
|
@ -4445,6 +4344,7 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
|||
void HistoryWidget::updateControlsGeometry() {
|
||||
_topBar->resizeToWidth(width());
|
||||
_topBar->moveToLeft(0, 0);
|
||||
_voiceRecordBar->resizeToWidth(width());
|
||||
|
||||
moveFieldControls();
|
||||
|
||||
|
@ -5571,7 +5471,7 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
|
|||
}
|
||||
}
|
||||
|
||||
if (_recording) {
|
||||
if (isRecording()) {
|
||||
// Just fix some strange inconsistency.
|
||||
_send->clearState();
|
||||
}
|
||||
|
@ -6070,7 +5970,7 @@ void HistoryWidget::updateTopBarSelection() {
|
|||
if (!Ui::isLayerShown() && !Core::App().passcodeLocked()) {
|
||||
if (_nonEmptySelection
|
||||
|| (_list && _list->wasSelectedText())
|
||||
|| _recording
|
||||
|| isRecording()
|
||||
|| isBotStart()
|
||||
|| isBlocked()
|
||||
|| !_canSendMessages) {
|
||||
|
@ -6097,7 +5997,7 @@ void HistoryWidget::updateReplyEditText(not_null<HistoryItem*> item) {
|
|||
st::messageTextStyle,
|
||||
item->inReplyText(),
|
||||
Ui::DialogTextOptions());
|
||||
if (!_field->isHidden() || _recording) {
|
||||
if (!_field->isHidden() || isRecording()) {
|
||||
_fieldBarCancel->show();
|
||||
updateMouseTracking();
|
||||
}
|
||||
|
@ -6400,29 +6300,6 @@ void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::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 = 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 HistoryWidget::drawPinnedBar(Painter &p) {
|
||||
// //if (_pinnedBar->msg) {
|
||||
|
@ -6478,11 +6355,8 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
|||
Painter p(this);
|
||||
const auto clip = e->rect();
|
||||
if (_list) {
|
||||
if (!_field->isHidden() || _recording) {
|
||||
if (!_field->isHidden() || isRecording()) {
|
||||
drawField(p, clip);
|
||||
if (!_send->isHidden() && _recording) {
|
||||
drawRecording(p, _send->recordActiveRatio());
|
||||
}
|
||||
} else if (const auto error = writeRestriction()) {
|
||||
drawRestrictedWrite(p, *error);
|
||||
}
|
||||
|
|
|
@ -94,6 +94,9 @@ class TopBarWidget;
|
|||
class ContactStatus;
|
||||
class Element;
|
||||
class PinnedTracker;
|
||||
namespace Controls {
|
||||
class VoiceRecordBar;
|
||||
} // namespace Controls
|
||||
} // namespace HistoryView
|
||||
|
||||
class DragArea;
|
||||
|
@ -108,6 +111,7 @@ class HistoryWidget final : public Window::AbstractSectionWidget {
|
|||
|
||||
public:
|
||||
using FieldHistoryAction = Ui::InputField::HistoryAction;
|
||||
using VoiceRecordBar = HistoryView::Controls::VoiceRecordBar;
|
||||
|
||||
HistoryWidget(
|
||||
QWidget *parent,
|
||||
|
@ -201,9 +205,6 @@ public:
|
|||
void updatePreview();
|
||||
void previewCancel();
|
||||
|
||||
bool recordingAnimationCallback(crl::time now);
|
||||
void stopRecording(bool send);
|
||||
|
||||
void escape();
|
||||
|
||||
void sendBotCommand(
|
||||
|
@ -345,6 +346,7 @@ private:
|
|||
friend inline constexpr bool is_flag_type(TextUpdateEvent) { return true; };
|
||||
|
||||
void initTabbedSelector();
|
||||
void initVoiceRecordBar();
|
||||
void refreshTabbedPanel();
|
||||
void createTabbedPanel();
|
||||
void setTabbedPanel(std::unique_ptr<TabbedPanel> panel);
|
||||
|
@ -395,11 +397,6 @@ private:
|
|||
|
||||
void animationCallback();
|
||||
void updateOverStates(QPoint pos);
|
||||
void recordDone(QByteArray result, VoiceWaveform waveform, int samples);
|
||||
void recordUpdate(ushort level, int samples);
|
||||
void recordStartCallback();
|
||||
void recordStopCallback(bool active);
|
||||
void recordUpdateCallback(QPoint globalPos);
|
||||
void chooseAttach();
|
||||
void historyDownAnimationFinish();
|
||||
void unreadMentionsAnimationFinish();
|
||||
|
@ -495,7 +492,6 @@ private:
|
|||
const QRect &rect,
|
||||
int left,
|
||||
int top) const;
|
||||
void drawRecording(Painter &p, float64 recordActive);
|
||||
void drawRestrictedWrite(Painter &p, const QString &error);
|
||||
bool paintShowAnimationFrame();
|
||||
|
||||
|
@ -566,6 +562,8 @@ private:
|
|||
void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result);
|
||||
void inlineBotResolveFail(const RPCError &error, const QString &username);
|
||||
|
||||
bool isRecording() const;
|
||||
|
||||
bool isBotStart() const;
|
||||
bool isBlocked() const;
|
||||
bool isJoinChannel() const;
|
||||
|
@ -673,7 +671,7 @@ private:
|
|||
|
||||
std::unique_ptr<HistoryView::ContactStatus> _contactStatus;
|
||||
|
||||
object_ptr<Ui::SendButton> _send;
|
||||
const std::shared_ptr<Ui::SendButton> _send;
|
||||
object_ptr<Ui::FlatButton> _unblock;
|
||||
object_ptr<Ui::FlatButton> _botStart;
|
||||
object_ptr<Ui::FlatButton> _joinChannel;
|
||||
|
@ -685,20 +683,11 @@ private:
|
|||
object_ptr<Ui::IconButton> _botCommandStart;
|
||||
object_ptr<Ui::SilentToggle> _silent = { nullptr };
|
||||
object_ptr<Ui::IconButton> _scheduled = { nullptr };
|
||||
const std::unique_ptr<VoiceRecordBar> _voiceRecordBar;
|
||||
bool _cmdStartShown = false;
|
||||
object_ptr<Ui::InputField> _field;
|
||||
bool _recording = false;
|
||||
bool _inField = false;
|
||||
bool _inReplyEditForward = false;
|
||||
bool _inClickable = false;
|
||||
int _recordingSamples = 0;
|
||||
int _recordCancelWidth;
|
||||
rpl::lifetime _recordingLifetime;
|
||||
|
||||
// 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;
|
||||
|
||||
bool kbWasHidden() const;
|
||||
|
||||
|
|
|
@ -26,8 +26,9 @@ using SendActionUpdate = VoiceRecordBar::SendActionUpdate;
|
|||
using VoiceToSend = VoiceRecordBar::VoiceToSend;
|
||||
|
||||
constexpr auto kRecordingUpdateDelta = crl::time(100);
|
||||
constexpr auto kAudioVoiceMaxLength = 100 * 60; // 100 minutes
|
||||
constexpr auto kMaxSamples =
|
||||
::Media::Player::kDefaultFrequency * AudioVoiceMsgMaxLength;
|
||||
::Media::Player::kDefaultFrequency * kAudioVoiceMaxLength;
|
||||
|
||||
[[nodiscard]] auto Duration(int samples) {
|
||||
return samples / ::Media::Player::kDefaultFrequency;
|
||||
|
|
Loading…
Reference in a new issue