diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 66c24098d5..f06e3fb0b5 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -313,6 +313,8 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { let avatarNode: AvatarNode let titleNode: TextNode let authorNode: TextNode + let measureNode: TextNode + private var currentItemHeight: CGFloat? let textNode: TextNode let contentImageNode: TransformImageNode let inputActivitiesNode: ChatListInputActivitiesNode @@ -431,6 +433,8 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { self.contextContainer = ContextControllerSourceNode() + self.measureNode = TextNode() + self.titleNode = TextNode() self.titleNode.isUserInteractionEnabled = false self.titleNode.displaysAsynchronously = true @@ -633,6 +637,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { let textLayout = TextNode.asyncLayout(self.textNode) let titleLayout = TextNode.asyncLayout(self.titleNode) let authorLayout = TextNode.asyncLayout(self.authorNode) + let makeMeasureLayout = TextNode.asyncLayout(self.measureNode) let inputActivitiesLayout = self.inputActivitiesNode.asyncLayout() let badgeLayout = self.badgeNode.asyncLayout() let mentionBadgeLayout = self.mentionBadgeNode.asyncLayout() @@ -1105,21 +1110,21 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { } badgeSize = max(badgeSize, reorderInset) - let (authorLayout, authorApply) = authorLayout(TextNodeLayoutArguments(attributedString: hideAuthor ? nil : authorAttributedString, backgroundColor: nil, minimumNumberOfLines: 1, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth - badgeSize, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets(top: 2.0, left: 1.0, bottom: 2.0, right: 1.0))) + let (authorLayout, authorApply) = authorLayout(TextNodeLayoutArguments(attributedString: hideAuthor ? nil : authorAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth - badgeSize, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets(top: 2.0, left: 1.0, bottom: 2.0, right: 1.0))) var textCutout: TextNodeCutout? if !textLeftCutout.isZero { textCutout = TextNodeCutout(topLeft: CGSize(width: textLeftCutout, height: 4.0), topRight: nil, bottomRight: nil) } - let (textLayout, textApply) = textLayout(TextNodeLayoutArguments(attributedString: textAttributedString, backgroundColor: nil, minimumNumberOfLines: authorAttributedString == nil ? 2 : 1, maximumNumberOfLines: authorAttributedString == nil ? 2 : 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth - badgeSize, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: textCutout, insets: UIEdgeInsets(top: 2.0, left: 1.0, bottom: 2.0, right: 1.0))) + let (textLayout, textApply) = textLayout(TextNodeLayoutArguments(attributedString: textAttributedString, backgroundColor: nil, maximumNumberOfLines: authorAttributedString == nil ? 2 : 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth - badgeSize, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: textCutout, insets: UIEdgeInsets(top: 2.0, left: 1.0, bottom: 2.0, right: 1.0))) let titleRectWidth = rawContentWidth - dateLayout.size.width - 10.0 - statusWidth - titleIconsWidth - let (titleLayout, titleApply) = titleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, minimumNumberOfLines: 1, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: titleRectWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (titleLayout, titleApply) = titleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: titleRectWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) var inputActivitiesSize: CGSize? var inputActivitiesApply: (() -> Void)? if let inputActivities = inputActivities, !inputActivities.isEmpty { - let (size, apply) = inputActivitiesLayout(CGSize(width: rawContentWidth - badgeSize, height: 40.0), item.presentationData.strings, item.presentationData.theme.chatList.messageTextColor, item.index.messageIndex.id.peerId, inputActivities) + let (size, apply) = inputActivitiesLayout(CGSize(width: rawContentWidth - badgeSize, height: 40.0), item.presentationData, item.presentationData.theme.chatList.messageTextColor, item.index.messageIndex.id.peerId, inputActivities) inputActivitiesSize = size inputActivitiesApply = apply } @@ -1177,15 +1182,22 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { animateContent = true } + let measureString = NSAttributedString(string: "A", font: titleFont, textColor: .black) + let (measureLayout, measureApply) = makeMeasureLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: titleRectWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let titleSpacing: CGFloat = -1.0 let authorSpacing: CGFloat = -3.0 - var itemHeight: CGFloat = 8.0 * 2.0 + titleLayout.size.height + titleSpacing - if authorLayout.size.height.isZero { + var itemHeight: CGFloat = 8.0 * 2.0 + 1.0 + itemHeight += measureLayout.size.height * 3.0 + itemHeight += titleSpacing + itemHeight += authorSpacing + + /*if authorLayout.size.height.isZero { itemHeight += textLayout.size.height } else { itemHeight += authorLayout.size.height itemHeight += authorSpacing + textLayout.size.height - } + }*/ let rawContentRect = CGRect(origin: CGPoint(x: 2.0, y: layoutOffset + 8.0), size: CGSize(width: rawContentWidth, height: itemHeight - 12.0 - 9.0)) @@ -1209,6 +1221,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { return (layout, { [weak self] synchronousLoads, animated in if let strongSelf = self { strongSelf.layoutParams = (item, first, last, firstWithHeader, nextIsPinned, params, countersSize) + strongSelf.currentItemHeight = itemHeight strongSelf.contentImageMedia = contentImageMedia strongSelf.cachedChatListText = chatListText strongSelf.cachedChatListSearchResult = chatListSearchResult @@ -1339,7 +1352,8 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { onlineIcon = PresentationResourcesChatList.recentStatusOnlineIcon(item.presentationData.theme, state: .regular) } strongSelf.onlineNode.setImage(onlineIcon) - + + let _ = measureApply() let _ = dateApply() let _ = textApply() let _ = authorApply() @@ -1354,6 +1368,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { let statusSize = CGSize(width: 24.0, height: 24.0) strongSelf.statusNode.frame = CGRect(origin: CGPoint(x: contentRect.origin.x + contentRect.size.width - dateLayout.size.width - statusSize.width, y: contentRect.origin.y + 2.0 - UIScreenPixel + floor((dateLayout.size.height - statusSize.height) / 2.0)), size: statusSize) + strongSelf.statusNode.fontSize = item.presentationData.fontSize.itemListBaseFontSize let _ = strongSelf.statusNode.transitionToState(statusState, animated: animateContent) if let _ = currentBadgeBackgroundImage { @@ -1817,7 +1832,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { if let item = self.item { if case .groupReference = item.content { - self.layer.sublayerTransform = CATransform3DMakeTranslation(0.0, currentValue - self.bounds.size.height, 0.0) + self.layer.sublayerTransform = CATransform3DMakeTranslation(0.0, currentValue - (self.currentItemHeight ?? 0.0), 0.0) } else { var separatorFrame = self.separatorNode.frame separatorFrame.origin.y = currentValue - UIScreenPixel diff --git a/submodules/ChatListUI/Sources/Node/ChatListStatusNode.swift b/submodules/ChatListUI/Sources/Node/ChatListStatusNode.swift index fdd9b7d121..a4f6cb2a2a 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListStatusNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListStatusNode.swift @@ -34,6 +34,8 @@ enum ChatListStatusNodeState: Equatable { private let transitionDuration = 0.2 class ChatListStatusContentNode: ASDisplayNode { + var fontSize: CGFloat = 17.0 + override init() { super.init() @@ -57,6 +59,13 @@ class ChatListStatusContentNode: ASDisplayNode { final class ChatListStatusNode: ASDisplayNode { private(set) var state: ChatListStatusNodeState = .none + var fontSize: CGFloat = 17.0 { + didSet { + self.contentNode?.fontSize = self.fontSize + self.nextContentNode?.fontSize = self.fontSize + } + } + private var contentNode: ChatListStatusContentNode? private var nextContentNode: ChatListStatusContentNode? @@ -66,6 +75,7 @@ final class ChatListStatusNode: ASDisplayNode { self.state = state let contentNode = state.contentNode() + contentNode?.fontSize = self.fontSize if contentNode?.classForCoder != self.contentNode?.classForCoder { contentNode?.updateWithState(state, animated: animated) self.transitionToContentNode(contentNode, state: state, fromState: currentState, animated: animated, completion: completion) @@ -190,10 +200,12 @@ private func maybeAddRotationAnimation(_ layer: CALayer, duration: Double) { private final class StatusChecksNodeParameters: NSObject { let color: UIColor let progress: CGFloat + let fontSize: CGFloat - init(color: UIColor, progress: CGFloat) { + init(color: UIColor, progress: CGFloat, fontSize: CGFloat) { self.color = color self.progress = progress + self.fontSize = fontSize super.init() } @@ -214,6 +226,12 @@ private class ChatListStatusChecksNode: ChatListStatusContentNode { } } + override var fontSize: CGFloat { + didSet { + self.setNeedsDisplay() + } + } + init(color: UIColor) { self.color = color @@ -241,7 +259,7 @@ private class ChatListStatusChecksNode: ChatListStatusContentNode { } override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? { - return StatusChecksNodeParameters(color: self.color, progress: self.effectiveProgress) + return StatusChecksNodeParameters(color: self.color, progress: self.effectiveProgress, fontSize: self.fontSize) } override func didEnterHierarchy() { @@ -261,6 +279,11 @@ private class ChatListStatusChecksNode: ChatListStatusContentNode { return } + let scaleFactor = min(1.4, parameters.fontSize / 17.0) + context.translateBy(x: bounds.width / 2.0, y: bounds.height / 2.0) + context.scaleBy(x: scaleFactor, y: scaleFactor) + context.translateBy(x: -bounds.width / 2.0, y: -bounds.height / 2.0) + let progress = parameters.progress context.setStrokeColor(parameters.color.cgColor) diff --git a/submodules/ChatListUI/Sources/Node/ChatListTypingNode.swift b/submodules/ChatListUI/Sources/Node/ChatListTypingNode.swift index dbcb66e59c..e67e3f05c9 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListTypingNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListTypingNode.swift @@ -10,8 +10,6 @@ import TelegramPresentationData import ChatTitleActivityNode import LocalizedPeerData -private let textFont = Font.regular(15.0) - final class ChatListInputActivitiesNode: ASDisplayNode { private let activityNode: ChatTitleActivityNode @@ -23,8 +21,12 @@ final class ChatListInputActivitiesNode: ASDisplayNode { self.addSubnode(self.activityNode) } - func asyncLayout() -> (CGSize, PresentationStrings, UIColor, PeerId, [(Peer, PeerInputActivity)]) -> (CGSize, () -> Void) { - return { [weak self] boundingSize, strings, color, peerId, activities in + func asyncLayout() -> (CGSize, ChatListPresentationData, UIColor, PeerId, [(Peer, PeerInputActivity)]) -> (CGSize, () -> Void) { + return { [weak self] boundingSize, presentationData, color, peerId, activities in + let strings = presentationData.strings + + let textFont = Font.regular(floor(presentationData.fontSize.itemListBaseFontSize * 15.0 / 17.0)) + var state = ChatTitleActivityNodeState.none if !activities.isEmpty { diff --git a/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift b/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift index d1728dc26a..5b8028f7a9 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift @@ -108,6 +108,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg private let maskNode: ASImageNode private let titleNode: TextNode + private let measureTitleSizeNode: TextNode private let textNode: TextFieldNode private let clearIconNode: ASImageNode private let clearButtonNode: HighlightableButtonNode @@ -131,6 +132,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg self.maskNode = ASImageNode() self.titleNode = TextNode() + self.measureTitleSizeNode = TextNode() self.textNode = TextFieldNode() self.clearIconNode = ASImageNode() @@ -185,6 +187,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg public func asyncLayout() -> (_ item: ItemListSingleLineInputItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { let makeTitleLayout = TextNode.asyncLayout(self.titleNode) + let makeMeasureTitleSizeLayout = TextNode.asyncLayout(self.measureTitleSizeNode) let currentItem = self.item @@ -215,9 +218,11 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleString, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - 32.0 - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (measureTitleLayout, measureTitleSizeApply) = makeMeasureTitleSizeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "A", font: Font.regular(item.presentationData.fontSize.itemListBaseFontSize)), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - 32.0 - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let separatorHeight = UIScreenPixel - let contentSize = CGSize(width: params.width, height: titleLayout.size.height + 22.0) + let contentSize = CGSize(width: params.width, height: max(titleLayout.size.height, measureTitleLayout.size.height) + 22.0) let insets = itemListNeighborsGroupedInsets(neighbors) let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets) @@ -246,6 +251,8 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg let _ = titleApply() strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: floor((layout.contentSize.height - titleLayout.size.height) / 2.0)), size: titleLayout.size) + let _ = measureTitleSizeApply() + let secureEntry: Bool let capitalizationType: UITextAutocapitalizationType let autocorrectionType: UITextAutocorrectionType diff --git a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift index 28ede8025f..f589a7fa94 100644 --- a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift +++ b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift @@ -113,7 +113,6 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView if case let .file(file) = presentationData.theme.chat.defaultWallpaper, file.id == 0 { self.remoteChatBackgroundNode.isHidden = false - self.toolbarNode.setDoneEnabled(false) } else { self.remoteChatBackgroundNode.isHidden = true } @@ -212,7 +211,8 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView guard let strongSelf = self else { return } - if case let .file(file) = wallpaper { + switch wallpaper { + case let .file(file): let dimensions = file.file.dimensions ?? PixelDimensions(width: 100, height: 100) let displaySize = dimensions.cgSize.dividedByScreenScale().integralFloor @@ -267,6 +267,8 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView } strongSelf.remoteChatBackgroundNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: displaySize, boundingSize: displaySize, intrinsicInsets: UIEdgeInsets(), emptyColor: patternColor))() + default: + break } } applyWallpaper(self.presentationData.chatWallpaper) @@ -519,6 +521,7 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView self.toolbarNode.updatePresentationThemeSettings(presentationThemeSettings: self.presentationThemeSettings) if let (layout, navigationBarHeight) = self.validLayout { self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate) + self.recursivelyEnsureDisplaySynchronously(true) } } diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift index f034e0b8ef..26b472281d 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift @@ -188,7 +188,7 @@ private func mappedInsertEntries(context: AccountContext, chatLocation: ChatLoca case .bubbles: item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes)) case let .list(search, _): - item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, context: context, chatLocation: chatLocation, controllerInteraction: controllerInteraction, message: message, selection: selection, displayHeader: search) + item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, fontSize: presentationData.fontSize, dateTimeFormat: presentationData.dateTimeFormat, context: context, chatLocation: chatLocation, controllerInteraction: controllerInteraction, message: message, selection: selection, displayHeader: search) } return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) case let .MessageGroupEntry(_, messages, presentationData): @@ -198,7 +198,7 @@ private func mappedInsertEntries(context: AccountContext, chatLocation: ChatLoca item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .group(messages: messages)) case let .list(search, _): assertionFailure() - item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, context: context, chatLocation: chatLocation, controllerInteraction: controllerInteraction, message: messages[0].0, selection: .none, displayHeader: search) + item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, fontSize: presentationData.fontSize, dateTimeFormat: presentationData.dateTimeFormat, context: context, chatLocation: chatLocation, controllerInteraction: controllerInteraction, message: messages[0].0, selection: .none, displayHeader: search) } return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) case let .UnreadEntry(_, presentationData): @@ -222,7 +222,7 @@ private func mappedUpdateEntries(context: AccountContext, chatLocation: ChatLoca case .bubbles: item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes)) case let .list(search, _): - item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, context: context, chatLocation: chatLocation, controllerInteraction: controllerInteraction, message: message, selection: selection, displayHeader: search) + item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, fontSize: presentationData.fontSize, dateTimeFormat: presentationData.dateTimeFormat, context: context, chatLocation: chatLocation, controllerInteraction: controllerInteraction, message: message, selection: selection, displayHeader: search) } return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) case let .MessageGroupEntry(_, messages, presentationData): @@ -232,7 +232,7 @@ private func mappedUpdateEntries(context: AccountContext, chatLocation: ChatLoca item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .group(messages: messages)) case let .list(search, _): assertionFailure() - item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, context: context, chatLocation: chatLocation, controllerInteraction: controllerInteraction, message: messages[0].0, selection: .none, displayHeader: search) + item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, fontSize: presentationData.fontSize, dateTimeFormat: presentationData.dateTimeFormat, context: context, chatLocation: chatLocation, controllerInteraction: controllerInteraction, message: messages[0].0, selection: .none, displayHeader: search) } return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) case let .UnreadEntry(_, presentationData): @@ -1547,7 +1547,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { case .bubbles: item = ChatMessageItem(presentationData: presentationData, context: self.context, chatLocation: self.chatLocation, associatedData: associatedData, controllerInteraction: self.controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes)) case let .list(search, _): - item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, context: self.context, chatLocation: self.chatLocation, controllerInteraction: self.controllerInteraction, message: message, selection: selection, displayHeader: search) + item = ListMessageItem(theme: presentationData.theme.theme, strings: presentationData.strings, fontSize: presentationData.fontSize, dateTimeFormat: presentationData.dateTimeFormat, context: self.context, chatLocation: self.chatLocation, controllerInteraction: self.controllerInteraction, message: message, selection: selection, displayHeader: search) } let updateItem = ListViewUpdateItem(index: index, previousIndex: index, item: item, directionHint: nil) self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [updateItem], options: [.AnimateInsertion], scrollToItem: nil, additionalScrollDistance: 0.0, updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) diff --git a/submodules/TelegramUI/TelegramUI/ChatHistorySearchContainerNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistorySearchContainerNode.swift index 974e57853c..3edfa84d36 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistorySearchContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistorySearchContainerNode.swift @@ -10,6 +10,7 @@ import TelegramPresentationData import MergeLists import AccountContext import SearchUI +import TelegramUIPreferences private enum ChatHistorySearchEntryStableId: Hashable { case messageId(MessageId) @@ -35,19 +36,19 @@ private enum ChatHistorySearchEntryStableId: Hashable { private enum ChatHistorySearchEntry: Comparable, Identifiable { - case message(Message, PresentationTheme, PresentationStrings, PresentationDateTimeFormat) + case message(Message, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationFontSize) var stableId: ChatHistorySearchEntryStableId { switch self { - case let .message(message, _, _, _): + case let .message(message, _, _, _, _): return .messageId(message.id) } } static func ==(lhs: ChatHistorySearchEntry, rhs: ChatHistorySearchEntry) -> Bool { switch lhs { - case let .message(lhsMessage, lhsTheme, lhsStrings, lhsDateTimeFormat): - if case let .message(rhsMessage, rhsTheme, rhsStrings, rhsDateTimeFormat) = rhs { + case let .message(lhsMessage, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsFontSize): + if case let .message(rhsMessage, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsFontSize) = rhs { if lhsMessage.id != rhsMessage.id { return false } @@ -63,6 +64,9 @@ private enum ChatHistorySearchEntry: Comparable, Identifiable { if lhsDateTimeFormat != rhsDateTimeFormat { return false } + if lhsFontSize != rhsFontSize { + return false + } return true } else { return false @@ -72,8 +76,8 @@ private enum ChatHistorySearchEntry: Comparable, Identifiable { static func <(lhs: ChatHistorySearchEntry, rhs: ChatHistorySearchEntry) -> Bool { switch lhs { - case let .message(lhsMessage, _, _, _): - if case let .message(rhsMessage, _, _, _) = rhs { + case let .message(lhsMessage, _, _, _, _): + if case let .message(rhsMessage, _, _, _, _) = rhs { return lhsMessage.index < rhsMessage.index } else { return false @@ -83,8 +87,8 @@ private enum ChatHistorySearchEntry: Comparable, Identifiable { func item(context: AccountContext, peerId: PeerId, interaction: ChatControllerInteraction) -> ListViewItem { switch self { - case let .message(message, theme, strings, dateTimeFormat): - return ListMessageItem(theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, context: context, chatLocation: .peer(peerId), controllerInteraction: interaction, message: message, selection: .none, displayHeader: true) + case let .message(message, theme, strings, dateTimeFormat, fontSize): + return ListMessageItem(theme: theme, strings: strings, fontSize: fontSize, dateTimeFormat: dateTimeFormat, context: context, chatLocation: .peer(peerId), controllerInteraction: interaction, message: message, selection: .none, displayHeader: true) } } } @@ -134,7 +138,7 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode { private var presentationData: PresentationData private var presentationDataDisposable: Disposable? - private let themeAndStringsPromise: Promise<(PresentationTheme, PresentationStrings, PresentationDateTimeFormat)> + private let themeAndStringsPromise: Promise<(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationFontSize)> private var enqueuedTransitions: [(ChatHistorySearchContainerTransition, Bool)] = [] @@ -143,7 +147,7 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode { self.presentationData = context.sharedContext.currentPresentationData.with { $0 } - self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings, self.presentationData.dateTimeFormat)) + self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings, self.presentationData.dateTimeFormat, self.presentationData.fontSize)) self.dimNode = ASDisplayNode() self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5) @@ -191,7 +195,7 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode { return ([], [:]) } else { return (messages.map { message -> ChatHistorySearchEntry in - return .message(message, themeAndStrings.0, themeAndStrings.1, themeAndStrings.2) + return .message(message, themeAndStrings.0, themeAndStrings.1, themeAndStrings.2, themeAndStrings.3) }, Dictionary(messages.map { ($0.id, $0) }, uniquingKeysWith: { lhs, _ in lhs })) } } @@ -224,7 +228,7 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode { self.presentationDataDisposable = context.sharedContext.presentationData.start(next: { [weak self] presentationData in if let strongSelf = self { - strongSelf.themeAndStringsPromise.set(.single((presentationData.theme, presentationData.strings, presentationData.dateTimeFormat))) + strongSelf.themeAndStringsPromise.set(.single((presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.fontSize))) strongSelf.emptyResultsTitleNode.attributedText = NSAttributedString(string: presentationData.strings.SharedMedia_SearchNoResults, font: Font.semibold(17.0), textColor: presentationData.theme.list.freeTextColor, paragraphAlignment: .center) @@ -342,10 +346,10 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode { if let currentEntries = self.currentEntries { for entry in currentEntries { switch entry { - case let .message(message, _, _, _): - if message.id == id { - return message - } + case let .message(message, _, _, _, _): + if message.id == id { + return message + } } } } diff --git a/submodules/TelegramUI/TelegramUI/ListMessageFileItemNode.swift b/submodules/TelegramUI/TelegramUI/ListMessageFileItemNode.swift index 5f8d3516d2..030f40ed65 100644 --- a/submodules/TelegramUI/TelegramUI/ListMessageFileItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ListMessageFileItemNode.swift @@ -114,10 +114,6 @@ private func extensionImage(fileExtension: String?) -> UIImage? { return nil } } - -private let titleFont = Font.medium(16.0) -private let audioTitleFont = Font.regular(16.0) -private let descriptionFont = Font.regular(13.0) private let extensionFont = Font.medium(13.0) private struct FetchControls { @@ -316,6 +312,10 @@ final class ListMessageFileItemNode: ListMessageNode { updatedTheme = item.theme } + let titleFont = Font.medium(floor(item.fontSize.baseDisplaySize * 16.0 / 17.0)) + let audioTitleFont = Font.regular(floor(item.fontSize.baseDisplaySize * 16.0 / 17.0)) + let descriptionFont = Font.regular(floor(item.fontSize.baseDisplaySize * 13.0 / 17.0)) + var leftInset: CGFloat = 65.0 + params.leftInset let rightInset: CGFloat = 8.0 + params.rightInset @@ -494,7 +494,7 @@ final class ListMessageFileItemNode: ListMessageNode { insets.top += header.height } - let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: 56.0), insets: insets) + let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: 8.0 * 2.0 + titleNodeLayout.size.height + 3.0 + descriptionNodeLayout.size.height), insets: insets) return (nodeLayout, { animation in if let strongSelf = self { @@ -562,7 +562,7 @@ final class ListMessageFileItemNode: ListMessageNode { } } - transition.updateFrame(node: strongSelf.descriptionNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset + descriptionOffset, y: 32.0), size: descriptionNodeLayout.size)) + transition.updateFrame(node: strongSelf.descriptionNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset + descriptionOffset, y: strongSelf.titleNode.frame.maxY + 3.0), size: descriptionNodeLayout.size)) let _ = descriptionNodeApply() let iconFrame: CGRect @@ -630,7 +630,7 @@ final class ListMessageFileItemNode: ListMessageNode { })) } - transition.updateFrame(node: strongSelf.downloadStatusIconNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset, y: 34.0), size: CGSize(width: 11.0, height: 11.0))) + transition.updateFrame(node: strongSelf.downloadStatusIconNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset, y: strongSelf.descriptionNode.frame.minY + floor((strongSelf.descriptionNode.frame.height - 11.0) / 2.0)), size: CGSize(width: 11.0, height: 11.0))) if let updatedFetchControls = updatedFetchControls { let _ = strongSelf.fetchControls.swap(updatedFetchControls) @@ -840,6 +840,7 @@ final class ListMessageFileItemNode: ListMessageNode { self.descriptionProgressNode.isHidden = true self.descriptionNode.isHidden = false } + let descriptionFont = Font.regular(floor(item.fontSize.baseDisplaySize * 13.0 / 17.0)) self.descriptionProgressNode.attributedText = NSAttributedString(string: downloadingString ?? "", font: descriptionFont, textColor: item.theme.list.itemSecondaryTextColor) let descriptionSize = self.descriptionProgressNode.updateLayout(CGSize(width: size.width - 14.0, height: size.height)) transition.updateFrame(node: self.descriptionProgressNode, frame: CGRect(origin: self.descriptionNode.frame.origin, size: descriptionSize)) diff --git a/submodules/TelegramUI/TelegramUI/ListMessageItem.swift b/submodules/TelegramUI/TelegramUI/ListMessageItem.swift index fdeebefad1..ee7fc455c1 100644 --- a/submodules/TelegramUI/TelegramUI/ListMessageItem.swift +++ b/submodules/TelegramUI/TelegramUI/ListMessageItem.swift @@ -8,10 +8,12 @@ import SwiftSignalKit import Postbox import TelegramPresentationData import AccountContext +import TelegramUIPreferences final class ListMessageItem: ListViewItem { let theme: PresentationTheme let strings: PresentationStrings + let fontSize: PresentationFontSize let dateTimeFormat: PresentationDateTimeFormat let context: AccountContext let chatLocation: ChatLocation @@ -23,9 +25,10 @@ final class ListMessageItem: ListViewItem { let selectable: Bool = true - public init(theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, context: AccountContext, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, message: Message, selection: ChatHistoryMessageSelection, displayHeader: Bool) { + public init(theme: PresentationTheme, strings: PresentationStrings, fontSize: PresentationFontSize, dateTimeFormat: PresentationDateTimeFormat, context: AccountContext, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, message: Message, selection: ChatHistoryMessageSelection, displayHeader: Bool) { self.theme = theme self.strings = strings + self.fontSize = fontSize self.dateTimeFormat = dateTimeFormat self.context = context self.chatLocation = chatLocation diff --git a/submodules/TelegramUI/TelegramUI/ListMessageSnippetItemNode.swift b/submodules/TelegramUI/TelegramUI/ListMessageSnippetItemNode.swift index e3df40f7e7..bd72494ca3 100644 --- a/submodules/TelegramUI/TelegramUI/ListMessageSnippetItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ListMessageSnippetItemNode.swift @@ -14,8 +14,6 @@ import PhotoResources import WebsiteType import UrlHandling -private let titleFont = Font.medium(16.0) -private let descriptionFont = Font.regular(14.0) private let iconFont = Font.medium(22.0) private let iconTextBackgroundImage = generateStretchableFilledCircleImage(radius: 2.0, color: UIColor(rgb: 0xdfdfdf)) @@ -157,6 +155,9 @@ final class ListMessageSnippetItemNode: ListMessageNode { updatedTheme = item.theme } + let titleFont = Font.medium(floor(item.fontSize.baseDisplaySize * 16.0 / 17.0)) + let descriptionFont = Font.regular(floor(item.fontSize.baseDisplaySize * 14.0 / 17.0)) + let leftInset: CGFloat = 65.0 + params.leftInset var leftOffset: CGFloat = 0.0 @@ -327,7 +328,7 @@ final class ListMessageSnippetItemNode: ListMessageNode { } } - let contentHeight = 40.0 + descriptionNodeLayout.size.height + linkNodeLayout.size.height + let contentHeight = 9.0 + titleNodeLayout.size.height + 10.0 + descriptionNodeLayout.size.height + linkNodeLayout.size.height var insets = UIEdgeInsets() if dateHeaderAtBottom, let header = item.header { @@ -379,7 +380,7 @@ final class ListMessageSnippetItemNode: ListMessageNode { transition.updateFrame(node: strongSelf.titleNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset, y: 9.0), size: titleNodeLayout.size)) let _ = titleNodeApply() - let descriptionFrame = CGRect(origin: CGPoint(x: leftOffset + leftInset - 1.0, y: 32.0), size: descriptionNodeLayout.size) + let descriptionFrame = CGRect(origin: CGPoint(x: leftOffset + leftInset - 1.0, y: strongSelf.titleNode.frame.maxY + 3.0), size: descriptionNodeLayout.size) transition.updateFrame(node: strongSelf.descriptionNode, frame: descriptionFrame) let _ = descriptionNodeApply()