Jump-to-scheduled on video processing.

This commit is contained in:
John Preston 2024-10-29 13:20:42 +04:00
parent b9ebb02e72
commit 3137c9f3f7
15 changed files with 120 additions and 18 deletions

View file

@ -2119,8 +2119,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_recommended_message_title" = "Recommended";
"lng_edited" = "edited";
"lng_commented" = "commented";
"lng_approximate" = "appx.";
"lng_edited_date" = "Edited: {date}";
"lng_sent_date" = "Sent: {date}";
"lng_approximate_about" = "Estimated date of video publishing.";
"lng_views_tooltip#one" = "Views: {count}";
"lng_views_tooltip#other" = "Views: {count}";
"lng_forwards_tooltip#one" = "Shares: {count}";

View file

@ -316,6 +316,9 @@ void Updates::feedUpdateVector(
} else if (policy == SkipUpdatePolicy::SkipExceptGroupCallParticipants) {
return;
}
if (policy == SkipUpdatePolicy::SkipNone) {
applyConvertToScheduledOnSend(updates);
}
for (const auto &entry : std::as_const(list)) {
const auto type = entry.type();
if ((policy == SkipUpdatePolicy::SkipMessageIds
@ -432,6 +435,7 @@ void Updates::feedChannelDifference(
session().data().processChats(data.vchats());
_handlingChannelDifference = true;
applyConvertToScheduledOnSend(data.vother_updates());
feedMessageIds(data.vother_updates());
session().data().processMessages(
data.vnew_messages(),
@ -596,6 +600,7 @@ void Updates::feedDifference(
Core::App().checkAutoLock();
session().data().processUsers(users);
session().data().processChats(chats);
applyConvertToScheduledOnSend(other);
feedMessageIds(other);
session().data().processMessages(msgs, NewMessageType::Unread);
feedUpdateVector(other, SkipUpdatePolicy::SkipMessageIds);
@ -881,6 +886,39 @@ void Updates::mtpUpdateReceived(const MTPUpdates &updates) {
}
}
void Updates::applyConvertToScheduledOnSend(
const MTPVector<MTPUpdate> &other) {
for (const auto &update : other.v) {
update.match([&](const MTPDupdateNewScheduledMessage &data) {
const auto id = IdFromMessage(data.vmessage());
const auto scheduledMessages = &_session->scheduledMessages();
const auto scheduledId = scheduledMessages->localMessageId(id);
for (const auto &updateId : other.v) {
updateId.match([&](const MTPDupdateMessageID &dataId) {
if (dataId.vid().v == id) {
const auto rand = dataId.vrandom_id().v;
auto &owner = session().data();
const auto localId = owner.messageIdByRandomId(rand);
if (const auto local = owner.message(localId)) {
if (!local->isScheduled()) {
using Flag = Data::MessageUpdate::Flag;
_session->data().sentToScheduled({
.item = local,
.scheduledId = scheduledId,
});
// We've sent a non-scheduled message,
// but it was converted to a scheduled.
local->destroy();
}
}
}
}, [](const auto &) {});
}
}, [](const auto &) {});
}
}
void Updates::applyGroupCallParticipantUpdates(const MTPUpdates &updates) {
updates.match([&](const MTPDupdates &data) {
session().data().processUsers(data.vusers());

View file

@ -131,6 +131,7 @@ private:
// Doesn't call sendHistoryChangeNotifications itself.
void feedUpdate(const MTPUpdate &update);
void applyConvertToScheduledOnSend(const MTPVector<MTPUpdate> &other);
void applyGroupCallParticipantUpdates(const MTPUpdates &updates);
bool whenGetDiffChanged(

View file

@ -4813,6 +4813,14 @@ void Session::viewTagsChanged(
}
}
void Session::sentToScheduled(SentToScheduled value) {
_sentToScheduled.fire(std::move(value));
}
rpl::producer<SentToScheduled> Session::sentToScheduled() const {
return _sentToScheduled.events();
}
void Session::clearLocalStorage() {
_cache->close();
_cache->clear();

View file

@ -89,6 +89,11 @@ struct GiftUpdate {
Action action = {};
};
struct SentToScheduled {
not_null<HistoryItem*> item;
MsgId scheduledId = 0;
};
class Session final {
public:
using ViewElement = HistoryView::Element;
@ -791,6 +796,9 @@ public:
std::vector<ReactionId> &&was,
std::vector<ReactionId> &&now);
void sentToScheduled(SentToScheduled value);
[[nodiscard]] rpl::producer<SentToScheduled> sentToScheduled() const;
void clearLocalStorage();
private:
@ -963,6 +971,7 @@ private:
rpl::event_stream<ChatListEntryRefresh> _chatListEntryRefreshes;
rpl::event_stream<> _unreadBadgeChanges;
rpl::event_stream<RepliesReadTillUpdate> _repliesReadTillUpdates;
rpl::event_stream<SentToScheduled> _sentToScheduled;
Dialogs::MainList _chatsList;
Dialogs::IndexedList _contactsList;

View file

@ -327,6 +327,8 @@ enum class MessageFlag : uint64 {
SensitiveContent = (1ULL << 47),
HasRestrictions = (1ULL << 48),
EstimatedDate = (1ULL << 49),
};
inline constexpr bool is_flag_type(MessageFlag) { return true; }
using MessageFlags = base::flags<MessageFlag>;

View file

@ -761,6 +761,10 @@ TimeId HistoryItem::date() const {
return _date;
}
bool HistoryItem::awaitingVideoProcessing() const {
return (_flags & MessageFlag::EstimatedDate);
}
HistoryServiceDependentData *HistoryItem::GetServiceDependentData() {
if (const auto pinned = Get<HistoryServicePinned>()) {
return pinned;

View file

@ -482,6 +482,7 @@ public:
[[nodiscard]] GlobalMsgId globalId() const;
[[nodiscard]] Data::MessagePosition position() const;
[[nodiscard]] TimeId date() const;
[[nodiscard]] bool awaitingVideoProcessing() const;
[[nodiscard]] Data::Media *media() const {
return _media.get();

View file

@ -451,7 +451,10 @@ MessageFlags FlagsFromMTP(
: Flag())
| ((flags & MTP::f_views) ? Flag::HasViews : Flag())
| ((flags & MTP::f_noforwards) ? Flag::NoForwards : Flag())
| ((flags & MTP::f_invert_media) ? Flag::InvertMedia : Flag());
| ((flags & MTP::f_invert_media) ? Flag::InvertMedia : Flag())
| ((flags & MTP::f_video_processing_pending)
? Flag::EstimatedDate
: Flag());
}
MessageFlags FlagsFromMTP(

View file

@ -723,6 +723,21 @@ HistoryWidget::HistoryWidget(
maybeMarkReactionsRead(update.item);
}, lifetime());
session().data().sentToScheduled(
) | rpl::start_with_next([=](const Data::SentToScheduled &value) {
if (value.item->history() == _history) {
const auto history = value.item->history();
const auto id = value.scheduledId;
crl::on_main(this, [=] {
controller->showSection(
std::make_shared<HistoryView::ScheduledMemento>(
history,
id));
});
return;
}
}, lifetime());
using MediaSwitch = Media::Player::Instance::Switch;
Media::Player::instance()->switchToNextEvents(
) | rpl::filter([=](const MediaSwitch &pair) {

View file

@ -407,6 +407,8 @@ void BottomInfo::layout() {
void BottomInfo::layoutDateText() {
const auto edited = (_data.flags & Data::Flag::Edited)
? (tr::lng_edited(tr::now) + ' ')
: (_data.flags & Data::Flag::EstimateDate)
? (tr::lng_approximate(tr::now) + ' ')
: QString();
const auto author = _data.author;
const auto prefix = !author.isEmpty() ? u", "_q : QString();
@ -601,6 +603,9 @@ BottomInfo::Data BottomInfoDataFromMessage(not_null<Message*> message) {
if (forwarded && forwarded->imported) {
result.flags |= Flag::Imported;
}
if (item->awaitingVideoProcessing()) {
result.flags |= Flag::EstimateDate;
}
// We don't want to pass and update it in Data for now.
//if (item->unread()) {
// result.flags |= Flag::Unread;

View file

@ -32,15 +32,16 @@ struct TextState;
class BottomInfo final : public Object {
public:
struct Data {
enum class Flag : uchar {
Edited = 0x01,
OutLayout = 0x02,
Sending = 0x04,
RepliesContext = 0x08,
Sponsored = 0x10,
Pinned = 0x20,
Imported = 0x40,
Shortcut = 0x80,
enum class Flag : uint16 {
Edited = 0x001,
OutLayout = 0x002,
Sending = 0x004,
RepliesContext = 0x008,
Sponsored = 0x010,
Pinned = 0x020,
Imported = 0x040,
Shortcut = 0x080,
EstimateDate = 0x100,
//Unread, // We don't want to pass and update it in Date for now.
};
friend inline constexpr bool is_flag_type(Flag) { return true; };

View file

@ -264,6 +264,9 @@ QString DateTooltipText(not_null<Element*> view) {
const auto format = QLocale::LongFormat;
const auto item = view->data();
auto dateText = locale.toString(view->dateTime(), format);
if (item->awaitingVideoProcessing()) {
dateText += '\n' + tr::lng_approximate_about(tr::now);
}
if (const auto editedDate = view->displayedEditDate()) {
dateText += '\n' + tr::lng_edited_date(
tr::now,

View file

@ -56,18 +56,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView {
ScheduledMemento::ScheduledMemento(not_null<History*> history)
: _history(history)
, _forumTopic(nullptr) {
ScheduledMemento::ScheduledMemento(
not_null<History*> history,
MsgId sentToScheduledId)
: _history(history)
, _forumTopic(nullptr)
, _sentToScheduledId(sentToScheduledId) {
const auto list = _history->session().scheduledMessages().list(_history);
if (!list.ids.empty()) {
_list.setScrollTopState({ .item = {.fullId = list.ids.front() } });
if (sentToScheduledId) {
_list.setScrollTopState({
.item = { .fullId = { _history->peer->id, sentToScheduledId } },
});
} else if (!list.ids.empty()) {
_list.setScrollTopState({ .item = { .fullId = list.ids.front() } });
}
}
ScheduledMemento::ScheduledMemento(not_null<Data::ForumTopic*> forumTopic)
: _history(forumTopic->owningHistory())
, _forumTopic(forumTopic) {
: _history(forumTopic->owningHistory())
, _forumTopic(forumTopic) {
const auto list = _history->session().scheduledMessages().list(
_forumTopic);
if (!list.ids.empty()) {

View file

@ -288,7 +288,9 @@ private:
class ScheduledMemento final : public Window::SectionMemento {
public:
ScheduledMemento(not_null<History*> history);
ScheduledMemento(
not_null<History*> history,
MsgId sentToScheduledId = 0);
ScheduledMemento(not_null<Data::ForumTopic*> forumTopic);
object_ptr<Window::SectionWidget> createWidget(
@ -309,6 +311,7 @@ private:
const not_null<History*> _history;
const Data::ForumTopic *_forumTopic;
ListMemento _list;
MsgId _sentToScheduledId;
};