Improve 5-line reply text elision.

This commit is contained in:
John Preston 2023-11-06 12:35:27 +04:00
parent d7539349c7
commit b2eeab53c5
15 changed files with 65 additions and 57 deletions

View file

@ -420,7 +420,7 @@ void PaintRow(
.now = context.now,
.pausedEmoji = context.paused || On(PowerSaving::kEmojiChat),
.pausedSpoiler = context.paused || On(PowerSaving::kChatSpoiler),
.elisionOneLine = true,
.elisionLines = 1,
});
} else if (draft
|| (supportMode
@ -514,7 +514,7 @@ void PaintRow(
.now = context.now,
.pausedEmoji = context.paused || On(PowerSaving::kEmojiChat),
.pausedSpoiler = context.paused || On(PowerSaving::kChatSpoiler),
.elisionOneLine = true,
.elisionLines = 1,
});
}
} else if (!item) {

View file

@ -141,7 +141,7 @@ void TopicsView::paint(
.now = context.now,
.pausedEmoji = context.paused || On(PowerSaving::kEmojiChat),
.pausedSpoiler = context.paused || On(PowerSaving::kChatSpoiler),
.elisionOneLine = true,
.elisionLines = 1,
});
const auto skip = skipBig
? context.st->topicsSkipBig

View file

@ -3349,13 +3349,15 @@ void HistoryItem::createComponentsHelper(
: (replyTo.messageId.peer == history()->peer->id)
? replyTo.messageId.msg
: MsgId();
const auto forum = _history->asForum();
const auto topic = forum
? forum->topicFor(replyTo.topicRootId)
: nullptr;
if (!config.reply.externalPeerId
&& to
&& config.reply.topicPost
&& replyTo.topicRootId != to->topicRootId()) {
&& topic
&& topic->rootId() != to->topicRootId()) {
config.reply.externalPeerId = replyTo.messageId.peer;
}
const auto forum = _history->asForum();
config.reply.topicPost = config.reply.externalPeerId
? (replyTo.topicRootId
&& (replyTo.topicRootId != Data::ForumTopic::kGeneralId))

View file

@ -424,12 +424,14 @@ bool HistoryMessageReply::updateData(
}
}
const auto external = this->external();
_multiline = !_fields.storyId && (external || !_fields.quote.empty());
const auto asExternal = displayAsExternal(holder);
const auto nonEmptyQuote = !_fields.quote.empty()
&& (asExternal || _fields.manualQuote);
_multiline = !_fields.storyId && (asExternal || nonEmptyQuote);
const auto displaying = resolvedMessage
|| resolvedStory
|| ((!_fields.quote.empty() || _fields.externalMedia)
|| ((nonEmptyQuote || _fields.externalMedia)
&& (!_fields.messageId || force));
_displaying = displaying ? 1 : 0;
@ -446,7 +448,7 @@ bool HistoryMessageReply::updateData(
}
return resolvedMessage
|| resolvedStory
|| (external && !_fields.messageId && !_fields.storyId)
|| (!_fields.messageId && !_fields.storyId && external())
|| _unavailable;
}
@ -508,6 +510,15 @@ bool HistoryMessageReply::external() const {
|| !_fields.externalSenderName.isEmpty();
}
bool HistoryMessageReply::displayAsExternal(
not_null<HistoryItem*> holder) const {
// Don't display replies that could be local as external.
return external()
&& (!resolvedMessage
|| (holder->history() != resolvedMessage->history())
|| (holder->topicRootId() != resolvedMessage->topicRootId()));
}
void HistoryMessageReply::itemRemoved(
not_null<HistoryItem*> holder,
not_null<HistoryItem*> removed) {

View file

@ -279,6 +279,8 @@ struct HistoryMessageReply
void clearData(not_null<HistoryItem*> holder);
[[nodiscard]] bool external() const;
[[nodiscard]] bool displayAsExternal(
not_null<HistoryItem*> holder) const;
void itemRemoved(
not_null<HistoryItem*> holder,
not_null<HistoryItem*> removed);

View file

@ -7951,7 +7951,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
.now = now,
.pausedEmoji = paused || On(PowerSaving::kEmojiChat),
.pausedSpoiler = pausedSpoiler,
.elisionOneLine = true,
.elisionLines = 1,
});
} else {
p.setFont(st::msgDateFont);

View file

@ -629,7 +629,7 @@ void FieldHeader::paintEditOrReplyToMessage(Painter &p) {
.now = crl::now(),
.pausedEmoji = p.inactive() || On(PowerSaving::kEmojiChat),
.pausedSpoiler = p.inactive() || On(PowerSaving::kChatSpoiler),
.elisionOneLine = true,
.elisionLines = 1,
});
}

View file

@ -669,6 +669,7 @@ void DraftOptionsBox(
});
}
const auto weak = Ui::MakeWeak(box);
Settings::AddButton(
bottom,
tr::lng_reply_show_in_chat(),
@ -676,6 +677,9 @@ void DraftOptionsBox(
{ &st::menuIconShowInChat }
)->setClickedCallback([=] {
highlight(resolveReply());
if (const auto strong = weak.data()) {
strong->closeBox();
}
});
Settings::AddButton(

View file

@ -396,7 +396,7 @@ void ForwardPanel::paint(
.now = now,
.pausedEmoji = paused || On(PowerSaving::kEmojiChat),
.pausedSpoiler = pausedSpoiler,
.elisionOneLine = true,
.elisionLines = 1,
});
}

View file

@ -210,10 +210,10 @@ void Reply::update(
const auto text = (!_displaying && data->unavailable())
? TextWithEntities()
: (message && (fields.quote.empty() || !fields.manualQuote))
? message->inReplyText()
: !fields.quote.empty()
? fields.quote
: message
? message->inReplyText()
: story
? story->inReplyText()
: externalMedia
@ -400,7 +400,9 @@ void Reply::updateName(
const auto externalPeer = fields.externalPeerId
? view->history()->owner().peer(fields.externalPeerId).get()
: nullptr;
const auto groupNameAdded = externalPeer
const auto displayAsExternal = data->displayAsExternal(view->data());
const auto groupNameAdded = displayAsExternal
&& externalPeer
&& (externalPeer != sender)
&& (externalPeer->isChat() || externalPeer->isMegagroup());
const auto shorten = !viaBotUsername.isEmpty() || groupNameAdded;
@ -433,7 +435,7 @@ void Reply::updateName(
icon.second));
};
auto nameFull = TextWithEntities();
if (!groupNameAdded && data->external() && !fields.storyId) {
if (displayAsExternal && !groupNameAdded && !fields.storyId) {
nameFull.append(peerEmoji(sender));
}
nameFull.append(name);
@ -509,7 +511,7 @@ int Reply::resizeToWidth(int width) const {
: 0;
if (width >= _maxWidth || !_multiline) {
_nameTwoLines = 0;
_expandable = 0;
_expandable = _minHeightExpandable;
_height = _minHeight;
return height();
}
@ -521,20 +523,13 @@ int Reply::resizeToWidth(int width) const {
_nameTwoLines = (desiredNameHeight > st::semiboldFont->height) ? 1 : 0;
const auto nameh = (_nameTwoLines ? 2 : 1) * st::semiboldFont->height;
const auto firstLineSkip = _nameTwoLines ? 0 : previewSkip;
auto lineCounter = 0;
auto elided = false;
const auto texth = _text.countDimensions(
textGeometry(innerw, firstLineSkip, &lineCounter, &elided)).height;
const auto useh = elided
? (kNonExpandedLinesLimit * st::normalFont->height)
: std::max(texth, st::normalFont->height);
if (!texth) {
int a = 0;
}
_expandable = (_multiline && elided) ? 1 : 0;
textGeometry(innerw, firstLineSkip, &elided)).height;
_expandable = elided ? 1 : 0;
_height = st::historyReplyPadding.top()
+ nameh
+ useh
+ std::max(texth, st::normalFont->height)
+ st::historyReplyPadding.bottom();
return height();
}
@ -542,21 +537,17 @@ int Reply::resizeToWidth(int width) const {
Ui::Text::GeometryDescriptor Reply::textGeometry(
int available,
int firstLineSkip,
not_null<int*> line,
not_null<bool*> outElided) const {
return { .layout = [=](Ui::Text::LineGeometry in) {
const auto skip = (*line ? 0 : firstLineSkip);
++*line;
*outElided = *outElided
|| !_multiline
|| (!_expanded
&& (*line == kNonExpandedLinesLimit)
&& in.width > available - skip);
in.width = available - skip;
in.left += skip;
in.elided = *outElided;
return in;
} };
bool *outElided) const {
return { .layout = [=](int line) {
const auto skip = (line ? 0 : firstLineSkip);
const auto elided = !_multiline
|| (!_expanded && (line + 1 >= kNonExpandedLinesLimit));
return Ui::Text::LineGeometry{
.left = skip,
.width = available - skip,
.elided = elided,
};
}, .outElided = outElided };
}
int Reply::height() const {
@ -570,10 +561,10 @@ QMargins Reply::margins() const {
QSize Reply::countMultilineOptimalSize(
int previewSkip) const {
auto elided = false;
auto lineCounter = 0;
const auto max = previewSkip + _text.maxWidth();
const auto result = _text.countDimensions(
textGeometry(max, previewSkip, &lineCounter, &elided));
textGeometry(max, previewSkip, &elided));
_minHeightExpandable = elided ? 1 : 0;
return {
result.width,
std::max(result.height, st::normalFont->height),
@ -767,18 +758,16 @@ void Reply::paint(
copy->linkFg = owned->color();
replyToTextPalette = &*copy;
}
auto l = 0;
auto e = false;
_text.draw(p, {
.position = { textLeft, textTop },
.geometry = textGeometry(textw, firstLineSkip, &l, &e),
.geometry = textGeometry(textw, firstLineSkip),
.palette = replyToTextPalette,
.spoiler = Ui::Text::DefaultSpoilerCache(),
.now = context.now,
.pausedEmoji = (context.paused
|| On(PowerSaving::kEmojiChat)),
.pausedSpoiler = pausedSpoiler,
.elisionOneLine = true,
.elisionLines = 1,
});
p.setTextPalette(stm->textPalette);
}

View file

@ -67,8 +67,7 @@ private:
[[nodiscard]] Ui::Text::GeometryDescriptor textGeometry(
int available,
int firstLineSkip,
not_null<int*> line,
not_null<bool*> outElided) const;
bool *outElided = nullptr) const;
[[nodiscard]] QSize countMultilineOptimalSize(
int firstLineSkip) const;
void setLinkFrom(
@ -101,11 +100,12 @@ private:
mutable int _minHeight = 0;
mutable int _height = 0;
mutable int _nameVersion = 0;
uint8 _hiddenSenderColorIndexPlusOne = 0;
uint8 _hiddenSenderColorIndexPlusOne : 7 = 0;
uint8 _hasQuoteIcon : 1 = 0;
uint8 _replyToStory : 1 = 0;
uint8 _expanded : 1 = 0;
mutable uint8 _expandable : 1 = 0;
mutable uint8 _minHeightExpandable : 1 = 0;
mutable uint8 _nameTwoLines : 1 = 0;
mutable uint8 _hasPreview : 1 = 0;
mutable uint8 _displaying : 1 = 0;

View file

@ -388,7 +388,7 @@ void Giveaway::paintChannels(
.align = style::al_left,
.palette = &stm->textPalette,
.now = context.now,
.elisionOneLine = true,
.elisionLines = 1,
.elisionBreakEverywhere = true,
});
}

View file

@ -455,7 +455,7 @@ void MessageBar::paint(Painter &p) {
.now = now,
.pausedEmoji = paused || On(PowerSaving::kEmojiChat),
.pausedSpoiler = pausedSpoiler,
.elisionOneLine = true,
.elisionLines = 1,
});
}
} else if (_animation->bodyAnimation == BodyAnimation::Text) {

View file

@ -828,7 +828,7 @@ void Notification::paintTitle(Painter &p) {
.spoiler = Ui::Text::DefaultSpoilerCache(),
.pausedEmoji = On(PowerSaving::kEmojiChat),
.pausedSpoiler = On(PowerSaving::kChatSpoiler),
.elisionOneLine = true,
.elisionLines = 1,
});
}

@ -1 +1 @@
Subproject commit 08235c5e06ac56564157f2856702804a2149d45e
Subproject commit 65310f32dcc980aeca0b13253b1278a6f3ce722e