This commit is contained in:
Ali 2023-06-30 23:22:59 +02:00
parent fa52c23399
commit fa3e626f47
7 changed files with 83 additions and 20 deletions

View File

@ -2616,11 +2616,11 @@ final class MessageHistoryTable: Table {
}
}
#if DEBUG
/*#if DEBUG
for key in associatedStories.keys {
associatedStories[key] = CodableEntry(data: Data())
}
#endif
#endif*/
associatedMessageIds.append(contentsOf: attribute.associatedMessageIds)
if addAssociatedMessages {

View File

@ -99,8 +99,7 @@ final class MediaNavigationStripComponent: Component {
var validIndices: [Int] = []
if component.count != 0 {
var idealItemWidth: CGFloat = (availableSize.width - CGFloat(component.count - 1) * spacing) / CGFloat(component.count)
idealItemWidth = floor(idealItemWidth)
let idealItemWidth: CGFloat = (availableSize.width - CGFloat(component.count - 1) * spacing) / CGFloat(component.count)
let itemWidth: CGFloat
if idealItemWidth < minItemWidth {

View File

@ -562,12 +562,16 @@ public final class StoryContentContextImpl: StoryContentContext {
var sortedItems: [EngineStorySubscriptions.Item] = []
if let accountItem = storySubscriptions.accountItem {
if startedWithUnseen {
if accountItem.hasUnseen || accountItem.hasPending {
if self.fixedSubscriptionOrder.contains(context.account.peerId) {
sortedItems.append(accountItem)
} else {
if startedWithUnseen {
if accountItem.hasUnseen || accountItem.hasPending {
sortedItems.append(accountItem)
}
} else {
sortedItems.append(accountItem)
}
} else {
sortedItems.append(accountItem)
}
}
for peerId in self.fixedSubscriptionOrder {

View File

@ -464,6 +464,7 @@ public final class StoryPeerListItemComponent: Component {
}
component.contextGesture(self.extractedContainerNode, gesture, component.peer)
}
self.containerNode.additionalActivationProgressLayer = self.avatarBackgroundContainer.layer
self.extractedContainerNode.willUpdateIsExtractedToContextPreview = { [weak self] isExtracted, transition in
guard let self, let component = self.component else {
@ -545,8 +546,6 @@ public final class StoryPeerListItemComponent: Component {
}
self.avatarBackgroundView.image = avatarBackgroundImage
self.avatarBackgroundView.isHidden = component.ringAnimation != nil
if themeUpdated {
self.avatarBackgroundView.tintColor = component.theme.rootController.navigationBar.opaqueBackgroundColor
}
@ -625,7 +624,7 @@ public final class StoryPeerListItemComponent: Component {
}
avatarAddBadgeTransition.setFrame(view: avatarAddBadgeView, frame: CGRect(origin: CGPoint(x: avatarFrame.width - 1.0 - badgeSize.width, y: avatarFrame.height - 2.0 - badgeSize.height), size: badgeSize))
} else {
if indicatorColorLayer.isHidden {
if self.indicatorColorLayer.isHidden {
self.indicatorColorLayer.isHidden = false
}
@ -635,6 +634,8 @@ public final class StoryPeerListItemComponent: Component {
}
}
self.avatarBackgroundView.isHidden = component.ringAnimation != nil || self.indicatorColorLayer.isHidden
let baseRadius: CGFloat = 30.0
let collapsedRadius: CGFloat = 32.0
let indicatorRadius: CGFloat = baseRadius * component.scale + collapsedRadius * (1.0 - component.scale)

View File

@ -41,6 +41,7 @@ struct ChatMessageAttachedContentNodeMediaFlags: OptionSet {
static let preferMediaInline = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 0)
static let preferMediaBeforeText = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 1)
static let preferMediaAspectFilled = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 2)
static let titleBeforeMedia = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 3)
}
final class ChatMessageAttachedContentButtonNode: HighlightTrackingButtonNode {
@ -261,6 +262,7 @@ final class ChatMessageAttachedContentButtonNode: HighlightTrackingButtonNode {
final class ChatMessageAttachedContentNode: ASDisplayNode {
private let lineNode: ASImageNode
private let topTitleNode: TextNode
private let textNode: TextNodeWithEntities
private let inlineImageNode: TransformImageNode
private var contentImageNode: ChatMessageInteractiveMediaNode?
@ -306,6 +308,12 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
self.lineNode.displaysAsynchronously = false
self.lineNode.displayWithoutProcessing = true
self.topTitleNode = TextNode()
self.topTitleNode.isUserInteractionEnabled = false
self.topTitleNode.displaysAsynchronously = false
self.topTitleNode.contentsScale = UIScreenScale
self.topTitleNode.contentMode = .topLeft
self.textNode = TextNodeWithEntities()
self.textNode.textNode.isUserInteractionEnabled = false
self.textNode.textNode.displaysAsynchronously = false
@ -322,12 +330,14 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
super.init()
self.addSubnode(self.lineNode)
self.addSubnode(self.topTitleNode)
self.addSubnode(self.textNode.textNode)
self.addSubnode(self.statusNode)
}
func asyncLayout() -> (_ presentationData: ChatPresentationData, _ automaticDownloadSettings: MediaAutoDownloadSettings, _ associatedData: ChatMessageItemAssociatedData, _ attributes: ChatMessageEntryAttributes, _ context: AccountContext, _ controllerInteraction: ChatControllerInteraction, _ message: Message, _ messageRead: Bool, _ chatLocation: ChatLocation, _ title: String?, _ subtitle: NSAttributedString?, _ text: String?, _ entities: [MessageTextEntity]?, _ media: (Media, ChatMessageAttachedContentNodeMediaFlags)?, _ mediaBadge: String?, _ actionIcon: ChatMessageAttachedContentActionIcon?, _ actionTitle: String?, _ displayLine: Bool, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ constrainedSize: CGSize, _ animationCache: AnimationCache, _ animationRenderer: MultiAnimationRenderer) -> (CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {
let topTitleAsyncLayout = TextNode.asyncLayout(self.topTitleNode)
let textAsyncLayout = TextNodeWithEntities.asyncLayout(self.textNode)
let currentImage = self.media as? TelegramMediaImage
let imageLayout = self.inlineImageNode.asyncLayout()
@ -367,11 +377,13 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
horizontalInsets.left += 12.0
}
var titleBeforeMedia = false
var preferMediaBeforeText = false
var preferMediaAspectFilled = false
if let (_, flags) = mediaAndFlags {
preferMediaBeforeText = flags.contains(.preferMediaBeforeText)
preferMediaAspectFilled = flags.contains(.preferMediaAspectFilled)
titleBeforeMedia = flags.contains(.titleBeforeMedia)
}
var contentMode: InteractiveMediaNodeContentMode = preferMediaAspectFilled ? .aspectFill : .aspectFit
@ -428,14 +440,20 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
var contentInstantVideoSizeAndApply: (ChatMessageInstantVideoItemLayoutResult, (ChatMessageInstantVideoItemLayoutData, ListViewItemUpdateAnimation) -> ChatMessageInteractiveInstantVideoNode)?
let topTitleString = NSMutableAttributedString()
let string = NSMutableAttributedString()
var notEmpty = false
let messageTheme = incoming ? presentationData.theme.theme.chat.message.incoming : presentationData.theme.theme.chat.message.outgoing
if let title = title, !title.isEmpty {
string.append(NSAttributedString(string: title, font: titleFont, textColor: messageTheme.accentTextColor))
notEmpty = true
if titleBeforeMedia {
topTitleString.append(NSAttributedString(string: title, font: titleFont, textColor: messageTheme.accentTextColor))
} else {
string.append(NSAttributedString(string: title, font: titleFont, textColor: messageTheme.accentTextColor))
notEmpty = true
}
}
if let subtitle = subtitle, subtitle.length > 0 {
@ -724,6 +742,8 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
let upatedTextCutout = textCutout
let (topTitleLayout, topTitleApply) = topTitleAsyncLayout(TextNodeLayoutArguments(attributedString: topTitleString, backgroundColor: nil, maximumNumberOfLines: 12, truncationType: .end, constrainedSize: textConstrainedSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let (textLayout, textApply) = textAsyncLayout(TextNodeLayoutArguments(attributedString: textString, backgroundColor: nil, maximumNumberOfLines: 12, truncationType: .end, constrainedSize: textConstrainedSize, alignment: .natural, cutout: upatedTextCutout, insets: UIEdgeInsets()))
var statusSuggestedWidthAndContinue: (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation) -> Void))?
@ -765,6 +785,11 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
var boundingSize = textFrame.size
var lineHeight = textLayout.rawTextSize.height
if titleBeforeMedia {
lineHeight += topTitleLayout.size.height + 4.0
boundingSize.height += topTitleLayout.size.height + 4.0
boundingSize.width = max(boundingSize.width, topTitleLayout.size.width)
}
if let inlineImageSize = inlineImageSize {
if boundingSize.height < inlineImageSize.height {
boundingSize.height = inlineImageSize.height
@ -946,8 +971,11 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
}
var textVerticalOffset: CGFloat = 0.0
if titleBeforeMedia {
textVerticalOffset += topTitleLayout.size.height + 4.0
}
if let contentMediaHeight = contentMediaHeight, let (_, flags) = mediaAndFlags, flags.contains(.preferMediaBeforeText) {
textVerticalOffset = contentMediaHeight + 7.0
textVerticalOffset += contentMediaHeight + 7.0
}
let adjustedTextFrame = textFrame.offsetBy(dx: 0.0, dy: textVerticalOffset)
@ -981,6 +1009,9 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
strongSelf.textNode.textNode.displaysAsynchronously = !isPreview
let _ = topTitleApply()
strongSelf.topTitleNode.frame = CGRect(origin: CGPoint(x: textFrame.minX, y: insets.top), size: topTitleLayout.size)
let _ = textApply(TextNodeWithEntities.Arguments(
context: context,
cache: animationCache,
@ -1036,9 +1067,12 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
contentImageNode.visibility = strongSelf.visibility != .none
}
let _ = contentImageApply(animation, synchronousLoads)
let contentImageFrame: CGRect
var contentImageFrame: CGRect
if let (_, flags) = mediaAndFlags, flags.contains(.preferMediaBeforeText) {
contentImageFrame = CGRect(origin: CGPoint(x: insets.left, y: insets.top), size: contentImageSize)
if titleBeforeMedia {
contentImageFrame.origin.y += topTitleLayout.size.height + 4.0
}
} else {
contentImageFrame = CGRect(origin: CGPoint(x: insets.left, y: textFrame.maxY + (textFrame.size.height > CGFloat.ulpOfOne ? 4.0 : 0.0)), size: contentImageSize)
}

View File

@ -702,9 +702,15 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
var maxHeight = layoutConstants.image.maxDimensions.height
var isStory = false
var additionalWidthConstrainment = false
var unboundSize: CGSize
if let _ = media as? TelegramMediaStory {
unboundSize = CGSize(width: 1080, height: 1920)
if message.media.contains(where: { $0 is TelegramMediaWebpage }) {
additionalWidthConstrainment = true
unboundSize = CGSize(width: 174.0, height: 239.0)
} else {
unboundSize = CGSize(width: 1080, height: 1920)
}
} else if let image = media as? TelegramMediaImage, let dimensions = largestImageRepresentation(image.representations)?.dimensions {
unboundSize = CGSize(width: max(10.0, floor(dimensions.cgSize.width * 0.5)), height: max(10.0, floor(dimensions.cgSize.height * 0.5)))
} else if let file = media as? TelegramMediaFile, var dimensions = file.dimensions {
@ -806,7 +812,12 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
if isSticker {
nativeSize = unboundSize.aspectFittedOrSmaller(constrainedSize)
} else {
if unboundSize.width > unboundSize.height {
var constrainedSize = constrainedSize
if additionalWidthConstrainment {
constrainedSize.width = min(constrainedSize.width, unboundSize.width)
constrainedSize.height = min(constrainedSize.height, unboundSize.height)
}
if unboundSize.width > unboundSize.height || additionalWidthConstrainment {
nativeSize = unboundSize.aspectFitted(constrainedSize)
} else {
nativeSize = unboundSize.aspectFitted(CGSize(width: constrainedSize.height, height: constrainedSize.width))
@ -867,7 +878,12 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
if isSecretMedia {
resultWidth = maxWidth
} else {
let maxFittedSize = nativeSize.aspectFitted(maxDimensions)
let maxFittedSize: CGSize
if additionalWidthConstrainment {
maxFittedSize = nativeSize.aspectFittedOrSmaller(maxDimensions)
} else {
maxFittedSize = nativeSize.aspectFitted(maxDimensions)
}
resultWidth = min(nativeSize.width, min(maxFittedSize.width, min(constrainedSize.width, maxDimensions.width)))
resultWidth = max(resultWidth, layoutConstants.image.minDimensions.width)
}
@ -886,7 +902,12 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
drawingSize = nativeSize.aspectFilled(boundingSize)
} else {
let fittedSize = nativeSize.fittedToWidthOrSmaller(boundingWidth)
let filledSize = fittedSize.aspectFilled(CGSize(width: boundingWidth, height: fittedSize.height))
let filledSize: CGSize
if additionalWidthConstrainment {
filledSize = fittedSize
} else {
filledSize = fittedSize.aspectFilled(CGSize(width: boundingWidth, height: fittedSize.height))
}
boundingSize = CGSize(width: boundingWidth, height: filledSize.height).cropped(CGSize(width: CGFloat.greatestFiniteMagnitude, height: maxHeight))
boundingSize.height = max(boundingSize.height, layoutConstants.image.minDimensions.height)

View File

@ -221,7 +221,11 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
mediaAndFlags = (image, flags)
}
} else if let story = mainMedia as? TelegramMediaStory {
mediaAndFlags = (story, [])
mediaAndFlags = (story, [.preferMediaBeforeText, .titleBeforeMedia])
if let storyItem = item.message.associatedStories[story.storyId]?.get(Stories.StoredItem.self), case let .item(itemValue) = storyItem {
text = itemValue.text
entities = itemValue.entities
}
} else if let type = webpage.type {
if type == "telegram_background" {
var colors: [UInt32] = []