From c71ba2b8e74d98f45efc5e932d319823a8c21261 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 6 Apr 2022 19:19:50 +0400 Subject: [PATCH] Choose newly uploaded ringtone in the box. --- Telegram/SourceFiles/api/api_ringtones.cpp | 14 +++- Telegram/SourceFiles/api/api_ringtones.h | 4 +- Telegram/SourceFiles/boxes/ringtones_box.cpp | 88 +++++++++++++------- Telegram/SourceFiles/boxes/ringtones_box.h | 20 +++++ 4 files changed, 90 insertions(+), 36 deletions(-) diff --git a/Telegram/SourceFiles/api/api_ringtones.cpp b/Telegram/SourceFiles/api/api_ringtones.cpp index 54c7678319..c44cb0bdb9 100644 --- a/Telegram/SourceFiles/api/api_ringtones.cpp +++ b/Telegram/SourceFiles/api/api_ringtones.cpp @@ -112,7 +112,9 @@ void Ringtones::ready(const FullMsgId &msgId, const MTPInputFile &file) { MTP_string(uploadedData.filename), MTP_string(uploadedData.filemime) )).done([=](const MTPDocument &result) { - _session->data().processDocument(result); + const auto document = _session->data().processDocument(result); + _list.documents.insert(_list.documents.begin(), document->id); + _uploadDones.fire_copy(document->id); }).fail([=](const MTP::Error &error) { _uploadFails.fire_copy(error.type()); }).send(); @@ -128,11 +130,11 @@ void Ringtones::requestList() { _list.requestId = 0; result.match([&](const MTPDaccount_savedRingtones &data) { _list.hash = data.vhash().v; - _list.documents.reserve(_list.documents.size() - + data.vringtones().v.size()); + _list.documents.clear(); + _list.documents.reserve(data.vringtones().v.size()); for (const auto &d : data.vringtones().v) { const auto document = _session->data().processDocument(d); - _list.documents.emplace(document->id); + _list.documents.emplace_back(document->id); } requestList(); _list.updates.fire({}); @@ -155,6 +157,10 @@ rpl::producer Ringtones::uploadFails() const { return _uploadFails.events(); } +rpl::producer Ringtones::uploadDones() const { + return _uploadDones.events(); +} + void Ringtones::applyUpdate() { _list.hash = 0; _list.documents.clear(); diff --git a/Telegram/SourceFiles/api/api_ringtones.h b/Telegram/SourceFiles/api/api_ringtones.h index 432206383c..8b903ca1df 100644 --- a/Telegram/SourceFiles/api/api_ringtones.h +++ b/Telegram/SourceFiles/api/api_ringtones.h @@ -22,7 +22,7 @@ class Ringtones final { public: explicit Ringtones(not_null api); - using Ids = std::unordered_set; + using Ids = std::vector; void requestList(); void applyUpdate(); @@ -36,6 +36,7 @@ public: [[nodiscard]] const Ids &list() const; [[nodiscard]] rpl::producer<> listUpdates() const; [[nodiscard]] rpl::producer uploadFails() const; + [[nodiscard]] rpl::producer uploadDones() const; private: struct UploadedData { @@ -49,6 +50,7 @@ private: base::flat_map _uploads; rpl::event_stream _uploadFails; + rpl::event_stream _uploadDones; struct { uint64 hash = 0; diff --git a/Telegram/SourceFiles/boxes/ringtones_box.cpp b/Telegram/SourceFiles/boxes/ringtones_box.cpp index e7d65fb0db..3d82e4830b 100644 --- a/Telegram/SourceFiles/boxes/ringtones_box.cpp +++ b/Telegram/SourceFiles/boxes/ringtones_box.cpp @@ -43,9 +43,34 @@ constexpr auto kNoSoundValue = -2; } // namespace +QString ExtractRingtoneName(not_null document) { + if (document->isNull()) { + return QString(); + } + const auto name = document->filename(); + if (!name.isEmpty()) { + const auto extension = Data::FileExtension(name); + if (extension.isEmpty()) { + return name; + } else if (name.size() > extension.size() + 1) { + return name.mid(0, name.size() - extension.size() - 1); + } + } + const auto date = langDateTime( + base::unixtime::parse(document->date)); + const auto base = document->isVoiceMessage() + ? (tr::lng_in_dlg_audio(tr::now) + ' ') + : document->isAudioFile() + ? (tr::lng_in_dlg_audio_file(tr::now) + ' ') + : QString(); + return base + date; +} + void RingtonesBox( not_null box, - not_null peer) { + not_null session, + Data::NotifySound selected, + Fn save) { box->setTitle(tr::lng_ringtones_box_title()); const auto container = box->verticalLayout(); @@ -56,13 +81,15 @@ void RingtonesBox( struct State { std::shared_ptr group; std::vector documentIds; + Data::NotifySound chosen; base::unique_qptr menu; QPointer defaultButton; QPointer chosenButton; std::vector> buttons; }; const auto state = container->lifetime().make_state(State{ - std::make_shared(), + .group = std::make_shared(), + .chosen = selected, }); const auto addToGroup = [=]( @@ -73,15 +100,12 @@ void RingtonesBox( if (chosen) { state->group->setValue(value); } - const auto extension = Data::FileExtension(text); const auto button = verticalLayout->add( object_ptr( verticalLayout, state->group, value, - extension.isEmpty() - ? text - : text.mid(0, text.length() - extension.length() - 1), + text, st::defaultCheckbox), padding); if (chosen) { @@ -105,7 +129,7 @@ void RingtonesBox( st::popupMenuWithIcons); auto callback = [=] { const auto id = state->documentIds[value]; - peer->session().api().ringtones().remove(id); + session->api().ringtones().remove(id); }; state->menu->addAction( tr::lng_box_delete(tr::now), @@ -116,7 +140,7 @@ void RingtonesBox( }); }; - peer->session().api().ringtones().uploadFails( + session->api().ringtones().uploadFails( ) | rpl::start_with_next([=](const QString &error) { if ((error == u"RINGTONE_DURATION_TOO_LONG"_q) || (error == u"RINGTONE_SIZE_TOO_BIG"_q)) { @@ -132,7 +156,7 @@ void RingtonesBox( container, tr::lng_ringtones_box_cloud_subtitle()); - const auto noSound = peer->owner().notifySettings().sound(peer).none; + const auto noSound = selected.none; addToGroup( container, kDefaultValue, @@ -154,23 +178,10 @@ void RingtonesBox( delete custom->widgetAt(0); } - const auto checkedId = peer->owner().notifySettings().sound(peer); - for (const auto &id : peer->session().api().ringtones().list()) { - const auto chosen = (checkedId.id && checkedId.id == id); - const auto document = peer->session().data().document(id); - const auto text = [&] { - if (!document->filename().isEmpty()) { - return document->filename(); - } - const auto date = langDateTime( - base::unixtime::parse(document->date)); - const auto base = document->isVoiceMessage() - ? (tr::lng_in_dlg_audio(tr::now) + ' ') - : document->isAudioFile() - ? (tr::lng_in_dlg_audio_file(tr::now) + ' ') - : QString(); - return base + date; - }(); + for (const auto &id : session->api().ringtones().list()) { + const auto chosen = (state->chosen.id && state->chosen.id == id); + const auto document = session->data().document(id); + const auto text = ExtractRingtoneName(document); addToGroup(custom, value++, text, chosen); state->documentIds.push_back(id); } @@ -182,10 +193,16 @@ void RingtonesBox( } }; - peer->session().api().ringtones().listUpdates( + session->api().ringtones().listUpdates( ) | rpl::start_with_next(rebuild, container->lifetime()); - peer->session().api().ringtones().requestList(); + session->api().ringtones().uploadDones( + ) | rpl::start_with_next([=](DocumentId id) { + state->chosen = Data::NotifySound{ .id = id }; + rebuild(); + }, container->lifetime()); + + session->api().ringtones().requestList(); rebuild(); const auto upload = box->addRow( @@ -221,7 +238,7 @@ void RingtonesBox( name = "audio"; } - peer->session().api().ringtones().upload(name, mime, content); + session->api().ringtones().upload(name, mime, content); }; FileDialog::GetOpenPath( box.get(), @@ -243,9 +260,18 @@ void RingtonesBox( ? Data::NotifySound() : (value == kNoSoundValue) ? Data::NotifySound{ .none = true } - : Data::NotifySound{ .id = state->documentIds[value] }; - peer->owner().notifySettings().update(peer, {}, {}, sound); + : Data::NotifySound{ .id = state->documentIds[value] }; + save(sound); box->closeBox(); }); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); } + +void PeerRingtonesBox( + not_null box, + not_null peer) { + const auto now = peer->owner().notifySettings().sound(peer); + RingtonesBox(box, &peer->session(), now, [=](Data::NotifySound sound) { + peer->owner().notifySettings().update(peer, {}, {}, sound); + }); +} diff --git a/Telegram/SourceFiles/boxes/ringtones_box.h b/Telegram/SourceFiles/boxes/ringtones_box.h index bea10f50b8..d4e62baaa9 100644 --- a/Telegram/SourceFiles/boxes/ringtones_box.h +++ b/Telegram/SourceFiles/boxes/ringtones_box.h @@ -11,6 +11,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class PeerData; +namespace Data { +struct NotifySound; +} // namespace Data + +namespace Main { +class Session; +} // namespace Main + +namespace Ui { +class GenericBox; +} // namespace Ui + +[[nodiscard]] QString ExtractRingtoneName(not_null document); + void RingtonesBox( + not_null box, + not_null session, + Data::NotifySound selected, + Fn save); + +void PeerRingtonesBox( not_null box, not_null peer);