Allow changing album quote before sending.

This commit is contained in:
John Preston 2023-10-31 23:25:26 +04:00
parent 10022a3c6d
commit 097c3c4a5a
3 changed files with 32 additions and 20 deletions

View File

@ -99,9 +99,8 @@ public:
not_null<History*> history); not_null<History*> history);
~PreviewWrap(); ~PreviewWrap();
[[nodiscard]] rpl::producer<TextWithEntities> showQuoteSelector( [[nodiscard]] rpl::producer<SelectedQuote> showQuoteSelector(
not_null<HistoryItem*> item, const SelectedQuote &quote);
const TextWithEntities &quote);
[[nodiscard]] rpl::producer<QString> showLinkSelector( [[nodiscard]] rpl::producer<QString> showLinkSelector(
const TextWithTags &message, const TextWithTags &message,
Data::WebPageDraft webpage, Data::WebPageDraft webpage,
@ -212,13 +211,13 @@ PreviewWrap::~PreviewWrap() {
} }
} }
rpl::producer<TextWithEntities> PreviewWrap::showQuoteSelector( rpl::producer<SelectedQuote> PreviewWrap::showQuoteSelector(
not_null<HistoryItem*> item, const SelectedQuote &quote) {
const TextWithEntities &quote) {
_selection.reset(TextSelection()); _selection.reset(TextSelection());
const auto item = quote.item;
const auto group = item->history()->owner().groups().find(item); const auto group = item->history()->owner().groups().find(item);
const auto leader = group ? group->items.front() : item; const auto leader = group ? group->items.front().get() : item;
_element = leader->createView(_delegate.get()); _element = leader->createView(_delegate.get());
_link = _pressedLink = nullptr; _link = _pressedLink = nullptr;
@ -235,10 +234,13 @@ rpl::producer<TextWithEntities> PreviewWrap::showQuoteSelector(
initElement(); initElement();
_selection = _element->selectionFromQuote(item, quote); _selection = _element->selectionFromQuote(item, quote.text);
return _selection.value( return _selection.value(
) | rpl::map([=](TextSelection selection) { ) | rpl::map([=](TextSelection selection) {
return _element->selectedQuote(selection).text; if (const auto result = _element->selectedQuote(selection)) {
return result;
}
return SelectedQuote{ item };
}); });
} }
@ -586,7 +588,7 @@ void DraftOptionsBox(
struct State { struct State {
rpl::variable<Section> shown; rpl::variable<Section> shown;
rpl::lifetime shownLifetime; rpl::lifetime shownLifetime;
rpl::variable<TextWithEntities> quote; rpl::variable<SelectedQuote> quote;
Data::WebPageDraft webpage; Data::WebPageDraft webpage;
WebPageData *preview = nullptr; WebPageData *preview = nullptr;
QString link; QString link;
@ -598,7 +600,7 @@ void DraftOptionsBox(
rpl::lifetime resolveLifetime; rpl::lifetime resolveLifetime;
}; };
const auto state = box->lifetime().make_state<State>(); const auto state = box->lifetime().make_state<State>();
state->quote = draft.reply.quote; state->quote = SelectedQuote{ replyItem, draft.reply.quote };
state->webpage = draft.webpage; state->webpage = draft.webpage;
state->preview = previewData; state->preview = previewData;
state->shown = previewData ? Section::Link : Section::Reply; state->shown = previewData ? Section::Link : Section::Reply;
@ -636,8 +638,10 @@ void DraftOptionsBox(
const auto &highlight = args.highlight; const auto &highlight = args.highlight;
const auto &clearOldDraft = args.clearOldDraft; const auto &clearOldDraft = args.clearOldDraft;
const auto resolveReply = [=] { const auto resolveReply = [=] {
const auto current = state->quote.current();
auto result = draft.reply; auto result = draft.reply;
result.quote = state->quote.current(); result.messageId = current.item->fullId();
result.quote = current.text;
return result; return result;
}; };
const auto finish = [=]( const auto finish = [=](
@ -652,7 +656,8 @@ void DraftOptionsBox(
const auto setupReplyActions = [=] { const auto setupReplyActions = [=] {
AddFilledSkip(bottom); AddFilledSkip(bottom);
if (replyItem->allowsForward()) { const auto item = state->quote.current().item;
if (item->allowsForward()) {
Settings::AddButton( Settings::AddButton(
bottom, bottom,
tr::lng_reply_in_another_chat(), tr::lng_reply_in_another_chat(),
@ -679,7 +684,7 @@ void DraftOptionsBox(
finish({}, state->webpage); finish({}, state->webpage);
}); });
if (!replyItem->originalText().empty()) { if (!item->originalText().empty()) {
AddFilledSkip(bottom); AddFilledSkip(bottom);
Settings::AddDividerText( Settings::AddDividerText(
bottom, bottom,
@ -808,7 +813,6 @@ void DraftOptionsBox(
state->shownLifetime.destroy(); state->shownLifetime.destroy();
if (shown == Section::Reply) { if (shown == Section::Reply) {
state->quote = state->wrap->showQuoteSelector( state->quote = state->wrap->showQuoteSelector(
replyItem,
state->quote.current()); state->quote.current());
setupReplyActions(); setupReplyActions();
} else { } else {
@ -827,8 +831,8 @@ void DraftOptionsBox(
auto save = rpl::combine( auto save = rpl::combine(
state->quote.value(), state->quote.value(),
state->shown.value() state->shown.value()
) | rpl::map([=](const TextWithEntities &quote, Section shown) { ) | rpl::map([=](const SelectedQuote &quote, Section shown) {
return (quote.empty() || shown != Section::Reply) return (quote.text.empty() || shown != Section::Reply)
? tr::lng_settings_save() ? tr::lng_settings_save()
: tr::lng_reply_quote_selected(); : tr::lng_reply_quote_selected();
}) | rpl::flatten_latest(); }) | rpl::flatten_latest();
@ -843,14 +847,20 @@ void DraftOptionsBox(
if (replyItem) { if (replyItem) {
args.show->session().data().itemRemoved( args.show->session().data().itemRemoved(
) | rpl::filter([=](not_null<const HistoryItem*> removed) { ) | rpl::filter([=](not_null<const HistoryItem*> removed) {
return removed == replyItem; const auto current = state->quote.current().item;
if ((removed == replyItem) || (removed == current)) {
return true;
}
const auto group = current->history()->owner().groups().find(
current);
return (group && ranges::contains(group->items, removed));
}) | rpl::start_with_next([=] { }) | rpl::start_with_next([=] {
if (previewData) { if (previewData) {
state->tabs = nullptr; state->tabs = nullptr;
box->setPinnedToTopContent( box->setPinnedToTopContent(
object_ptr<Ui::RpWidget>(nullptr)); object_ptr<Ui::RpWidget>(nullptr));
box->setNoContentMargin(false); box->setNoContentMargin(false);
box->setTitle(state->quote.current().empty() box->setTitle(state->quote.current().text.empty()
? tr::lng_reply_options_header() ? tr::lng_reply_options_header()
: tr::lng_reply_options_quote()); : tr::lng_reply_options_quote());
state->shown = Section::Link; state->shown = Section::Link;

View File

@ -273,6 +273,7 @@ struct SelectedQuote {
explicit operator bool() const { explicit operator bool() const {
return item && !text.empty(); return item && !text.empty();
} }
friend inline bool operator==(SelectedQuote, SelectedQuote) = default;
}; };
class Element class Element

View File

@ -343,6 +343,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
? Ui::BubbleRounding{ kSmall, kSmall, kSmall, kSmall } ? Ui::BubbleRounding{ kSmall, kSmall, kSmall, kSmall }
: adjustedBubbleRoundingWithCaption(_caption); : adjustedBubbleRoundingWithCaption(_caption);
auto highlight = context.highlight.range; auto highlight = context.highlight.range;
const auto subpartHighlight = IsSubGroupSelection(highlight);
for (auto i = 0, count = int(_parts.size()); i != count; ++i) { for (auto i = 0, count = int(_parts.size()); i != count; ++i) {
const auto &part = _parts[i]; const auto &part = _parts[i];
auto partContext = context.withSelection(fullSelection auto partContext = context.withSelection(fullSelection
@ -363,7 +364,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
if (textSelection) { if (textSelection) {
selection = part.content->skipSelection(selection); selection = part.content->skipSelection(selection);
} }
if (!highlighted) { if (!subpartHighlight) {
highlight = part.content->skipSelection(highlight); highlight = part.content->skipSelection(highlight);
} }
if (!part.cache.isNull()) { if (!part.cache.isNull()) {