Support fileref refresh in saved music.

This commit is contained in:
John Preston 2025-08-18 17:23:41 +04:00
parent 4f1c2788b8
commit 10448bcc3d
11 changed files with 116 additions and 88 deletions

View file

@ -817,8 +817,8 @@ PRIVATE
history/view/media/history_view_poll.h
history/view/media/history_view_premium_gift.cpp
history/view/media/history_view_premium_gift.h
history/view/media/history_view_save_audio_action.cpp
history/view/media/history_view_save_audio_action.h
history/view/media/history_view_save_document_action.cpp
history/view/media/history_view_save_document_action.h
history/view/media/history_view_service_box.cpp
history/view/media/history_view_service_box.h
history/view/media/history_view_similar_channels.cpp

View file

@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_forum_topic.h"
#include "data/data_forum.h"
#include "data/data_saved_messages.h"
#include "data/data_saved_music.h"
#include "data/data_saved_sublist.h"
#include "data/data_search_controller.h"
#include "data/data_session.h"
@ -2479,6 +2480,17 @@ void ApiWrap::refreshFileReference(
request(MTPmessages_GetScheduledMessages(
item->history()->peer->input,
MTP_vector<MTPint>(1, MTP_int(realId))));
} else if (item->isSavedMusicItem()) {
const auto user = item->history()->peer->asUser();
const auto media = item->media();
const auto document = media ? media->document() : nullptr;
if (user && document) {
request(MTPusers_GetSavedMusicByID(
user->inputUser,
MTP_vector<MTPInputDocument>(1, document->mtpInput())));
} else {
fail();
}
} else if (item->isBusinessShortcut()) {
const auto &shortcuts = _session->data().shortcutMessages();
const auto realId = shortcuts.lookupId(item);

View file

@ -204,6 +204,12 @@ struct FileReferenceAccumulator {
void push(const MTPstories_Stories &data) {
push(data.data().vstories());
}
void push(const MTPusers_SavedMusic &data) {
data.match([&](const MTPDusers_savedMusic &data) {
push(data.vdocuments());
}, [](const MTPDusers_savedMusicNotModified &data) {
});
}
UpdatedFileReferences result;
};
@ -273,6 +279,10 @@ UpdatedFileReferences GetFileReferences(const MTPstories_Stories &data) {
return GetFileReferencesHelper(data);
}
UpdatedFileReferences GetFileReferences(const MTPusers_SavedMusic &data) {
return GetFileReferencesHelper(data);
}
UpdatedFileReferences GetFileReferences(const MTPMessageMedia &data) {
return GetFileReferencesHelper(data);
}

View file

@ -221,6 +221,7 @@ UpdatedFileReferences GetFileReferences(
UpdatedFileReferences GetFileReferences(const MTPhelp_PremiumPromo &data);
UpdatedFileReferences GetFileReferences(const MTPmessages_WebPage &data);
UpdatedFileReferences GetFileReferences(const MTPstories_Stories &data);
UpdatedFileReferences GetFileReferences(const MTPusers_SavedMusic &data);
// Admin Log Event.
UpdatedFileReferences GetFileReferences(const MTPMessageMedia &data);

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "base/unixtime.h"
#include "data/data_document.h"
#include "data/data_file_origin.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "data/data_user.h"
@ -94,7 +95,9 @@ bool SavedMusic::has(not_null<DocumentData*> document) const {
return ranges::contains(_myIds, document->id);
}
void SavedMusic::save(not_null<DocumentData*> document) {
void SavedMusic::save(
not_null<DocumentData*> document,
Data::FileOrigin origin) {
const auto peerId = _owner->session().userPeerId();
auto &entry = _entries[peerId];
if (entry.list.empty() && !entry.loaded) {
@ -109,11 +112,27 @@ void SavedMusic::save(not_null<DocumentData*> document) {
++entry.total;
}
_myIds.insert(begin(_myIds), document->id);
_owner->session().api().request(MTPaccount_SaveMusic(
MTP_flags(0),
document->mtpInput(),
MTPInputDocument()
)).send();
const auto send = [=](auto resend) -> void {
const auto usedFileReference = document->fileReference();
_owner->session().api().request(MTPaccount_SaveMusic(
MTP_flags(0),
document->mtpInput(),
MTPInputDocument()
)).fail([=](const MTP::Error &error) {
if (error.code() == 400
&& error.type().startsWith(u"FILE_REFERENCE_"_q)) {
document->session().api().refreshFileReference(origin, [=](
const auto &) {
if (document->fileReference() != usedFileReference) {
resend(resend);
}
});
}
}).send();
};
send(send);
_changed.fire_copy(peerId);
}

View file

@ -16,6 +16,7 @@ class PeerData;
namespace Data {
class Session;
struct FileOrigin;
class SavedMusic final {
public:
@ -34,7 +35,7 @@ public:
void loadIds();
[[nodiscard]] bool has(not_null<DocumentData*> document) const;
void save(not_null<DocumentData*> document);
void save(not_null<DocumentData*> document, FileOrigin origin);
void remove(not_null<DocumentData*> document);
void apply(not_null<UserData*> user, const MTPDocument *last);

View file

@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/controls/history_view_forward_panel.h"
#include "history/view/controls/history_view_draft_options.h"
#include "history/view/controls/history_view_suggest_options.h"
#include "history/view/media/history_view_save_audio_action.h"
#include "history/view/media/history_view_save_document_action.h"
#include "history/view/media/history_view_sticker.h"
#include "history/view/media/history_view_web_page.h"
#include "history/view/reactions/history_view_reactions.h"
@ -2513,9 +2513,6 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
return;
}
const auto itemId = item ? item->fullId() : FullMsgId();
const auto lnkIsVideo = document->isVideoFile();
const auto lnkIsVoice = document->isVoiceMessage();
const auto lnkIsAudio = document->isAudioFile();
if (document->isGifv()) {
const auto notAutoplayedGif = [&] {
return item
@ -2548,26 +2545,11 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
item,
document,
controller);
if (lnkIsAudio) {
HistoryView::AddSaveAudioAction(
Ui::Menu::CreateAddActionCallback(_menu),
item,
document,
controller);
} else {
const auto text = lnkIsVideo
? tr::lng_context_save_video(tr::now)
: lnkIsVoice
? tr::lng_context_save_audio(tr::now)
: lnkIsAudio
? tr::lng_context_save_audio_file(tr::now)
: tr::lng_context_save_file(tr::now);
const auto &ripple = st::defaultDropdownMenu.menu.ripple;
const auto duration = ripple.hideDuration;
_menu->addAction(text, base::fn_delayed(duration, this, [=] {
saveDocumentToFile(itemId, document);
}), &st::menuIconDownload);
}
HistoryView::AddSaveDocumentAction(
Ui::Menu::CreateAddActionCallback(_menu),
item,
document,
controller);
HistoryView::AddCopyFilename(
_menu,
document,
@ -2581,7 +2563,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}, &st::menuIconStickers);
}
if (item
&& (lnkIsVoice || document->isVideoMessage())
&& (document->isVoiceMessage() || document->isVideoMessage())
&& Menu::HasRateTranscribeItem(item)) {
rateTranscriptionItem = item;
}

View file

@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item_text.h"
#include "history/view/history_view_schedule_box.h"
#include "history/view/media/history_view_media.h"
#include "history/view/media/history_view_save_document_action.h"
#include "history/view/media/history_view_web_page.h"
#include "history/view/reactions/history_view_reactions_list.h"
#include "info/info_memento.h"
@ -236,39 +237,6 @@ void ShowInFolder(not_null<DocumentData*> document) {
}
}
void AddSaveDocumentAction(
not_null<Ui::PopupMenu*> menu,
HistoryItem *item,
not_null<DocumentData*> document,
not_null<ListWidget*> list) {
if (list->hasCopyMediaRestriction(item) || ItemHasTtl(item)) {
return;
}
const auto origin = item ? item->fullId() : FullMsgId();
const auto save = [=] {
DocumentSaveClickHandler::SaveAndTrack(
origin,
document,
DocumentSaveClickHandler::Mode::ToNewFile);
};
menu->addAction(
(document->isVideoFile()
? tr::lng_context_save_video(tr::now)
: (document->isVoiceMessage()
? tr::lng_context_save_audio(tr::now)
: (document->isAudioFile()
? tr::lng_context_save_audio_file(tr::now)
: (document->sticker()
? tr::lng_context_save_image(tr::now)
: tr::lng_context_save_file(tr::now))))),
base::fn_delayed(
st::defaultDropdownMenu.menu.ripple.hideDuration,
&document->session(),
save),
&st::menuIconDownload);
}
void AddDocumentActions(
not_null<Ui::PopupMenu*> menu,
not_null<DocumentData*> document,

View file

@ -5,18 +5,22 @@ the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/media/history_view_save_audio_action.h"
#include "history/view/media/history_view_save_document_action.h"
#include "base/call_delayed.h"
#include "data/data_document.h"
#include "data/data_file_click_handler.h"
#include "data/data_file_origin.h"
#include "data/data_peer.h"
#include "data/data_saved_music.h"
#include "data/data_session.h"
#include "history/view/history_view_context_menu.h"
#include "history/view/history_view_list_widget.h"
#include "history/history.h"
#include "history/history_item.h"
#include "lang/lang_keys.h"
#include "ui/widgets/menu/menu_add_action_callback.h"
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
#include "ui/widgets/menu/menu_multiline_action.h"
#include "ui/widgets/popup_menu.h"
#include "window/window_peer_menu.h"
@ -27,7 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView {
void AddSaveAudioAction(
void AddSaveDocumentAction(
const Ui::Menu::MenuCallback &addAction,
not_null<HistoryItem*> item,
not_null<DocumentData*> document,
@ -46,16 +50,22 @@ void AddSaveAudioAction(
DocumentSaveClickHandler::Mode::ToNewFile);
});
if (!document->isMusicForProfile() || (fromSaved && inProfile)) {
addAction(
tr::lng_context_save_audio_file(tr::now),
saveAs,
&st::menuIconDownload);
const auto text = document->isVideoFile()
? tr::lng_context_save_video(tr::now)
: document->isVoiceMessage()
? tr::lng_context_save_audio(tr::now)
: document->isAudioFile()
? tr::lng_context_save_audio_file(tr::now)
: document->sticker()
? tr::lng_context_save_image(tr::now)
: tr::lng_context_save_file(tr::now);
addAction(text, saveAs, &st::menuIconDownload);
return;
}
const auto fill = [&](not_null<Ui::PopupMenu*> menu) {
if (!inProfile) {
const auto saved = [=] {
savedMusic->save(document);
savedMusic->save(document, contextId);
show->showToast(tr::lng_saved_music_added(tr::now));
};
menu->addAction(
@ -98,4 +108,19 @@ void AddSaveAudioAction(
});
}
void AddSaveDocumentAction(
not_null<Ui::PopupMenu*> menu,
HistoryItem *item,
not_null<DocumentData*> document,
not_null<ListWidget*> list) {
if (!item || list->hasCopyMediaRestriction(item) || ItemHasTtl(item)) {
return;
}
AddSaveDocumentAction(
Ui::Menu::CreateAddActionCallback(menu),
item,
document,
list->controller());
}
} // namespace HistoryView

View file

@ -10,6 +10,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class DocumentData;
class HistoryItem;
namespace Ui {
class PopupMenu;
} // namespace Ui
namespace Ui::Menu {
struct MenuCallback;
} // namespace Ui::Menu
@ -20,10 +24,18 @@ class SessionController;
namespace HistoryView {
void AddSaveAudioAction(
class ListWidget;
void AddSaveDocumentAction(
const Ui::Menu::MenuCallback &addAction,
not_null<HistoryItem*> item,
not_null<DocumentData*> document,
not_null<Window::SessionController*> controller);
void AddSaveDocumentAction(
not_null<Ui::PopupMenu*> menu,
HistoryItem *item,
not_null<DocumentData*> document,
not_null<ListWidget*> list);
} // namespace HistoryView

View file

@ -30,15 +30,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_download_manager.h"
#include "data/data_forum_topic.h"
#include "data/data_saved_sublist.h"
#include "history/history_item.h"
#include "history/history_item_helpers.h"
#include "history/history.h"
#include "history/view/media/history_view_save_document_action.h"
#include "history/view/history_view_cursor_state.h"
#include "history/view/history_view_service_message.h"
#include "history/history.h"
#include "history/history_item.h"
#include "history/history_item_helpers.h"
#include "media/stories/media_stories_controller.h" // ...TogglePinnedToast.
#include "media/stories/media_stories_share.h" // PrepareShareBox.
#include "window/window_session_controller.h"
#include "window/window_peer_menu.h"
#include "ui/widgets/menu/menu_add_action_callback.h"
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
#include "ui/widgets/popup_menu.h"
#include "ui/boxes/confirm_box.h"
#include "ui/controls/delete_message_context_action.h"
@ -1150,16 +1153,11 @@ void ListWidget::showContextMenu(
DocumentSaveClickHandler::Mode::ToNewFile);
});
if (_provider->allowSaveFileAs(item, lnkDocument)) {
_contextMenu->addAction(
(isVideo
? tr::lng_context_save_video(tr::now)
: isVoice
? tr::lng_context_save_audio(tr::now)
: isAudio
? tr::lng_context_save_audio_file(tr::now)
: tr::lng_context_save_file(tr::now)),
std::move(handler),
&st::menuIconDownload);
HistoryView::AddSaveDocumentAction(
Ui::Menu::CreateAddActionCallback(_contextMenu),
item,
lnkDocument,
_controller->parentController());
}
}
}