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 handleSupportSwitch = false;
bool hideViaBot = false;
crl::time ttlSeconds = 0;
};
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();

View File

@ -79,16 +79,17 @@ MTPInputMedia PrepareUploadedPhoto(
not_null<HistoryItem*> 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<MTPInputDocument>(
ranges::to<QVector<MTPInputDocument>>(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<MTPInputDocument>(
ranges::to<QVector<MTPInputDocument>>(info.attachedStickers)),
MTP_int(0));
MTP_int(ttlSeconds));
}
bool HasAttachedStickers(MTPInputMedia media) {

View File

@ -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.");
}

View File

@ -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({})) {

View File

@ -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<void()> &&callback) {
_showAnimation.start(std::move(animationCallback), from, to, duration);
}
void VoiceRecordBar::setStartRecordingFilter(Fn<bool()> &&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<int>::max()
: 0
};
_sendVoiceRequests.fire({
data.bytes,
data.waveform,
duration,
options,
});
} else if (type == StopType::Listen) {
_listen = std::make_unique<ListenWrap>(
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<int>::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();

View File

@ -54,6 +54,7 @@ class VoiceRecordBar final : public Ui::RpWidget {
public:
using SendActionUpdate = Controls::SendActionUpdate;
using VoiceToSend = Controls::VoiceToSend;
using FilterCallback = Fn<bool()>;
VoiceRecordBar(
not_null<Ui::RpWidget*> parent,
@ -88,7 +89,8 @@ public:
void requestToSendWithOptions(Api::SendOptions options);
void setStartRecordingFilter(Fn<bool()> &&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<Ui::RpWidget*> _outerContainer;
const std::shared_ptr<ChatHelpers::Show> _show;
@ -170,7 +174,8 @@ private:
Ui::Text::String _message;
Fn<bool()> _startRecordingFilter;
FilterCallback _startRecordingFilter;
FilterCallback _hasTTLFilter;
bool _warningShown = false;

View File

@ -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(