Added initial ability to send recorded voice data from listen state.
This commit is contained in:
parent
647cbc5464
commit
a19e3ca3dc
|
@ -804,6 +804,11 @@ void HistoryWidget::initVoiceRecordBar() {
|
|||
updateUnreadMentionsVisibility();
|
||||
}, lifetime());
|
||||
|
||||
_voiceRecordBar->updateSendButtonTypeRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateSendButtonType();
|
||||
}, lifetime());
|
||||
|
||||
_voiceRecordBar->hideFast();
|
||||
}
|
||||
|
||||
|
@ -3639,6 +3644,7 @@ bool HistoryWidget::isMuteUnmute() const {
|
|||
|
||||
bool HistoryWidget::showRecordButton() const {
|
||||
return Media::Capture::instance()->available()
|
||||
&& !_voiceRecordBar->isListenState()
|
||||
&& !HasSendText(_field)
|
||||
&& !readyToForward()
|
||||
&& !_editMsgId;
|
||||
|
|
|
@ -994,6 +994,7 @@ void ComposeControls::orderControls() {
|
|||
|
||||
bool ComposeControls::showRecordButton() const {
|
||||
return ::Media::Capture::instance()->available()
|
||||
&& !_voiceRecordBar->isListenState()
|
||||
&& !HasSendText(_field)
|
||||
//&& !readyToForward()
|
||||
&& !isEditingMessage();
|
||||
|
@ -1533,6 +1534,11 @@ void ComposeControls::initVoiceRecordBar() {
|
|||
_voiceRecordBar->setEscFilter([=] {
|
||||
return (isEditingMessage() || replyingToMessage());
|
||||
});
|
||||
|
||||
_voiceRecordBar->updateSendButtonTypeRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateSendButtonType();
|
||||
}, _wrap->lifetime());
|
||||
}
|
||||
|
||||
void ComposeControls::updateWrappingVisibility() {
|
||||
|
|
|
@ -78,10 +78,11 @@ class ListenWrap final {
|
|||
public:
|
||||
ListenWrap(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const ::Media::Capture::Result &data);
|
||||
::Media::Capture::Result &&data);
|
||||
|
||||
void requestPaintProgress(float64 progress);
|
||||
rpl::producer<> stopRequests() const;
|
||||
::Media::Capture::Result *data() const;
|
||||
|
||||
rpl::lifetime &lifetime();
|
||||
|
||||
|
@ -90,7 +91,8 @@ private:
|
|||
|
||||
not_null<Ui::RpWidget*> _parent;
|
||||
|
||||
const std::unique_ptr<VoiceData> _voiceData;
|
||||
const std::unique_ptr<::Media::Capture::Result> _data;
|
||||
// const std::unique_ptr<VoiceData> _voiceData;
|
||||
const style::IconButton &_stDelete;
|
||||
base::unique_qptr<Ui::IconButton> _delete;
|
||||
|
||||
|
@ -102,9 +104,10 @@ private:
|
|||
|
||||
ListenWrap::ListenWrap(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const ::Media::Capture::Result &data)
|
||||
::Media::Capture::Result &&data)
|
||||
: _parent(parent)
|
||||
, _voiceData(ProcessCaptureResult(data))
|
||||
, _data(std::make_unique<::Media::Capture::Result>(std::move(data)))
|
||||
// , _voiceData(ProcessCaptureResult(_data))
|
||||
, _stDelete(st::historyRecordDelete)
|
||||
, _delete(base::make_unique_q<Ui::IconButton>(parent, _stDelete)) {
|
||||
init();
|
||||
|
@ -137,6 +140,10 @@ rpl::producer<> ListenWrap::stopRequests() const {
|
|||
return _delete->clicks() | rpl::to_empty;
|
||||
}
|
||||
|
||||
::Media::Capture::Result *ListenWrap::data() const {
|
||||
return _data.get();
|
||||
}
|
||||
|
||||
rpl::lifetime &ListenWrap::lifetime() {
|
||||
return _lifetime;
|
||||
}
|
||||
|
@ -533,11 +540,9 @@ void VoiceRecordBar::init() {
|
|||
_lock->stops(
|
||||
) | rpl::start_with_next([=] {
|
||||
::Media::Capture::instance()->startedChanges(
|
||||
) | rpl::filter([](auto capturing) {
|
||||
return !capturing;
|
||||
) | rpl::filter([=](auto capturing) {
|
||||
return !capturing && _listen;
|
||||
}) | rpl::take(1) | rpl::start_with_next([=] {
|
||||
Assert(_listen != nullptr);
|
||||
|
||||
_lockShowing = false;
|
||||
|
||||
const auto to = 1.;
|
||||
|
@ -605,6 +610,50 @@ void VoiceRecordBar::init() {
|
|||
_startTimer.cancel();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
_listenChanges.events(
|
||||
) | rpl::filter([=] {
|
||||
return _listen != nullptr;
|
||||
}) | rpl::start_with_next([=] {
|
||||
_listen->stopRequests(
|
||||
) | rpl::take(1) | rpl::start_with_next([=] {
|
||||
visibilityAnimate(false, [=] { hide(); });
|
||||
}, _listen->lifetime());
|
||||
|
||||
_listen->lifetime().add([=] { _listenChanges.fire({}); });
|
||||
|
||||
auto filterCallback = [=](not_null<QEvent*> e) {
|
||||
using Result = base::EventFilterResult;
|
||||
if (_send->type() != Ui::SendButton::Type::Send
|
||||
&& _send->type() != Ui::SendButton::Type::Schedule) {
|
||||
return Result::Continue;
|
||||
}
|
||||
switch(e->type()) {
|
||||
case QEvent::MouseButtonRelease: {
|
||||
auto callback = [=] {
|
||||
const auto data = _listen->data();
|
||||
_sendVoiceRequests.fire({
|
||||
data->bytes,
|
||||
data->waveform,
|
||||
Duration(data->samples) });
|
||||
hide();
|
||||
};
|
||||
visibilityAnimate(false, std::move(callback));
|
||||
_send->clearState();
|
||||
return Result::Cancel;
|
||||
}
|
||||
default: return Result::Continue;
|
||||
}
|
||||
};
|
||||
|
||||
auto filter = base::install_event_filter(
|
||||
_send.get(),
|
||||
std::move(filterCallback));
|
||||
|
||||
_listen->lifetime().make_state<base::unique_qptr<QObject>>(
|
||||
std::move(filter));
|
||||
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void VoiceRecordBar::activeAnimate(bool active) {
|
||||
|
@ -783,8 +832,10 @@ void VoiceRecordBar::stopRecording(StopType type) {
|
|||
instance()->stop();
|
||||
return;
|
||||
}
|
||||
instance()->stop(crl::guard(this, [=](const Result &data) {
|
||||
instance()->stop(crl::guard(this, [=](Result &&data) {
|
||||
if (data.bytes.isEmpty()) {
|
||||
// Close everything.
|
||||
stop(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -793,11 +844,8 @@ void VoiceRecordBar::stopRecording(StopType type) {
|
|||
if (type == StopType::Send) {
|
||||
_sendVoiceRequests.fire({ data.bytes, data.waveform, duration });
|
||||
} else if (type == StopType::Listen) {
|
||||
_listen = std::make_unique<ListenWrap>(this, data);
|
||||
_listen->stopRequests(
|
||||
) | rpl::take(1) | rpl::start_with_next([=] {
|
||||
visibilityAnimate(false, [=] { hide(); });
|
||||
}, _listen->lifetime());
|
||||
_listen = std::make_unique<ListenWrap>(this, std::move(data));
|
||||
_listenChanges.fire({});
|
||||
|
||||
_lockShowing = false;
|
||||
}
|
||||
|
@ -879,10 +927,18 @@ rpl::producer<bool> VoiceRecordBar::lockShowStarts() const {
|
|||
return _lockShowing.changes();
|
||||
}
|
||||
|
||||
rpl::producer<> VoiceRecordBar::updateSendButtonTypeRequests() const {
|
||||
return _listenChanges.events();
|
||||
}
|
||||
|
||||
bool VoiceRecordBar::isLockPresent() const {
|
||||
return _lockShowing.current();
|
||||
}
|
||||
|
||||
bool VoiceRecordBar::isListenState() const {
|
||||
return _listen != nullptr;
|
||||
}
|
||||
|
||||
bool VoiceRecordBar::isTypeRecord() const {
|
||||
return (_send->type() == Ui::SendButton::Type::Record);
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
[[nodiscard]] rpl::producer<VoiceToSend> sendVoiceRequests() const;
|
||||
[[nodiscard]] rpl::producer<bool> recordingStateChanges() const;
|
||||
[[nodiscard]] rpl::producer<bool> lockShowStarts() const;
|
||||
[[nodiscard]] rpl::producer<> updateSendButtonTypeRequests() const;
|
||||
|
||||
void setLockBottom(rpl::producer<int> &&bottom);
|
||||
void setSendButtonGeometryValue(rpl::producer<QRect> &&geometry);
|
||||
|
@ -65,6 +66,7 @@ public:
|
|||
|
||||
[[nodiscard]] bool isRecording() const;
|
||||
[[nodiscard]] bool isLockPresent() const;
|
||||
[[nodiscard]] bool isListenState() const;
|
||||
|
||||
private:
|
||||
enum class StopType {
|
||||
|
@ -117,6 +119,7 @@ private:
|
|||
|
||||
rpl::event_stream<SendActionUpdate> _sendActionUpdates;
|
||||
rpl::event_stream<VoiceToSend> _sendVoiceRequests;
|
||||
rpl::event_stream<> _listenChanges;
|
||||
|
||||
int _centerY = 0;
|
||||
QRect _redCircleRect;
|
||||
|
@ -130,6 +133,7 @@ private:
|
|||
|
||||
rpl::variable<bool> _recording = false;
|
||||
rpl::variable<bool> _inField = false;
|
||||
rpl::variable<bool> _lockShowing = false;
|
||||
int _recordingSamples = 0;
|
||||
float64 _redCircleProgress = 0.;
|
||||
|
||||
|
@ -137,8 +141,6 @@ private:
|
|||
|
||||
rpl::lifetime _recordingLifetime;
|
||||
|
||||
rpl::variable<bool> _lockShowing = false;
|
||||
|
||||
Ui::Animations::Simple _showLockAnimation;
|
||||
Ui::Animations::Simple _showListenAnimation;
|
||||
Ui::Animations::Simple _activeAnimation;
|
||||
|
|
Loading…
Reference in New Issue