mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added ability to send voice message with ttl.
This commit is contained in:
parent
ca86dce760
commit
69f8cb5951
7 changed files with 84 additions and 21 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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({})) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Add table
Reference in a new issue