From 69f8cb595123cdd35b785ef353b0edc0e118b091 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 3 Jan 2024 16:28:36 +0300 Subject: [PATCH] Added ability to send voice message with ttl. --- Telegram/SourceFiles/api/api_common.h | 1 + Telegram/SourceFiles/api/api_media.cpp | 18 +++++---- Telegram/SourceFiles/api/api_sending.cpp | 23 +++++++++++- .../SourceFiles/history/history_widget.cpp | 10 +++++ .../history_view_voice_record_bar.cpp | 37 ++++++++++++++++--- .../controls/history_view_voice_record_bar.h | 9 ++++- .../view/media/history_view_document.cpp | 7 ++-- 7 files changed, 84 insertions(+), 21 deletions(-) diff --git a/Telegram/SourceFiles/api/api_common.h b/Telegram/SourceFiles/api/api_common.h index c828411425..155666a5d4 100644 --- a/Telegram/SourceFiles/api/api_common.h +++ b/Telegram/SourceFiles/api/api_common.h @@ -25,6 +25,7 @@ struct SendOptions { bool silent = false; bool handleSupportSwitch = false; bool hideViaBot = false; + crl::time ttlSeconds = 0; }; [[nodiscard]] SendOptions DefaultSendWhenOnlineOptions(); diff --git a/Telegram/SourceFiles/api/api_media.cpp b/Telegram/SourceFiles/api/api_media.cpp index ec8c1e4b26..a9fdec5406 100644 --- a/Telegram/SourceFiles/api/api_media.cpp +++ b/Telegram/SourceFiles/api/api_media.cpp @@ -79,16 +79,17 @@ MTPInputMedia PrepareUploadedPhoto( not_null item, RemoteFileInfo info) { using Flag = MTPDinputMediaUploadedPhoto::Flag; - const auto spoiler = item->media() - && item->media()->hasSpoiler(); + const auto spoiler = item->media() && item->media()->hasSpoiler(); + const auto ttlSeconds = item->media() && item->media()->ttlSeconds(); const auto flags = (spoiler ? Flag::f_spoiler : Flag()) - | (info.attachedStickers.empty() ? Flag() : Flag::f_stickers); + | (info.attachedStickers.empty() ? Flag() : Flag::f_stickers) + | (ttlSeconds ? Flag::f_ttl_seconds : Flag()); return MTP_inputMediaUploadedPhoto( MTP_flags(flags), info.file, MTP_vector( ranges::to>(info.attachedStickers)), - MTP_int(0)); + MTP_int(ttlSeconds)); } MTPInputMedia PrepareUploadedDocument( @@ -98,12 +99,13 @@ MTPInputMedia PrepareUploadedDocument( return MTP_inputMediaEmpty(); } using Flag = MTPDinputMediaUploadedDocument::Flag; - const auto spoiler = item->media() - && item->media()->hasSpoiler(); + const auto spoiler = item->media() && item->media()->hasSpoiler(); + const auto ttlSeconds = item->media() && item->media()->ttlSeconds(); const auto flags = (spoiler ? Flag::f_spoiler : Flag()) | (info.thumb ? Flag::f_thumb : Flag()) | (item->groupId() ? Flag::f_nosound_video : Flag()) - | (info.attachedStickers.empty() ? Flag::f_stickers : Flag()); + | (info.attachedStickers.empty() ? Flag::f_stickers : Flag()) + | (ttlSeconds ? Flag::f_ttl_seconds : Flag()); const auto document = item->media()->document(); return MTP_inputMediaUploadedDocument( MTP_flags(flags), @@ -113,7 +115,7 @@ MTPInputMedia PrepareUploadedDocument( ComposeSendingDocumentAttributes(document), MTP_vector( ranges::to>(info.attachedStickers)), - MTP_int(0)); + MTP_int(ttlSeconds)); } bool HasAttachedStickers(MTPInputMedia media) { diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index 850f21656b..d971a03f44 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -443,11 +443,30 @@ void SendConfirmedFile( MTPDocument(), // alt_document MTPint()); } else if (file->type == SendMediaType::Audio) { + const auto ttlSeconds = file->to.options.ttlSeconds; + const auto isVoice = [&] { + return file->document.match([](const MTPDdocumentEmpty &d) { + return false; + }, [](const MTPDdocument &d) { + return ranges::any_of(d.vattributes().v, [&]( + const MTPDocumentAttribute &attribute) { + using Att = MTPDdocumentAttributeAudio; + return attribute.match([](const Att &data) -> bool { + return data.vflags().v & Att::Flag::f_voice; + }, [](const auto &) { + return false; + }); + }); + }); + }(); + using Flag = MTPDmessageMediaDocument::Flag; return MTP_messageMediaDocument( - MTP_flags(MTPDmessageMediaDocument::Flag::f_document), + MTP_flags(Flag::f_document + | (isVoice ? Flag::f_voice : Flag()) + | (ttlSeconds ? Flag::f_ttl_seconds : Flag())), file->document, MTPDocument(), // alt_document - MTPint()); + MTP_int(ttlSeconds)); } else { Unexpected("Type in sendFilesConfirmed."); } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 1c4c575722..1fc698dcf6 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -948,6 +948,16 @@ void HistoryWidget::initVoiceRecordBar() { } return false; }); + _voiceRecordBar->setTTLFilter([=] { + if (const auto peer = _history ? _history->peer : nullptr) { + if (const auto user = peer->asUser()) { + if (!user->isSelf() && !user->isBot()) { + return true; + } + } + } + return false; + }); const auto applyLocalDraft = [=] { if (_history && _history->localDraft({})) { diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp index 778cd1763d..bc2cc83a5a 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp @@ -358,6 +358,7 @@ TTLButton::TTLButton( void TTLButton::clearState() { Ui::AbstractButton::setDisabled(true); update(); + Ui::RpWidget::hide(); } QImage TTLButton::prepareRippleMask() const { @@ -1360,7 +1361,9 @@ void VoiceRecordBar::init() { _lock->locks( ) | rpl::start_with_next([=] { - _ttlButton->show(); + if (_hasTTLFilter && _hasTTLFilter()) { + _ttlButton->show(); + } updateTTLGeometry(TTLAnimationType::RightTopStatic, 0); _level->setType(VoiceRecordButton::Type::Send); @@ -1472,10 +1475,14 @@ void VoiceRecordBar::visibilityAnimate(bool show, Fn &&callback) { _showAnimation.start(std::move(animationCallback), from, to, duration); } -void VoiceRecordBar::setStartRecordingFilter(Fn &&callback) { +void VoiceRecordBar::setStartRecordingFilter(FilterCallback &&callback) { _startRecordingFilter = std::move(callback); } +void VoiceRecordBar::setTTLFilter(FilterCallback &&callback) { + _hasTTLFilter = std::move(callback); +} + void VoiceRecordBar::initLockGeometry() { rpl::combine( _lock->heightValue(), @@ -1610,7 +1617,7 @@ void VoiceRecordBar::hideFast() { hide(); _lock->hide(); _level->hide(); - _ttlButton->clearState(); + [[maybe_unused]] const auto s = takeTTLState(); } void VoiceRecordBar::stopRecording(StopType type) { @@ -1632,7 +1639,17 @@ void VoiceRecordBar::stopRecording(StopType type) { window()->activateWindow(); const auto duration = Duration(data.samples); if (type == StopType::Send) { - _sendVoiceRequests.fire({ data.bytes, data.waveform, duration }); + const auto options = Api::SendOptions{ + .ttlSeconds = takeTTLState() + ? std::numeric_limits::max() + : 0 + }; + _sendVoiceRequests.fire({ + data.bytes, + data.waveform, + duration, + options, + }); } else if (type == StopType::Listen) { _listen = std::make_unique( this, @@ -1702,11 +1719,15 @@ void VoiceRecordBar::drawMessage(QPainter &p, float64 recordActive) { void VoiceRecordBar::requestToSendWithOptions(Api::SendOptions options) { if (isListenState()) { const auto data = _listen->data(); + if (takeTTLState()) { + options.ttlSeconds = std::numeric_limits::max(); + } _sendVoiceRequests.fire({ data->bytes, data->waveform, Duration(data->samples), - options }); + options, + }); } } @@ -1825,6 +1846,12 @@ void VoiceRecordBar::computeAndSetLockProgress(QPoint globalPos) { _lock->requestPaintProgress(Progress(localPos.y(), higher - lower)); } +bool VoiceRecordBar::takeTTLState() const { + const auto hasTtl = !_ttlButton->isDisabled(); + _ttlButton->clearState(); + return hasTtl; +} + void VoiceRecordBar::orderControls() { stackUnder(_send.get()); _lock->raise(); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h index 8ec19191c6..31c0eb30e3 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h @@ -54,6 +54,7 @@ class VoiceRecordBar final : public Ui::RpWidget { public: using SendActionUpdate = Controls::SendActionUpdate; using VoiceToSend = Controls::VoiceToSend; + using FilterCallback = Fn; VoiceRecordBar( not_null parent, @@ -88,7 +89,8 @@ public: void requestToSendWithOptions(Api::SendOptions options); - void setStartRecordingFilter(Fn &&callback); + void setStartRecordingFilter(FilterCallback &&callback); + void setTTLFilter(FilterCallback &&callback); [[nodiscard]] bool isRecording() const; [[nodiscard]] bool isRecordingLocked() const; @@ -146,6 +148,8 @@ private: void computeAndSetLockProgress(QPoint globalPos); + [[nodiscard]] bool takeTTLState() const; + const style::RecordBar &_st; const not_null _outerContainer; const std::shared_ptr _show; @@ -170,7 +174,8 @@ private: Ui::Text::String _message; - Fn _startRecordingFilter; + FilterCallback _startRecordingFilter; + FilterCallback _hasTTLFilter; bool _warningShown = false; diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index e3e2808cdc..aeb2372082 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -718,10 +718,6 @@ void Document::draw( PainterHighQualityEnabler hq(p); p.setBrush(stm->msgFileBg); p.drawEllipse(inner); - - if (_parent->data()->media()->ttlSeconds()) { - DrawCornerBadgeTTL(p, stm->msgFileBg, inner); - } } } @@ -898,6 +894,9 @@ void Document::draw( .highlight = highlightRequest ? &*highlightRequest : nullptr, }); } + if (_parent->data()->media()->ttlSeconds()) { + DrawCornerBadgeTTL(p, stm->msgFileBg, inner); + } } Ui::BubbleRounding Document::thumbRounding(