mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Process gift updates in list.
This commit is contained in:
parent
779e9b658b
commit
962d4d29ee
12 changed files with 177 additions and 34 deletions
Telegram
Resources/langs
SourceFiles
|
@ -3014,6 +3014,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_gift_limited_of_one" = "unique";
|
||||
"lng_gift_limited_of_count" = "1 of {amount}";
|
||||
"lng_gift_anonymous_hint" = "Only you can see the sender's name.";
|
||||
"lng_gift_hidden_hint" = "This gift is hidden. Only you can see it.";
|
||||
"lng_gift_visible_hint" = "This gift is visible to visitors of your page.";
|
||||
"lng_gift_availability" = "Availability";
|
||||
"lng_gift_from_hidden" = "Hidden User";
|
||||
"lng_gift_availability_left#one" = "{count} of {amount} left";
|
||||
|
|
|
@ -251,7 +251,7 @@ void StickerPremiumMark::paint(
|
|||
: (singleSize.height() - (bg.height() / factor) - radius);
|
||||
const auto point = position + QPoint(shiftx, shifty);
|
||||
p.drawImage(point, bg);
|
||||
if (_premium) {
|
||||
if (_premium && _part != RectPart::Center) {
|
||||
validateStar();
|
||||
p.drawImage(point, _star);
|
||||
} else {
|
||||
|
|
|
@ -69,6 +69,7 @@ struct CreditsHistoryEntry final {
|
|||
bool converted = false;
|
||||
bool anonymous = false;
|
||||
bool savedToProfile = false;
|
||||
bool fromGiftsList = false;
|
||||
bool reaction = false;
|
||||
bool refunded = false;
|
||||
bool pending = false;
|
||||
|
|
|
@ -579,6 +579,10 @@ const Invoice *Media::invoice() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const GiftCode *Media::gift() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CloudImage *Media::location() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2331,8 +2335,8 @@ not_null<PeerData*> MediaGiftBox::from() const {
|
|||
return _from;
|
||||
}
|
||||
|
||||
const GiftCode &MediaGiftBox::data() const {
|
||||
return _data;
|
||||
const GiftCode *MediaGiftBox::gift() const {
|
||||
return &_data;
|
||||
}
|
||||
|
||||
TextWithEntities MediaGiftBox::notificationText() const {
|
||||
|
|
|
@ -172,6 +172,7 @@ public:
|
|||
virtual const Call *call() const;
|
||||
virtual GameData *game() const;
|
||||
virtual const Invoice *invoice() const;
|
||||
virtual const GiftCode *gift() const;
|
||||
virtual CloudImage *location() const;
|
||||
virtual PollData *poll() const;
|
||||
virtual const WallPaper *paper() const;
|
||||
|
@ -621,7 +622,7 @@ public:
|
|||
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
|
||||
|
||||
[[nodiscard]] not_null<PeerData*> from() const;
|
||||
[[nodiscard]] const GiftCode &data() const;
|
||||
[[nodiscard]] const GiftCode *gift() const override;
|
||||
|
||||
TextWithEntities notificationText() const override;
|
||||
QString pinnedTextSubstring() const override;
|
||||
|
|
|
@ -1645,6 +1645,14 @@ rpl::producer<not_null<HistoryItem*>> Session::newItemAdded() const {
|
|||
return _newItemAdded.events();
|
||||
}
|
||||
|
||||
void Session::notifyGiftUpdate(GiftUpdate &&update) {
|
||||
_giftUpdates.fire(std::move(update));
|
||||
}
|
||||
|
||||
rpl::producer<GiftUpdate> Session::giftUpdates() const {
|
||||
return _giftUpdates.events();
|
||||
}
|
||||
|
||||
HistoryItem *Session::changeMessageId(PeerId peerId, MsgId wasId, MsgId nowId) {
|
||||
const auto list = messagesListForInsert(peerId);
|
||||
const auto i = list->find(wasId);
|
||||
|
|
|
@ -77,6 +77,18 @@ struct RepliesReadTillUpdate {
|
|||
bool out = false;
|
||||
};
|
||||
|
||||
struct GiftUpdate {
|
||||
enum class Action : uchar {
|
||||
Save,
|
||||
Unsave,
|
||||
Convert,
|
||||
Delete,
|
||||
};
|
||||
|
||||
FullMsgId itemId;
|
||||
Action action = {};
|
||||
};
|
||||
|
||||
class Session final {
|
||||
public:
|
||||
using ViewElement = HistoryView::Element;
|
||||
|
@ -281,6 +293,8 @@ public:
|
|||
[[nodiscard]] rpl::producer<not_null<const ViewElement*>> viewLayoutChanged() const;
|
||||
void notifyNewItemAdded(not_null<HistoryItem*> item);
|
||||
[[nodiscard]] rpl::producer<not_null<HistoryItem*>> newItemAdded() const;
|
||||
void notifyGiftUpdate(GiftUpdate &&update);
|
||||
[[nodiscard]] rpl::producer<GiftUpdate> giftUpdates() const;
|
||||
void requestItemRepaint(not_null<const HistoryItem*> item);
|
||||
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemRepaintRequest() const;
|
||||
void requestViewRepaint(not_null<const ViewElement*> view);
|
||||
|
@ -924,6 +938,7 @@ private:
|
|||
rpl::event_stream<not_null<const HistoryItem*>> _itemLayoutChanges;
|
||||
rpl::event_stream<not_null<const ViewElement*>> _viewLayoutChanges;
|
||||
rpl::event_stream<not_null<HistoryItem*>> _newItemAdded;
|
||||
rpl::event_stream<GiftUpdate> _giftUpdates;
|
||||
rpl::event_stream<not_null<const HistoryItem*>> _itemRepaintRequest;
|
||||
rpl::event_stream<not_null<const ViewElement*>> _viewRepaintRequest;
|
||||
rpl::event_stream<not_null<const HistoryItem*>> _itemResizeRequest;
|
||||
|
|
|
@ -175,6 +175,15 @@ void History::itemVanished(not_null<HistoryItem*> item) {
|
|||
&& unreadCount() > 0) {
|
||||
setUnreadCount(unreadCount() - 1);
|
||||
}
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto gift = media->gift()) {
|
||||
using GiftAction = Data::GiftUpdate::Action;
|
||||
owner().notifyGiftUpdate({
|
||||
.itemId = item->fullId(),
|
||||
.action = GiftAction::Delete,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void History::takeLocalDraft(not_null<History*> from) {
|
||||
|
|
|
@ -2374,6 +2374,7 @@ bool Message::hasFromPhoto() const {
|
|||
} else if (item->isPost()) {
|
||||
return true;
|
||||
} else if (item->isEmpty()
|
||||
|| item->isFakeAboutView()
|
||||
|| (context() == Context::Replies && item->isDiscussionPost())) {
|
||||
return false;
|
||||
} else if (delegate()->elementIsChatWide()) {
|
||||
|
|
|
@ -37,7 +37,7 @@ PremiumGift::PremiumGift(
|
|||
not_null<Data::MediaGiftBox*> gift)
|
||||
: _parent(parent)
|
||||
, _gift(gift)
|
||||
, _data(gift->data()) {
|
||||
, _data(*gift->gift()) {
|
||||
}
|
||||
|
||||
PremiumGift::~PremiumGift() = default;
|
||||
|
@ -155,7 +155,7 @@ ClickHandlerPtr PremiumGift::createViewLink() {
|
|||
const auto itemId = _parent->data()->fullId();
|
||||
const auto peer = _parent->history()->peer;
|
||||
const auto date = _parent->data()->date();
|
||||
const auto data = _gift->data();
|
||||
const auto data = *_gift->gift();
|
||||
return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
if (const auto controller = my.sessionWindow.get()) {
|
||||
|
|
|
@ -76,7 +76,9 @@ private:
|
|||
int visibleBottom) override;
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void subscribeToUpdates();
|
||||
void loadMore();
|
||||
void refreshButtons();
|
||||
void validateButtons();
|
||||
void showGift(int index);
|
||||
|
||||
|
@ -119,6 +121,52 @@ InnerWidget::InnerWidget(
|
|||
, _totalCount(_user->peerGiftsCount())
|
||||
, _api(&_user->session().mtp()) {
|
||||
_singleMin = _delegate.buttonSize();
|
||||
|
||||
if (user->isSelf()) {
|
||||
subscribeToUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::subscribeToUpdates() {
|
||||
_user->owner().giftUpdates(
|
||||
) | rpl::start_with_next([=](const Data::GiftUpdate &update) {
|
||||
const auto itemId = [](const Entry &entry) {
|
||||
return FullMsgId(entry.gift.fromId, entry.gift.messageId);
|
||||
};
|
||||
const auto i = ranges::find(_entries, update.itemId, itemId);
|
||||
if (i == end(_entries)) {
|
||||
return;
|
||||
}
|
||||
const auto index = int(i - begin(_entries));
|
||||
using Action = Data::GiftUpdate::Action;
|
||||
if (update.action == Action::Convert
|
||||
|| update.action == Action::Delete) {
|
||||
_entries.erase(i);
|
||||
if (_totalCount > 0) {
|
||||
--_totalCount;
|
||||
}
|
||||
for (auto &view : _views) {
|
||||
if (view.entry >= index) {
|
||||
--view.entry;
|
||||
}
|
||||
}
|
||||
} else if (update.action == Action::Save
|
||||
|| update.action == Action::Unsave) {
|
||||
i->gift.hidden = (update.action == Action::Unsave);
|
||||
v::match(i->descriptor, [](GiftTypePremium &) {
|
||||
}, [&](GiftTypeStars &data) {
|
||||
data.hidden = i->gift.hidden;
|
||||
});
|
||||
for (auto &view : _views) {
|
||||
if (view.entry == index) {
|
||||
view.entry = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
refreshButtons();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void InnerWidget::visibleTopBottomUpdated(
|
||||
|
@ -170,17 +218,21 @@ void InnerWidget::loadMore() {
|
|||
});
|
||||
}
|
||||
}
|
||||
_viewsForWidth = 0;
|
||||
_viewsFromRow = 0;
|
||||
_viewsTillRow = 0;
|
||||
resizeToWidth(width());
|
||||
validateButtons();
|
||||
refreshButtons();
|
||||
}).fail([=] {
|
||||
_loadMoreRequestId = 0;
|
||||
_allLoaded = true;
|
||||
}).send();
|
||||
}
|
||||
|
||||
void InnerWidget::refreshButtons() {
|
||||
_viewsForWidth = 0;
|
||||
_viewsFromRow = 0;
|
||||
_viewsTillRow = 0;
|
||||
resizeToWidth(width());
|
||||
validateButtons();
|
||||
}
|
||||
|
||||
void InnerWidget::validateButtons() {
|
||||
if (!_perRow) {
|
||||
return;
|
||||
|
|
|
@ -38,6 +38,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "info/channel_statistics/boosts/giveaway/boost_badge.h" // InfiniteRadialAnimationWidget.
|
||||
#include "info/settings/info_settings_widget.h" // SectionCustomTopBarData.
|
||||
#include "info/statistics/info_statistics_list_controllers.h"
|
||||
#include "info/info_controller.h"
|
||||
#include "info/info_memento.h"
|
||||
#include "iv/iv_instance.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "lottie/lottie_single_player.h"
|
||||
|
@ -158,21 +160,19 @@ private:
|
|||
|
||||
void ToggleStarGiftSaved(
|
||||
not_null<Window::SessionController*> window,
|
||||
not_null<HistoryItem*> item,
|
||||
not_null<UserData*> sender,
|
||||
MsgId itemId,
|
||||
bool save,
|
||||
Fn<void(bool)> done) {
|
||||
Expects(item->history()->peer->isUser());
|
||||
|
||||
using Flag = MTPpayments_SaveStarGift::Flag;
|
||||
const auto api = &window->session().api();
|
||||
const auto weak = base::make_weak(window);
|
||||
api->request(MTPpayments_SaveStarGift(
|
||||
MTP_flags(save ? Flag(0) : Flag::f_unsave),
|
||||
item->history()->peer->asUser()->inputUser,
|
||||
MTP_int(item->id.bare)
|
||||
sender->inputUser,
|
||||
MTP_int(itemId.bare)
|
||||
)).done([=] {
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->showPeerInfo(strong->session().user());
|
||||
strong->showToast((save
|
||||
? tr::lng_gift_display_done
|
||||
: tr::lng_gift_display_done_hide)(tr::now));
|
||||
|
@ -206,16 +206,15 @@ void ConfirmConvertStarGift(
|
|||
|
||||
void ConvertStarGift(
|
||||
not_null<Window::SessionController*> window,
|
||||
not_null<HistoryItem*> item,
|
||||
not_null<UserData*> sender,
|
||||
MsgId itemId,
|
||||
int stars,
|
||||
Fn<void(bool)> done) {
|
||||
Expects(item->history()->peer->isUser());
|
||||
|
||||
const auto api = &window->session().api();
|
||||
const auto weak = base::make_weak(window);
|
||||
api->request(MTPpayments_ConvertStarGift(
|
||||
item->history()->peer->asUser()->inputUser,
|
||||
MTP_int(item->id.bare)
|
||||
sender->inputUser,
|
||||
MTP_int(itemId)
|
||||
)).done([=] {
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->showSettings(Settings::CreditsId());
|
||||
|
@ -734,6 +733,8 @@ void ReceiptCreditsBox(
|
|||
const auto myStarGift = isStarGift && e.in;
|
||||
const auto starGiftSender = (isStarGift && item)
|
||||
? item->history()->peer->asUser()
|
||||
: (isStarGift && e.in)
|
||||
? controller->session().data().peer(PeerId(e.barePeerId))->asUser()
|
||||
: nullptr;
|
||||
const auto canConvert = myStarGift
|
||||
&& !e.converted
|
||||
|
@ -1081,6 +1082,15 @@ void ReceiptCreditsBox(
|
|||
tr::lng_credits_box_out_about_link(tr::now)),
|
||||
Ui::Text::WithEntities),
|
||||
st::creditsBoxAboutDivider)));
|
||||
} else if (myStarGift && e.fromGiftsList) {
|
||||
box->addRow(object_ptr<Ui::CenterWrap<>>(
|
||||
box,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
(e.savedToProfile
|
||||
? tr::lng_gift_visible_hint()
|
||||
: tr::lng_gift_hidden_hint()),
|
||||
st::creditsBoxAboutDivider)));
|
||||
} else if (myStarGift && e.anonymous) {
|
||||
box->addRow(object_ptr<Ui::CenterWrap<>>(
|
||||
box,
|
||||
|
@ -1157,11 +1167,29 @@ void ReceiptCreditsBox(
|
|||
if (canConvert) {
|
||||
const auto save = !e.savedToProfile;
|
||||
const auto window = weakWindow.get();
|
||||
const auto item = session->data().message(
|
||||
starGiftSender->id,
|
||||
MsgId(e.bareMsgId));
|
||||
if (window && item) {
|
||||
ToggleStarGiftSaved(window, item, save, [=](bool ok) {
|
||||
const auto showSection = !e.fromGiftsList;
|
||||
const auto itemId = MsgId(e.bareMsgId);
|
||||
if (window) {
|
||||
const auto done = [=](bool ok) {
|
||||
if (const auto window = weakWindow.get()) {
|
||||
if (ok) {
|
||||
using GiftAction = Data::GiftUpdate::Action;
|
||||
window->session().data().notifyGiftUpdate({
|
||||
.itemId = FullMsgId(
|
||||
starGiftSender->id,
|
||||
itemId),
|
||||
.action = (save
|
||||
? GiftAction::Save
|
||||
: GiftAction::Unsave),
|
||||
});
|
||||
if (showSection) {
|
||||
window->showSection(
|
||||
std::make_shared<Info::Memento>(
|
||||
window->session().user(),
|
||||
Info::Section::Type::PeerGifts));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (const auto strong = weak.data()) {
|
||||
if (ok) {
|
||||
strong->closeBox();
|
||||
|
@ -1169,7 +1197,13 @@ void ReceiptCreditsBox(
|
|||
state->confirmButtonBusy = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
ToggleStarGiftSaved(
|
||||
window,
|
||||
starGiftSender,
|
||||
itemId,
|
||||
save,
|
||||
done);
|
||||
}
|
||||
} else if (toRenew && s.expired) {
|
||||
Api::CheckChatInvite(controller, s.inviteHash, nullptr, [=] {
|
||||
|
@ -1265,11 +1299,20 @@ void ReceiptCreditsBox(
|
|||
}
|
||||
state->convertButtonBusy = true;
|
||||
const auto window = weakWindow.get();
|
||||
const auto item = session->data().message(
|
||||
starGiftSender->id,
|
||||
MsgId(e.bareMsgId));
|
||||
if (window && item && stars) {
|
||||
ConvertStarGift(window, item, stars, [=](bool ok) {
|
||||
const auto itemId = MsgId(e.bareMsgId);
|
||||
if (window && stars) {
|
||||
const auto done = [=](bool ok) {
|
||||
if (const auto window = weakWindow.get()) {
|
||||
if (ok) {
|
||||
using GiftAction = Data::GiftUpdate::Action;
|
||||
window->session().data().notifyGiftUpdate({
|
||||
.itemId = FullMsgId(
|
||||
starGiftSender->id,
|
||||
itemId),
|
||||
.action = GiftAction::Convert,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (const auto strong = weak.data()) {
|
||||
if (ok) {
|
||||
strong->closeBox();
|
||||
|
@ -1277,7 +1320,13 @@ void ReceiptCreditsBox(
|
|||
state->convertButtonBusy = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
ConvertStarGift(
|
||||
window,
|
||||
starGiftSender,
|
||||
itemId,
|
||||
stars,
|
||||
done);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1366,6 +1415,7 @@ void UserStarGiftBox(
|
|||
.converted = false,
|
||||
.anonymous = data.anonymous,
|
||||
.savedToProfile = !data.hidden,
|
||||
.fromGiftsList = true,
|
||||
.in = data.mine,
|
||||
.gift = true,
|
||||
},
|
||||
|
|
Loading…
Add table
Reference in a new issue