Partially support correct rounding near unwrapped media.
This commit is contained in:
		
							parent
							
								
									83008fa358
								
							
						
					
					
						commit
						1e8dfb7315
					
				
					 12 changed files with 107 additions and 32 deletions
				
			
		|  | @ -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); | ||||
| 			} | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  |  | |||
|  | @ -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(); | ||||
| 
 | ||||
| }; | ||||
|  |  | |||
|  | @ -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; | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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()); | ||||
|  |  | |||
|  | @ -93,6 +93,7 @@ public: | |||
| 		return _caption.toTextWithEntities(); | ||||
| 	} | ||||
| 	bool needsBubble() const override; | ||||
| 	bool unwrapped() const override; | ||||
| 	bool customInfoLayout() const override { | ||||
| 		return _caption.isEmpty(); | ||||
| 	} | ||||
|  |  | |||
|  | @ -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()); | ||||
|  |  | |||
|  | @ -85,6 +85,9 @@ public: | |||
| 	bool needsBubble() const override { | ||||
| 		return false; | ||||
| 	} | ||||
| 	bool unwrapped() const override { | ||||
| 		return true; | ||||
| 	} | ||||
| 	bool customInfoLayout() const override { | ||||
| 		return true; | ||||
| 	} | ||||
|  |  | |||
|  | @ -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()); | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 John Preston
						John Preston