Added ability to send voice message with ttl.

This commit is contained in:
23rd 2024-01-03 16:28:36 +03:00
parent ca86dce760
commit 69f8cb5951
7 changed files with 84 additions and 21 deletions

View file

@ -25,6 +25,7 @@ struct SendOptions {
bool silent = false; bool silent = false;
bool handleSupportSwitch = false; bool handleSupportSwitch = false;
bool hideViaBot = false; bool hideViaBot = false;
crl::time ttlSeconds = 0;
}; };
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions(); [[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();

View file

@ -79,16 +79,17 @@ MTPInputMedia PrepareUploadedPhoto(
not_null<HistoryItem*> item, not_null<HistoryItem*> item,
RemoteFileInfo info) { RemoteFileInfo info) {
using Flag = MTPDinputMediaUploadedPhoto::Flag; using Flag = MTPDinputMediaUploadedPhoto::Flag;
const auto spoiler = item->media() const auto spoiler = item->media() && item->media()->hasSpoiler();
&& item->media()->hasSpoiler(); const auto ttlSeconds = item->media() && item->media()->ttlSeconds();
const auto flags = (spoiler ? Flag::f_spoiler : Flag()) 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( return MTP_inputMediaUploadedPhoto(
MTP_flags(flags), MTP_flags(flags),
info.file, info.file,
MTP_vector<MTPInputDocument>( MTP_vector<MTPInputDocument>(
ranges::to<QVector<MTPInputDocument>>(info.attachedStickers)), ranges::to<QVector<MTPInputDocument>>(info.attachedStickers)),
MTP_int(0)); MTP_int(ttlSeconds));
} }
MTPInputMedia PrepareUploadedDocument( MTPInputMedia PrepareUploadedDocument(
@ -98,12 +99,13 @@ MTPInputMedia PrepareUploadedDocument(
return MTP_inputMediaEmpty(); return MTP_inputMediaEmpty();
} }
using Flag = MTPDinputMediaUploadedDocument::Flag; using Flag = MTPDinputMediaUploadedDocument::Flag;
const auto spoiler = item->media() const auto spoiler = item->media() && item->media()->hasSpoiler();
&& item->media()->hasSpoiler(); const auto ttlSeconds = item->media() && item->media()->ttlSeconds();
const auto flags = (spoiler ? Flag::f_spoiler : Flag()) const auto flags = (spoiler ? Flag::f_spoiler : Flag())
| (info.thumb ? Flag::f_thumb : Flag()) | (info.thumb ? Flag::f_thumb : Flag())
| (item->groupId() ? Flag::f_nosound_video : 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(); const auto document = item->media()->document();
return MTP_inputMediaUploadedDocument( return MTP_inputMediaUploadedDocument(
MTP_flags(flags), MTP_flags(flags),
@ -113,7 +115,7 @@ MTPInputMedia PrepareUploadedDocument(
ComposeSendingDocumentAttributes(document), ComposeSendingDocumentAttributes(document),
MTP_vector<MTPInputDocument>( MTP_vector<MTPInputDocument>(
ranges::to<QVector<MTPInputDocument>>(info.attachedStickers)), ranges::to<QVector<MTPInputDocument>>(info.attachedStickers)),
MTP_int(0)); MTP_int(ttlSeconds));
} }
bool HasAttachedStickers(MTPInputMedia media) { bool HasAttachedStickers(MTPInputMedia media) {

View file

@ -443,11 +443,30 @@ void SendConfirmedFile(
MTPDocument(), // alt_document MTPDocument(), // alt_document
MTPint()); MTPint());
} else if (file->type == SendMediaType::Audio) { } 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( 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, file->document,
MTPDocument(), // alt_document MTPDocument(), // alt_document
MTPint()); MTP_int(ttlSeconds));
} else { } else {
Unexpected("Type in sendFilesConfirmed."); Unexpected("Type in sendFilesConfirmed.");
} }

View file

@ -948,6 +948,16 @@ void HistoryWidget::initVoiceRecordBar() {
} }
return false; 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 = [=] { const auto applyLocalDraft = [=] {
if (_history && _history->localDraft({})) { if (_history && _history->localDraft({})) {

View file

@ -358,6 +358,7 @@ TTLButton::TTLButton(
void TTLButton::clearState() { void TTLButton::clearState() {
Ui::AbstractButton::setDisabled(true); Ui::AbstractButton::setDisabled(true);
update(); update();
Ui::RpWidget::hide();
} }
QImage TTLButton::prepareRippleMask() const { QImage TTLButton::prepareRippleMask() const {
@ -1360,7 +1361,9 @@ void VoiceRecordBar::init() {
_lock->locks( _lock->locks(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
_ttlButton->show(); if (_hasTTLFilter && _hasTTLFilter()) {
_ttlButton->show();
}
updateTTLGeometry(TTLAnimationType::RightTopStatic, 0); updateTTLGeometry(TTLAnimationType::RightTopStatic, 0);
_level->setType(VoiceRecordButton::Type::Send); _level->setType(VoiceRecordButton::Type::Send);
@ -1472,10 +1475,14 @@ void VoiceRecordBar::visibilityAnimate(bool show, Fn<void()> &&callback) {
_showAnimation.start(std::move(animationCallback), from, to, duration); _showAnimation.start(std::move(animationCallback), from, to, duration);
} }
void VoiceRecordBar::setStartRecordingFilter(Fn<bool()> &&callback) { void VoiceRecordBar::setStartRecordingFilter(FilterCallback &&callback) {
_startRecordingFilter = std::move(callback); _startRecordingFilter = std::move(callback);
} }
void VoiceRecordBar::setTTLFilter(FilterCallback &&callback) {
_hasTTLFilter = std::move(callback);
}
void VoiceRecordBar::initLockGeometry() { void VoiceRecordBar::initLockGeometry() {
rpl::combine( rpl::combine(
_lock->heightValue(), _lock->heightValue(),
@ -1610,7 +1617,7 @@ void VoiceRecordBar::hideFast() {
hide(); hide();
_lock->hide(); _lock->hide();
_level->hide(); _level->hide();
_ttlButton->clearState(); [[maybe_unused]] const auto s = takeTTLState();
} }
void VoiceRecordBar::stopRecording(StopType type) { void VoiceRecordBar::stopRecording(StopType type) {
@ -1632,7 +1639,17 @@ void VoiceRecordBar::stopRecording(StopType type) {
window()->activateWindow(); window()->activateWindow();
const auto duration = Duration(data.samples); const auto duration = Duration(data.samples);
if (type == StopType::Send) { if (type == StopType::Send) {
_sendVoiceRequests.fire({ data.bytes, data.waveform, duration }); const auto options = Api::SendOptions{
.ttlSeconds = takeTTLState()
? std::numeric_limits<int>::max()
: 0
};
_sendVoiceRequests.fire({
data.bytes,
data.waveform,
duration,
options,
});
} else if (type == StopType::Listen) { } else if (type == StopType::Listen) {
_listen = std::make_unique<ListenWrap>( _listen = std::make_unique<ListenWrap>(
this, this,
@ -1702,11 +1719,15 @@ void VoiceRecordBar::drawMessage(QPainter &p, float64 recordActive) {
void VoiceRecordBar::requestToSendWithOptions(Api::SendOptions options) { void VoiceRecordBar::requestToSendWithOptions(Api::SendOptions options) {
if (isListenState()) { if (isListenState()) {
const auto data = _listen->data(); const auto data = _listen->data();
if (takeTTLState()) {
options.ttlSeconds = std::numeric_limits<int>::max();
}
_sendVoiceRequests.fire({ _sendVoiceRequests.fire({
data->bytes, data->bytes,
data->waveform, data->waveform,
Duration(data->samples), Duration(data->samples),
options }); options,
});
} }
} }
@ -1825,6 +1846,12 @@ void VoiceRecordBar::computeAndSetLockProgress(QPoint globalPos) {
_lock->requestPaintProgress(Progress(localPos.y(), higher - lower)); _lock->requestPaintProgress(Progress(localPos.y(), higher - lower));
} }
bool VoiceRecordBar::takeTTLState() const {
const auto hasTtl = !_ttlButton->isDisabled();
_ttlButton->clearState();
return hasTtl;
}
void VoiceRecordBar::orderControls() { void VoiceRecordBar::orderControls() {
stackUnder(_send.get()); stackUnder(_send.get());
_lock->raise(); _lock->raise();

View file

@ -54,6 +54,7 @@ class VoiceRecordBar final : public Ui::RpWidget {
public: public:
using SendActionUpdate = Controls::SendActionUpdate; using SendActionUpdate = Controls::SendActionUpdate;
using VoiceToSend = Controls::VoiceToSend; using VoiceToSend = Controls::VoiceToSend;
using FilterCallback = Fn<bool()>;
VoiceRecordBar( VoiceRecordBar(
not_null<Ui::RpWidget*> parent, not_null<Ui::RpWidget*> parent,
@ -88,7 +89,8 @@ public:
void requestToSendWithOptions(Api::SendOptions options); void requestToSendWithOptions(Api::SendOptions options);
void setStartRecordingFilter(Fn<bool()> &&callback); void setStartRecordingFilter(FilterCallback &&callback);
void setTTLFilter(FilterCallback &&callback);
[[nodiscard]] bool isRecording() const; [[nodiscard]] bool isRecording() const;
[[nodiscard]] bool isRecordingLocked() const; [[nodiscard]] bool isRecordingLocked() const;
@ -146,6 +148,8 @@ private:
void computeAndSetLockProgress(QPoint globalPos); void computeAndSetLockProgress(QPoint globalPos);
[[nodiscard]] bool takeTTLState() const;
const style::RecordBar &_st; const style::RecordBar &_st;
const not_null<Ui::RpWidget*> _outerContainer; const not_null<Ui::RpWidget*> _outerContainer;
const std::shared_ptr<ChatHelpers::Show> _show; const std::shared_ptr<ChatHelpers::Show> _show;
@ -170,7 +174,8 @@ private:
Ui::Text::String _message; Ui::Text::String _message;
Fn<bool()> _startRecordingFilter; FilterCallback _startRecordingFilter;
FilterCallback _hasTTLFilter;
bool _warningShown = false; bool _warningShown = false;

View file

@ -718,10 +718,6 @@ void Document::draw(
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
p.setBrush(stm->msgFileBg); p.setBrush(stm->msgFileBg);
p.drawEllipse(inner); p.drawEllipse(inner);
if (_parent->data()->media()->ttlSeconds()) {
DrawCornerBadgeTTL(p, stm->msgFileBg, inner);
}
} }
} }
@ -898,6 +894,9 @@ void Document::draw(
.highlight = highlightRequest ? &*highlightRequest : nullptr, .highlight = highlightRequest ? &*highlightRequest : nullptr,
}); });
} }
if (_parent->data()->media()->ttlSeconds()) {
DrawCornerBadgeTTL(p, stm->msgFileBg, inner);
}
} }
Ui::BubbleRounding Document::thumbRounding( Ui::BubbleRounding Document::thumbRounding(