Partially support correct rounding near unwrapped media.

This commit is contained in:
John Preston 2022-10-04 11:10:17 +04:00
parent 83008fa358
commit 1e8dfb7315
12 changed files with 107 additions and 32 deletions

View File

@ -889,8 +889,8 @@ void InnerWidget::itemsAdded(Direction direction, int addedCount) {
const auto previous = _items[i].get(); const auto previous = _items[i].get();
view->setDisplayDate(view->dateTime().date() != previous->dateTime().date()); view->setDisplayDate(view->dateTime().date() != previous->dateTime().date());
const auto attach = view->computeIsAttachToPrevious(previous); const auto attach = view->computeIsAttachToPrevious(previous);
view->setAttachToPrevious(attach); view->setAttachToPrevious(attach, previous);
previous->setAttachToNext(attach); previous->setAttachToNext(attach, view);
} else { } else {
view->setDisplayDate(true); view->setDisplayDate(true);
} }

View File

@ -174,8 +174,8 @@ const char kOptionAutoScrollInactiveChat[] =
namespace { namespace {
constexpr auto kMessagesPerPageFirst = 30; constexpr auto kMessagesPerPageFirst = 10;
constexpr auto kMessagesPerPage = 50; constexpr auto kMessagesPerPage = 10;
constexpr auto kPreloadHeightsCount = 3; // when 3 screens to scroll left make a preload request constexpr auto kPreloadHeightsCount = 3; // when 3 screens to scroll left make a preload request
constexpr auto kScrollToVoiceAfterScrolledMs = 1000; constexpr auto kScrollToVoiceAfterScrolledMs = 1000;
constexpr auto kSkipRepaintWhileScrollMs = 100; constexpr auto kSkipRepaintWhileScrollMs = 100;

View File

@ -368,8 +368,11 @@ Element::Element(
? QDateTime() ? QDateTime()
: ItemDateTime(data)) : ItemDateTime(data))
, _text(st::msgMinWidth) , _text(st::msgMinWidth)
, _isScheduledUntilOnline(IsItemScheduledUntilOnline(data)) , _flags(serviceFlag
, _flags(serviceFlag | Flag::NeedsResize) | Flag::NeedsResize
| (IsItemScheduledUntilOnline(data)
? Flag::ScheduledUntilOnline
: Flag()))
, _context(delegate->elementContext()) { , _context(delegate->elementContext()) {
history()->owner().registerItemView(this); history()->owner().registerItemView(this);
refreshMedia(replacing); refreshMedia(replacing);
@ -546,6 +549,14 @@ bool Element::isAttachedToNext() const {
return _flags & Flag::AttachedToNext; return _flags & Flag::AttachedToNext;
} }
bool Element::isBubbleAttachedToPrevious() const {
return _flags & Flag::BubbleAttachedToPrevious;
}
bool Element::isBubbleAttachedToNext() const {
return _flags & Flag::BubbleAttachedToNext;
}
int Element::skipBlockWidth() const { int Element::skipBlockWidth() const {
return st::msgDateSpace + infoWidth() - st::msgDateDelta.x(); return st::msgDateSpace + infoWidth() - st::msgDateDelta.x();
} }
@ -883,11 +894,12 @@ void Element::recountAttachToPreviousInBlocks() {
return; return;
} }
auto attachToPrevious = false; auto attachToPrevious = false;
if (const auto previous = previousDisplayedInBlocks()) { const auto previous = previousDisplayedInBlocks();
if (previous) {
attachToPrevious = computeIsAttachToPrevious(previous); attachToPrevious = computeIsAttachToPrevious(previous);
previous->setAttachToNext(attachToPrevious); previous->setAttachToNext(attachToPrevious, this);
} }
setAttachToPrevious(attachToPrevious); setAttachToPrevious(attachToPrevious, previous);
} }
void Element::recountDisplayDateInBlocks() { void Element::recountDisplayDateInBlocks() {
@ -925,7 +937,8 @@ void Element::setDisplayDate(bool displayDate) {
const auto item = data(); const auto item = data();
if (displayDate && !Has<DateBadge>()) { if (displayDate && !Has<DateBadge>()) {
AddComponents(DateBadge::Bit()); AddComponents(DateBadge::Bit());
Get<DateBadge>()->init(ItemDateText(item, _isScheduledUntilOnline)); Get<DateBadge>()->init(
ItemDateText(item, (_flags & Flag::ScheduledUntilOnline)));
setPendingResize(); setPendingResize();
} else if (!displayDate && Has<DateBadge>()) { } else if (!displayDate && Has<DateBadge>()) {
RemoveComponents(DateBadge::Bit()); RemoveComponents(DateBadge::Bit());
@ -933,22 +946,50 @@ void Element::setDisplayDate(bool displayDate) {
} }
} }
void Element::setAttachToNext(bool attachToNext) { void Element::setAttachToNext(bool attachToNext, Element *next) {
Expects(next || !attachToNext);
auto pending = false;
if (attachToNext && !(_flags & Flag::AttachedToNext)) { if (attachToNext && !(_flags & Flag::AttachedToNext)) {
_flags |= Flag::AttachedToNext; _flags |= Flag::AttachedToNext;
setPendingResize(); pending = true;
} else if (!attachToNext && (_flags & Flag::AttachedToNext)) { } else if (!attachToNext && (_flags & Flag::AttachedToNext)) {
_flags &= ~Flag::AttachedToNext; _flags &= ~Flag::AttachedToNext;
pending = true;
}
const auto bubble = attachToNext && !next->unwrapped();
if (bubble && !(_flags & Flag::BubbleAttachedToNext)) {
_flags |= Flag::BubbleAttachedToNext;
pending = true;
} else if (!bubble && (_flags & Flag::BubbleAttachedToNext)) {
_flags &= ~Flag::BubbleAttachedToNext;
pending = true;
}
if (pending) {
setPendingResize(); setPendingResize();
} }
} }
void Element::setAttachToPrevious(bool attachToPrevious) { void Element::setAttachToPrevious(bool attachToPrevious, Element *previous) {
Expects(previous || !attachToPrevious);
auto pending = false;
if (attachToPrevious && !(_flags & Flag::AttachedToPrevious)) { if (attachToPrevious && !(_flags & Flag::AttachedToPrevious)) {
_flags |= Flag::AttachedToPrevious; _flags |= Flag::AttachedToPrevious;
setPendingResize(); pending = true;
} else if (!attachToPrevious && (_flags & Flag::AttachedToPrevious)) { } else if (!attachToPrevious && (_flags & Flag::AttachedToPrevious)) {
_flags &= ~Flag::AttachedToPrevious; _flags &= ~Flag::AttachedToPrevious;
pending = true;
}
const auto bubble = attachToPrevious && !previous->unwrapped();
if (bubble && !(_flags & Flag::BubbleAttachedToPrevious)) {
_flags |= Flag::BubbleAttachedToPrevious;
pending = true;
} else if (!bubble && (_flags & Flag::BubbleAttachedToPrevious)) {
_flags &= ~Flag::BubbleAttachedToPrevious;
pending = true;
}
if (pending) {
setPendingResize(); setPendingResize();
} }
} }
@ -985,6 +1026,10 @@ bool Element::hasBubble() const {
return false; return false;
} }
bool Element::unwrapped() const {
return true;
}
bool Element::hasFastReply() const { bool Element::hasFastReply() const {
return false; return false;
} }

View File

@ -240,14 +240,17 @@ class Element
, public ClickHandlerHost , public ClickHandlerHost
, public base::has_weak_ptr { , public base::has_weak_ptr {
public: public:
enum class Flag : uchar { enum class Flag : uint16 {
ServiceMessage = 0x01, ServiceMessage = 0x0001,
NeedsResize = 0x02, NeedsResize = 0x0002,
AttachedToPrevious = 0x04, AttachedToPrevious = 0x0004,
AttachedToNext = 0x08, AttachedToNext = 0x0008,
HiddenByGroup = 0x10, BubbleAttachedToPrevious = 0x0010,
SpecialOnlyEmoji = 0x20, BubbleAttachedToNext = 0x0020,
CustomEmojiRepainting = 0x40, HiddenByGroup = 0x0040,
SpecialOnlyEmoji = 0x0080,
CustomEmojiRepainting = 0x0100,
ScheduledUntilOnline = 0x0200,
}; };
using Flags = base::flags<Flag>; using Flags = base::flags<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; } friend inline constexpr auto is_flag_type(Flag) { return true; }
@ -281,6 +284,8 @@ public:
[[nodiscard]] bool isAttachedToPrevious() const; [[nodiscard]] bool isAttachedToPrevious() const;
[[nodiscard]] bool isAttachedToNext() const; [[nodiscard]] bool isAttachedToNext() const;
[[nodiscard]] bool isBubbleAttachedToPrevious() const;
[[nodiscard]] bool isBubbleAttachedToNext() const;
[[nodiscard]] int skipBlockWidth() const; [[nodiscard]] int skipBlockWidth() const;
[[nodiscard]] int skipBlockHeight() const; [[nodiscard]] int skipBlockHeight() const;
@ -304,11 +309,11 @@ public:
[[nodiscard]] Ui::Text::OnlyCustomEmoji onlyCustomEmoji() const; [[nodiscard]] Ui::Text::OnlyCustomEmoji onlyCustomEmoji() const;
// For blocks context this should be called only from recountAttachToPreviousInBlocks(). // For blocks context this should be called only from recountAttachToPreviousInBlocks().
void setAttachToPrevious(bool attachToNext); void setAttachToPrevious(bool attachToNext, Element *previous = nullptr);
// For blocks context this should be called only from recountAttachToPreviousInBlocks() // For blocks context this should be called only from recountAttachToPreviousInBlocks()
// of the next item or when the next item is removed through nextInBlocksRemoved() call. // of the next item or when the next item is removed through nextInBlocksRemoved() call.
void setAttachToNext(bool attachToNext); void setAttachToNext(bool attachToNext, Element *next = nullptr);
// For blocks context this should be called only from recountDisplayDate(). // For blocks context this should be called only from recountDisplayDate().
void setDisplayDate(bool displayDate); void setDisplayDate(bool displayDate);
@ -369,6 +374,7 @@ public:
[[nodiscard]] virtual bool hasOutLayout() const; [[nodiscard]] virtual bool hasOutLayout() const;
[[nodiscard]] virtual bool drawBubble() const; [[nodiscard]] virtual bool drawBubble() const;
[[nodiscard]] virtual bool hasBubble() const; [[nodiscard]] virtual bool hasBubble() const;
[[nodiscard]] virtual bool unwrapped() const;
[[nodiscard]] virtual int minWidthForMedia() const { [[nodiscard]] virtual int minWidthForMedia() const {
return 0; return 0;
} }
@ -523,9 +529,8 @@ private:
int _y = 0; int _y = 0;
int _indexInBlock = -1; int _indexInBlock = -1;
bool _isScheduledUntilOnline = false;
mutable bool _heavyCustomEmoji = false;
mutable Flags _flags = Flag(0); mutable Flags _flags = Flag(0);
mutable bool _heavyCustomEmoji = false;
Context _context = Context(); Context _context = Context();
}; };

View File

@ -3358,8 +3358,8 @@ void ListWidget::refreshAttachmentsFromTill(int from, int till) {
const auto nextDate = next->dateTime(); const auto nextDate = next->dateTime();
next->setDisplayDate(nextDate.date() != viewDate.date()); next->setDisplayDate(nextDate.date() != viewDate.date());
auto attached = next->computeIsAttachToPrevious(view); auto attached = next->computeIsAttachToPrevious(view);
next->setAttachToPrevious(attached); next->setAttachToPrevious(attached, view);
view->setAttachToNext(attached); view->setAttachToNext(attached, next);
view = next; view = next;
} }
} }

View File

@ -2635,6 +2635,19 @@ bool Message::hasBubble() const {
return drawBubble(); return drawBubble();
} }
bool Message::unwrapped() const {
const auto item = message();
if (isHidden()) {
return true;
} else if (logEntryOriginal()) {
return false;
}
const auto media = this->media();
return media
? (!hasVisibleText() && media->unwrapped())
: item->isEmpty();
}
int Message::minWidthForMedia() const { int Message::minWidthForMedia() const {
auto result = infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()); auto result = infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x());
const auto views = data()->Get<HistoryMessageViews>(); const auto views = data()->Get<HistoryMessageViews>();
@ -3099,8 +3112,8 @@ QRect Message::countGeometry() const {
} }
Ui::BubbleRounding Message::countMessageRounding() const { Ui::BubbleRounding Message::countMessageRounding() const {
const auto smallTop = isAttachedToPrevious(); const auto smallTop = isBubbleAttachedToPrevious();
const auto smallBottom = isAttachedToNext(); const auto smallBottom = isBubbleAttachedToNext();
const auto media = smallBottom ? nullptr : this->media(); const auto media = smallBottom ? nullptr : this->media();
const auto keyboard = data()->inlineReplyKeyboard(); const auto keyboard = data()->inlineReplyKeyboard();
const auto skipTail = smallBottom const auto skipTail = smallBottom

View File

@ -118,6 +118,7 @@ public:
bool hasOutLayout() const override; bool hasOutLayout() const override;
bool drawBubble() const override; bool drawBubble() const override;
bool hasBubble() const override; bool hasBubble() const override;
bool unwrapped() const override;
int minWidthForMedia() const override; int minWidthForMedia() const override;
bool hasFastReply() const override; bool hasFastReply() const override;
bool displayFastReply() const override; bool displayFastReply() const override;

View File

@ -1252,6 +1252,10 @@ bool Gif::needsBubble() const {
return false; return false;
} }
bool Gif::unwrapped() const {
return isUnwrapped();
}
QRect Gif::contentRectForReactions() const { QRect Gif::contentRectForReactions() const {
if (!isUnwrapped()) { if (!isUnwrapped()) {
return QRect(0, 0, width(), height()); return QRect(0, 0, width(), height());

View File

@ -93,6 +93,7 @@ public:
return _caption.toTextWithEntities(); return _caption.toTextWithEntities();
} }
bool needsBubble() const override; bool needsBubble() const override;
bool unwrapped() const override;
bool customInfoLayout() const override { bool customInfoLayout() const override {
return _caption.isEmpty(); return _caption.isEmpty();
} }

View File

@ -209,6 +209,9 @@ public:
return TextWithEntities(); return TextWithEntities();
} }
[[nodiscard]] virtual bool needsBubble() const = 0; [[nodiscard]] virtual bool needsBubble() const = 0;
[[nodiscard]] virtual bool unwrapped() const {
return false;
}
[[nodiscard]] virtual bool customInfoLayout() const = 0; [[nodiscard]] virtual bool customInfoLayout() const = 0;
[[nodiscard]] virtual QRect contentRectForReactions() const { [[nodiscard]] virtual QRect contentRectForReactions() const {
return QRect(0, 0, width(), height()); return QRect(0, 0, width(), height());

View File

@ -85,6 +85,9 @@ public:
bool needsBubble() const override { bool needsBubble() const override {
return false; return false;
} }
bool unwrapped() const override {
return true;
}
bool customInfoLayout() const override { bool customInfoLayout() const override {
return true; return true;
} }

View File

@ -514,8 +514,8 @@ void ConfirmContactBox::prepare() {
auto maxWidth = 0; auto maxWidth = 0;
if (_comment) { if (_comment) {
_comment->setAttachToNext(true); _comment->setAttachToNext(true, _contact.get());
_contact->setAttachToPrevious(true); _contact->setAttachToPrevious(true, _comment.get());
_comment->initDimensions(); _comment->initDimensions();
accumulate_max(maxWidth, _comment->maxWidth()); accumulate_max(maxWidth, _comment->maxWidth());
} }