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();
view->setDisplayDate(view->dateTime().date() != previous->dateTime().date());
const auto attach = view->computeIsAttachToPrevious(previous);
view->setAttachToPrevious(attach);
previous->setAttachToNext(attach);
view->setAttachToPrevious(attach, previous);
previous->setAttachToNext(attach, view);
} else {
view->setDisplayDate(true);
}

View File

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

View File

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

View File

@ -240,14 +240,17 @@ class Element
, public ClickHandlerHost
, public base::has_weak_ptr {
public:
enum class Flag : uchar {
ServiceMessage = 0x01,
NeedsResize = 0x02,
AttachedToPrevious = 0x04,
AttachedToNext = 0x08,
HiddenByGroup = 0x10,
SpecialOnlyEmoji = 0x20,
CustomEmojiRepainting = 0x40,
enum class Flag : uint16 {
ServiceMessage = 0x0001,
NeedsResize = 0x0002,
AttachedToPrevious = 0x0004,
AttachedToNext = 0x0008,
BubbleAttachedToPrevious = 0x0010,
BubbleAttachedToNext = 0x0020,
HiddenByGroup = 0x0040,
SpecialOnlyEmoji = 0x0080,
CustomEmojiRepainting = 0x0100,
ScheduledUntilOnline = 0x0200,
};
using Flags = base::flags<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }
@ -281,6 +284,8 @@ public:
[[nodiscard]] bool isAttachedToPrevious() const;
[[nodiscard]] bool isAttachedToNext() const;
[[nodiscard]] bool isBubbleAttachedToPrevious() const;
[[nodiscard]] bool isBubbleAttachedToNext() const;
[[nodiscard]] int skipBlockWidth() const;
[[nodiscard]] int skipBlockHeight() const;
@ -304,11 +309,11 @@ public:
[[nodiscard]] Ui::Text::OnlyCustomEmoji onlyCustomEmoji() const;
// 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()
// 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().
void setDisplayDate(bool displayDate);
@ -369,6 +374,7 @@ public:
[[nodiscard]] virtual bool hasOutLayout() const;
[[nodiscard]] virtual bool drawBubble() const;
[[nodiscard]] virtual bool hasBubble() const;
[[nodiscard]] virtual bool unwrapped() const;
[[nodiscard]] virtual int minWidthForMedia() const {
return 0;
}
@ -523,9 +529,8 @@ private:
int _y = 0;
int _indexInBlock = -1;
bool _isScheduledUntilOnline = false;
mutable bool _heavyCustomEmoji = false;
mutable Flags _flags = Flag(0);
mutable bool _heavyCustomEmoji = false;
Context _context = Context();
};

View File

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

View File

@ -2635,6 +2635,19 @@ bool Message::hasBubble() const {
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 {
auto result = infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x());
const auto views = data()->Get<HistoryMessageViews>();
@ -3099,8 +3112,8 @@ QRect Message::countGeometry() const {
}
Ui::BubbleRounding Message::countMessageRounding() const {
const auto smallTop = isAttachedToPrevious();
const auto smallBottom = isAttachedToNext();
const auto smallTop = isBubbleAttachedToPrevious();
const auto smallBottom = isBubbleAttachedToNext();
const auto media = smallBottom ? nullptr : this->media();
const auto keyboard = data()->inlineReplyKeyboard();
const auto skipTail = smallBottom

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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