diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 866a569926..6a993c9b52 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1001,6 +1001,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_color_changed_profile" = "Your profile style has been updated!"; "lng_settings_color_changed_profile_channel" = "Your channel profile style has been updated!"; "lng_settings_color_apply" = "Apply Style"; +"lng_settings_color_wear" = "Wear Collectible"; "lng_settings_color_profile_emoji" = "Add icons to Profile"; "lng_settings_color_profile_emoji_channel" = "Profile Logo"; "lng_settings_color_reset" = "Reset Profile Color"; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp index e288e2f710..f9463c8c0a 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp @@ -521,11 +521,6 @@ void Set( } else { peer->changeColorProfileIndex(index); } - if (colorCollectible) { - peer->changeColorCollectible(*colorCollectible); - } else { - peer->clearColorCollectible(); - } peer->changeProfileBackgroundEmojiId(emojiId); } else { if (index == kUnsetColorIndex) { @@ -542,8 +537,10 @@ void Set( } peer->session().changes().peerUpdated( peer, - (values.forProfile ? UpdateFlag::ColorProfile : UpdateFlag::Color) - | UpdateFlag::BackgroundEmoji); + (UpdateFlag::BackgroundEmoji + | (values.forProfile + ? UpdateFlag::ColorProfile + : UpdateFlag::Color))); }; setLocal( values.colorIndex, @@ -580,10 +577,11 @@ void Set( using ColorFlag = MTPDpeerColor::Flag; send(MTPaccount_UpdateColor( MTP_flags((values.forProfile ? Flag::f_for_profile : Flag(0)) - | (values.colorIndex != kUnsetColorIndex + | (((!values.forProfile && values.colorCollectible) + || (values.colorIndex != kUnsetColorIndex)) ? Flag::f_color : Flag(0))), - (values.colorCollectible + ((!values.forProfile && values.colorCollectible) ? MTP_inputPeerColorCollectible( MTP_long(values.colorCollectible->collectibleId)) : MTP_peerColor( @@ -594,6 +592,13 @@ void Set( : ColorFlag(0))), MTP_int(values.colorIndex), MTP_long(values.backgroundEmojiId))))); + if (values.statusChanged + && (values.statusId || peer->emojiStatusId())) { + peer->owner().emojiStatuses().set( + peer, + values.statusId, + values.statusUntil); + } } else if (const auto channel = peer->asChannel()) { if (peer->isBroadcast()) { using Flag = MTPchannels_UpdateColor::Flag; @@ -648,10 +653,10 @@ void Apply( const auto colorMatch = (currentColorIndex == values.colorIndex); const auto emojiMatch = (currentEmojiId == values.backgroundEmojiId); - const auto collectibleMatch = (!peer->colorCollectible() - == !values.colorCollectible) - && (!peer->colorCollectible() - || (*peer->colorCollectible() == *values.colorCollectible)); + const auto collectibleMatch = values.forProfile + || ((!peer->colorCollectible() == !values.colorCollectible) + && (!peer->colorCollectible() + || (*peer->colorCollectible() == *values.colorCollectible))); if (colorMatch && emojiMatch @@ -1179,7 +1184,7 @@ void AddGiftSelector( not_null session, rpl::producer showingGiftIdValue, Fn selected)> chosen, - rpl::producer> selected, + rpl::producer selected, bool profile, rpl::producer selectedGiftId = rpl::single(uint64(0)), Fn switchToNextTab = nullptr) { @@ -1202,7 +1207,7 @@ void AddGiftSelector( std::vector validated; std::vector> buttons; rpl::variable visibleRange; - rpl::variable> selected; + rpl::variable selected; rpl::variable selectedGiftId; int perRow = 1; base::unique_qptr emptyPlaceholder; @@ -1302,8 +1307,7 @@ void AddGiftSelector( Assert(rowTill >= rowFrom); const auto first = rowFrom * perRow; const auto last = std::min(rowTill * perRow, count); - const auto current = state->selected.current(); - const auto selectedCollectibleId = current ? current->collectibleId : 0; + const auto selectedCollectibleId = state->selected.current(); const auto selectedGiftId = state->selectedGiftId.current(); auto checkedFrom = 0; auto checkedTill = int(buttons.size()); @@ -1396,10 +1400,8 @@ void AddGiftSelector( state->selected.value( ) | rpl::combine_previous() | rpl::start_with_next([=]( - const std::optional &was, - const std::optional &now) { - const auto wasCollectibleId = was ? was->collectibleId : 0; - const auto nowCollectibleId = now ? now->collectibleId : 0; + uint64 wasCollectibleId, + uint64 nowCollectibleId) { if (wasCollectibleId) { if (const auto button = find(wasCollectibleId)) { button->toggleSelected(false, GiftSelectionMode::Inset); @@ -2063,7 +2065,10 @@ void EditPeerColorSection( ? *selected->peerColor : std::optional(); }, - state->collectible.value(), + state->collectible.value() | rpl::map([]( + const std::optional &value) { + return value ? value->collectibleId : 0; + }), false, rpl::single(uint64(0)), switchToNextTab); @@ -2179,6 +2184,8 @@ void EditPeerProfileColorSection( std::shared_ptr style, std::shared_ptr theme, Fn aboutCallback) { + Expects(peer->isSelf()); + ProcessButton(button); const auto preview = CreateProfilePreview(box, container, show, peer); @@ -2189,7 +2196,7 @@ void EditPeerProfileColorSection( struct State { rpl::variable index = kUnsetColorIndex; rpl::variable patternEmojiId; - rpl::variable> collectible; + rpl::variable wearable; rpl::variable showingGiftId; rpl::variable selectedGiftId; std::shared_ptr buyCollectible; @@ -2197,14 +2204,12 @@ void EditPeerProfileColorSection( }; const auto state = button->lifetime().make_state(); state->patternEmojiId = peer->profileBackgroundEmojiId(); - state->collectible = peer->colorCollectible() - ? *peer->colorCollectible() - : std::optional(); + state->wearable = peer->emojiStatusId(); const auto resetUnique = [=] { preview->setLocalEmojiStatusId({}); state->buyCollectible = nullptr; - state->collectible.force_assign(std::nullopt); + state->wearable = {}; }; const auto setIndex = [=](uint8 index) { @@ -2215,7 +2220,9 @@ void EditPeerProfileColorSection( preview->setPatternEmojiId(index == kUnsetColorIndex ? std::nullopt : std::make_optional(state->patternEmojiId.current())); - resetUnique(); + if (index != kUnsetColorIndex) { + resetUnique(); + } }; setIndex(peer->colorProfileIndex().value_or(kUnsetColorIndex)); @@ -2323,17 +2330,16 @@ void EditPeerProfileColorSection( && selected->starsForResale > 0) ? selected : nullptr; - state->collectible = selected->peerColor - ? *selected->peerColor - : std::optional(); + const auto statuses = &peer->owner().emojiStatuses(); + state->wearable = statuses->fromUniqueGift(*selected); preview->setColorProfileIndex(std::nullopt); preview->setPatternEmojiId(selected->pattern.document->id); - preview->setLocalEmojiStatusId( - session->data().emojiStatuses().fromUniqueGift( - *selected)); + preview->setLocalEmojiStatusId(state->wearable.current()); resetWrap->toggle(true, anim::type::normal); }, - state->collectible.value(), + state->wearable.value() | rpl::map([=](const EmojiStatusId &value) { + return value.collectible ? value.collectible->id : 0; + }), true, state->selectedGiftId.value(), switchToNextTab); @@ -2350,13 +2356,19 @@ void EditPeerProfileColorSection( } else if (ShowPremiumPreview(show, peer)) { return; } + const auto statusId = peer->emojiStatusId(); + const auto wearable = state->wearable.current(); + const auto statusChanged = wearable.collectible + ? (!statusId.collectible + || statusId.collectible->id != wearable.collectible->id) + : (statusId.collectible != nullptr); const auto values = SetValues{ .colorIndex = state->index.current(), .backgroundEmojiId = state->patternEmojiId.current(), - .colorCollectible = state->collectible.current(), - .statusId = {}, + .colorCollectible = std::nullopt, + .statusId = state->wearable.current(), .statusUntil = 0, - .statusChanged = false, + .statusChanged = statusChanged, .forProfile = true, }; if (const auto buy = state->buyCollectible) { @@ -2379,15 +2391,17 @@ void EditPeerProfileColorSection( profileState->applying = false; })); }); - state->collectible.value( - ) | rpl::start_with_next([=] { + state->wearable.value( + ) | rpl::start_with_next([=](EmojiStatusId id) { const auto buy = state->buyCollectible.get(); while (!button->children().isEmpty()) { delete button->children().first(); } if (!buy) { button->setText(rpl::combine( - tr::lng_settings_color_apply(), + (id.collectible + ? tr::lng_settings_color_wear() + : tr::lng_settings_color_apply()), Data::AmPremiumValue(&peer->session()) ) | rpl::map([=](const QString &text, bool premium) { auto result = TextWithEntities();