Fix channel reactions list editing.

This commit is contained in:
John Preston 2024-08-13 10:08:51 +02:00
parent 0a1ddddd81
commit 7ef44fb621
2 changed files with 58 additions and 19 deletions

View file

@ -282,6 +282,9 @@ void SetupOnlyCustomEmojiField(
const auto offset = size(); const auto offset = size();
if (unifiedId) { if (unifiedId) {
result.text.append('@'); result.text.append('@');
} else if (id.paid()) {
result.text.append(QChar(0x2B50));
unifiedId = reactions->lookupPaid()->selectAnimation->id;
} else { } else {
result.text.append(id.emoji()); result.text.append(id.emoji());
const auto i = ranges::find(all, id, &Data::Reaction::id); const auto i = ranges::find(all, id, &Data::Reaction::id);
@ -312,6 +315,7 @@ struct ReactionsSelectorArgs {
rpl::producer<QString> title; rpl::producer<QString> title;
std::vector<Data::Reaction> list; std::vector<Data::Reaction> list;
std::vector<Data::ReactionId> selected; std::vector<Data::ReactionId> selected;
rpl::producer<bool> paid;
Fn<void(std::vector<Data::ReactionId>, bool)> callback; Fn<void(std::vector<Data::ReactionId>, bool)> callback;
rpl::producer<ReactionsSelectorState> stateValue; rpl::producer<ReactionsSelectorState> stateValue;
int customAllowed = 0; int customAllowed = 0;
@ -341,13 +345,18 @@ object_ptr<Ui::RpWidget> AddReactionsSelector(
std::unique_ptr<UnifiedFactoryOwner> unifiedFactoryOwner; std::unique_ptr<UnifiedFactoryOwner> unifiedFactoryOwner;
UnifiedFactoryOwner::RecentFactory factory; UnifiedFactoryOwner::RecentFactory factory;
base::flat_set<DocumentId> allowed; base::flat_set<DocumentId> allowed;
std::vector<Data::ReactionId> reactions;
rpl::lifetime focusLifetime; rpl::lifetime focusLifetime;
}; };
const auto paid = reactions->lookupPaid();
auto normal = reactions->list(Data::Reactions::Type::Active);
normal.push_back(*paid);
const auto state = raw->lifetime().make_state<State>(); const auto state = raw->lifetime().make_state<State>();
state->unifiedFactoryOwner = std::make_unique<UnifiedFactoryOwner>( state->unifiedFactoryOwner = std::make_unique<UnifiedFactoryOwner>(
session, session,
reactions->list(Data::Reactions::Type::Active)); normal);
state->factory = state->unifiedFactoryOwner->factory(); state->factory = state->unifiedFactoryOwner->factory();
state->reactions = std::move(args.selected);
const auto customEmojiPaused = [controller = args.controller] { const auto customEmojiPaused = [controller = args.controller] {
return controller->isGifPausedAtLeastFor(PauseReason::Layer); return controller->isGifPausedAtLeastFor(PauseReason::Layer);
@ -396,9 +405,32 @@ object_ptr<Ui::RpWidget> AddReactionsSelector(
state->allowed = std::move(allowed); state->allowed = std::move(allowed);
raw->rawTextEdit()->update(); raw->rawTextEdit()->update();
} }
state->reactions = reactions;
callback(std::move(reactions), hardLimitHit); callback(std::move(reactions), hardLimitHit);
}, isCustom, args.customHardLimit); }, isCustom, args.customHardLimit);
raw->setTextWithTags(ComposeEmojiList(reactions, args.selected)); const auto applyFromState = [=] {
raw->setTextWithTags(ComposeEmojiList(reactions, state->reactions));
};
applyFromState();
std::move(
args.paid
) | rpl::start_with_next([=](bool paid) {
const auto id = Data::ReactionId::Paid();
if (paid && !ranges::contains(state->reactions, id)) {
state->reactions.insert(begin(state->reactions), id);
applyFromState();
} else if (!paid && ranges::contains(state->reactions, id)) {
state->reactions.erase(
ranges::remove(state->reactions, id),
end(state->reactions));
applyFromState();
}
}, raw->lifetime());
const auto toggle = Ui::CreateChild<Ui::IconButton>(
parent.get(),
st::manageGroupReactions);
using SelectorState = ReactionsSelectorState; using SelectorState = ReactionsSelectorState;
std::move( std::move(
@ -444,10 +476,6 @@ object_ptr<Ui::RpWidget> AddReactionsSelector(
} }
}, raw->lifetime()); }, raw->lifetime());
const auto toggle = Ui::CreateChild<Ui::IconButton>(
parent.get(),
st::manageGroupReactions);
const auto panel = Ui::CreateChild<TabbedPanel>( const auto panel = Ui::CreateChild<TabbedPanel>(
args.outer.get(), args.outer.get(),
args.controller, args.controller,
@ -458,8 +486,11 @@ object_ptr<Ui::RpWidget> AddReactionsSelector(
(args.all (args.all
? TabbedSelector::Mode::FullReactions ? TabbedSelector::Mode::FullReactions
: TabbedSelector::Mode::RecentReactions))); : TabbedSelector::Mode::RecentReactions)));
panel->selector()->provideRecentEmoji( auto panelList = state->unifiedFactoryOwner->unifiedIdsList();
state->unifiedFactoryOwner->unifiedIdsList()); panelList.erase(
ranges::remove(panelList, paid->selectAnimation->id),
end(panelList));
panel->selector()->provideRecentEmoji(panelList);
panel->setDesiredHeightValues( panel->setDesiredHeightValues(
1., 1.,
st::emojiPanMinHeight / 2, st::emojiPanMinHeight / 2,
@ -608,12 +639,12 @@ void EditAllowedReactionsBox(
rpl::variable<SelectorState> selectorState; rpl::variable<SelectorState> selectorState;
std::vector<Data::ReactionId> selected; std::vector<Data::ReactionId> selected;
rpl::variable<int> customCount; rpl::variable<int> customCount;
bool paidEnabled = false; rpl::variable<bool> paidEnabled;
}; };
const auto allowed = args.allowed; const auto allowed = args.allowed;
const auto optionInitial = (allowed.type != AllowedReactionsType::Some) const auto optionInitial = (allowed.type != AllowedReactionsType::Some)
? Option::All ? Option::All
: allowed.some.empty() : (allowed.some.empty() && !allowed.paidEnabled)
? Option::None ? Option::None
: Option::Some; : Option::Some;
const auto state = box->lifetime().make_state<State>(State{ const auto state = box->lifetime().make_state<State>(State{
@ -704,13 +735,19 @@ void EditAllowedReactionsBox(
| ranges::views::transform(&Data::Reaction::id) | ranges::views::transform(&Data::Reaction::id)
| ranges::to_vector) | ranges::to_vector)
: allowed.some; : allowed.some;
if (allowed.paidEnabled) {
selected.insert(begin(selected), Data::ReactionId::Paid());
}
const auto changed = [=]( const auto changed = [=](
std::vector<Data::ReactionId> chosen, std::vector<Data::ReactionId> chosen,
bool hardLimitHit) { bool hardLimitHit) {
state->selected = std::move(chosen); state->selected = std::move(chosen);
state->customCount = ranges::count_if( state->customCount = ranges::count_if(
state->selected, state->selected,
&Data::ReactionId::custom); &Data::ReactionId::custom);
state->paidEnabled = ranges::contains(
state->selected,
Data::ReactionId::Paid());
if (hardLimitHit) { if (hardLimitHit) {
box->uiShow()->showToast( box->uiShow()->showToast(
tr::lng_manage_peer_reactions_limit(tr::now)); tr::lng_manage_peer_reactions_limit(tr::now));
@ -729,6 +766,7 @@ void EditAllowedReactionsBox(
.title = tr::lng_manage_peer_reactions_available_ph(), .title = tr::lng_manage_peer_reactions_available_ph(),
.list = all, .list = all,
.selected = state->selected, .selected = state->selected,
.paid = state->paidEnabled.value(),
.callback = changed, .callback = changed,
.stateValue = state->selectorState.value(), .stateValue = state->selectorState.value(),
.customAllowed = args.allowedCustomReactions, .customAllowed = args.allowedCustomReactions,
@ -737,7 +775,7 @@ void EditAllowedReactionsBox(
}), st::boxRowPadding); }), st::boxRowPadding);
box->setFocusCallback([=] { box->setFocusCallback([=] {
if (!wrap || state->option.current() == Option::Some) { if (state->option.current() == Option::Some) {
state->selectorState.force_assign(SelectorState::Active); state->selectorState.force_assign(SelectorState::Active);
} }
}); });
@ -855,7 +893,7 @@ void EditAllowedReactionsBox(
inner, inner,
tr::lng_manage_peer_reactions_paid(), tr::lng_manage_peer_reactions_paid(),
st::manageGroupNoIconButton.button)); st::manageGroupNoIconButton.button));
paid->toggleOn(rpl::single(allowed.paidEnabled)); paid->toggleOn(state->paidEnabled.value());
paid->toggledValue( paid->toggledValue(
) | rpl::start_with_next([=](bool value) { ) | rpl::start_with_next([=](bool value) {
state->paidEnabled = value; state->paidEnabled = value;
@ -882,7 +920,7 @@ void EditAllowedReactionsBox(
result.some = state->selected; result.some = state->selected;
} }
if (!isGroup && enabled->toggled()) { if (!isGroup && enabled->toggled()) {
result.paidEnabled = state->paidEnabled; result.paidEnabled = state->paidEnabled.current();
} }
auto some = result.some; auto some = result.some;
auto simple = all | ranges::views::transform( auto simple = all | ranges::views::transform(

View file

@ -214,20 +214,21 @@ PossibleItemReactionsRef LookupPossibleReactions(
result.tags = true; result.tags = true;
} else if (limited) { } else if (limited) {
result.recent.reserve((allowed.paidEnabled ? 1 : 0) + all.size()); result.recent.reserve((allowed.paidEnabled ? 1 : 0) + all.size());
if (allowed.paidEnabled) {
result.recent.push_back(reactions->lookupPaid());
}
add([&](const Reaction &reaction) { add([&](const Reaction &reaction) {
return ranges::contains(all, reaction.id, &MessageReaction::id); return ranges::contains(all, reaction.id, &MessageReaction::id);
}); });
for (const auto &reaction : all) { for (const auto &reaction : all) {
const auto id = reaction.id; const auto id = reaction.id;
if (!added.contains(id)) { if (added.emplace(id).second) {
if (const auto temp = reactions->lookupTemporary(id)) { if (const auto temp = reactions->lookupTemporary(id)) {
result.recent.push_back(temp); result.recent.push_back(temp);
} }
} }
} }
if (allowed.paidEnabled
&& !added.contains(Data::ReactionId::Paid())) {
result.recent.push_back(reactions->lookupPaid());
}
} else { } else {
result.recent.reserve((allowed.paidEnabled ? 1 : 0) result.recent.reserve((allowed.paidEnabled ? 1 : 0)
+ ((allowed.type == AllowedReactionsType::Some) + ((allowed.type == AllowedReactionsType::Some)