mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-02 04:38:33 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/TelegramUI
This commit is contained in:
commit
7ffa11e408
@ -766,7 +766,34 @@ final class ChatListSearchContainerNode: SearchDisplayControllerContentNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
var recentItemsTransition = combineLatest(hasRecentPeers, recentlySearchedPeers(postbox: account.postbox), presentationDataPromise.get(), self.statePromise.get())
|
|
||||||
|
let previousRecentlySearchedPeerOrder = Atomic<[PeerId]>(value: [])
|
||||||
|
let fixedRecentlySearchedPeers = recentlySearchedPeers(postbox: account.postbox)
|
||||||
|
|> map { peers -> [RecentlySearchedPeer] in
|
||||||
|
var result: [RecentlySearchedPeer] = []
|
||||||
|
let _ = previousRecentlySearchedPeerOrder.modify { current in
|
||||||
|
var updated: [PeerId] = []
|
||||||
|
for id in current {
|
||||||
|
inner: for peer in peers {
|
||||||
|
if peer.peer.peerId == id {
|
||||||
|
updated.append(id)
|
||||||
|
result.append(peer)
|
||||||
|
break inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for peer in peers.reversed() {
|
||||||
|
if !updated.contains(peer.peer.peerId) {
|
||||||
|
updated.insert(peer.peer.peerId, at: 0)
|
||||||
|
result.insert(peer, at: 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return updated
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
var recentItemsTransition = combineLatest(hasRecentPeers, fixedRecentlySearchedPeers, presentationDataPromise.get(), self.statePromise.get())
|
||||||
|> mapToSignal { [weak self] hasRecentPeers, peers, presentationData, state -> Signal<(ChatListSearchContainerRecentTransition, Bool), NoError> in
|
|> mapToSignal { [weak self] hasRecentPeers, peers, presentationData, state -> Signal<(ChatListSearchContainerRecentTransition, Bool), NoError> in
|
||||||
var entries: [ChatListRecentEntry] = []
|
var entries: [ChatListRecentEntry] = []
|
||||||
if !filter.contains(.onlyGroups) {
|
if !filter.contains(.onlyGroups) {
|
||||||
|
|||||||
@ -22,6 +22,7 @@ enum InteractiveMediaNodeActivateContent {
|
|||||||
|
|
||||||
final class ChatMessageInteractiveMediaNode: ASDisplayNode {
|
final class ChatMessageInteractiveMediaNode: ASDisplayNode {
|
||||||
private let imageNode: TransformImageNode
|
private let imageNode: TransformImageNode
|
||||||
|
private var currentImageArguments: TransformImageArguments?
|
||||||
private var videoNode: UniversalVideoNode?
|
private var videoNode: UniversalVideoNode?
|
||||||
private var statusNode: RadialStatusNode?
|
private var statusNode: RadialStatusNode?
|
||||||
private var badgeNode: ChatMessageInteractiveMediaBadge?
|
private var badgeNode: ChatMessageInteractiveMediaBadge?
|
||||||
@ -396,7 +397,19 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode {
|
|||||||
strongSelf.sizeCalculation = sizeCalculation
|
strongSelf.sizeCalculation = sizeCalculation
|
||||||
strongSelf.automaticPlayback = automaticPlayback
|
strongSelf.automaticPlayback = automaticPlayback
|
||||||
strongSelf.automaticDownload = automaticDownload
|
strongSelf.automaticDownload = automaticDownload
|
||||||
|
|
||||||
|
if let previousArguments = strongSelf.currentImageArguments {
|
||||||
|
if previousArguments.imageSize == arguments.imageSize {
|
||||||
|
strongSelf.imageNode.frame = imageFrame
|
||||||
|
} else {
|
||||||
transition.updateFrame(node: strongSelf.imageNode, frame: imageFrame)
|
transition.updateFrame(node: strongSelf.imageNode, frame: imageFrame)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
strongSelf.imageNode.frame = imageFrame
|
||||||
|
}
|
||||||
|
strongSelf.currentImageArguments = arguments
|
||||||
|
imageApply()
|
||||||
|
|
||||||
strongSelf.statusNode?.position = CGPoint(x: imageFrame.midX, y: imageFrame.midY)
|
strongSelf.statusNode?.position = CGPoint(x: imageFrame.midX, y: imageFrame.midY)
|
||||||
|
|
||||||
if let replaceVideoNode = replaceVideoNode {
|
if let replaceVideoNode = replaceVideoNode {
|
||||||
@ -469,8 +482,6 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode {
|
|||||||
strongSelf.fetchControls.with({ $0 })?.fetch(false)
|
strongSelf.fetchControls.with({ $0 })?.fetch(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
imageApply()
|
|
||||||
|
|
||||||
strongSelf.updateFetchStatus()
|
strongSelf.updateFetchStatus()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -304,6 +304,7 @@ class ContactMultiselectionController: ViewController {
|
|||||||
if let presentationArguments = self.presentationArguments as? ViewControllerPresentationArguments {
|
if let presentationArguments = self.presentationArguments as? ViewControllerPresentationArguments {
|
||||||
switch presentationArguments.presentationAnimation {
|
switch presentationArguments.presentationAnimation {
|
||||||
case .modalSheet:
|
case .modalSheet:
|
||||||
|
self.view.endEditing(true)
|
||||||
self.contactsNode.animateOut(completion: { [weak self] in
|
self.contactsNode.animateOut(completion: { [weak self] in
|
||||||
self?.dismissed?()
|
self?.dismissed?()
|
||||||
completion?()
|
completion?()
|
||||||
|
|||||||
@ -174,7 +174,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func animateOut(completion: (() -> Void)?) {
|
func animateOut(completion: (() -> Void)?) {
|
||||||
self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: 0.0, y: self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, additive: true, completion: { [weak self] _ in
|
self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, additive: true, completion: { [weak self] _ in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.dismiss?()
|
strongSelf.dismiss?()
|
||||||
completion?()
|
completion?()
|
||||||
|
|||||||
@ -368,7 +368,14 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.currentExpandedDetails == nil {
|
if var currentExpandedDetails = self.currentExpandedDetails {
|
||||||
|
for (index, expanded) in expandedDetails {
|
||||||
|
if currentExpandedDetails[index] == nil {
|
||||||
|
currentExpandedDetails[index] = expanded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.currentExpandedDetails = currentExpandedDetails
|
||||||
|
} else {
|
||||||
self.currentExpandedDetails = expandedDetails
|
self.currentExpandedDetails = expandedDetails
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,7 +548,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let currentLayout = self.currentLayout, collapseOffset > 0.0 {
|
if let currentLayout = self.currentLayout {
|
||||||
let effectiveContentHeight = currentLayout.contentSize.height - collapseOffset
|
let effectiveContentHeight = currentLayout.contentSize.height - collapseOffset
|
||||||
if effectiveContentHeight != self.scrollNode.view.contentSize.height {
|
if effectiveContentHeight != self.scrollNode.view.contentSize.height {
|
||||||
transition.animateView {
|
transition.animateView {
|
||||||
@ -928,12 +935,17 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
private func findAnchorItem(_ anchor: String, items: [InstantPageItem]) -> (InstantPageItem, CGFloat, [InstantPageDetailsItem])? {
|
private func findAnchorItem(_ anchor: String, items: [InstantPageItem]) -> (InstantPageItem, CGFloat, [InstantPageDetailsItem])? {
|
||||||
for item in items {
|
for item in items {
|
||||||
if let item = item as? InstantPageAnchorItem, item.anchor == anchor {
|
if let item = item as? InstantPageAnchorItem, item.anchor == anchor {
|
||||||
return (item, 0.0, [])
|
return (item, -10.0, [])
|
||||||
} else if let item = item as? InstantPageTextItem {
|
} else if let item = item as? InstantPageTextItem {
|
||||||
if let lineIndex = item.anchors[anchor] {
|
if let lineIndex = item.anchors[anchor] {
|
||||||
return (item, item.lines[lineIndex].frame.minY - 10.0, [])
|
return (item, item.lines[lineIndex].frame.minY - 10.0, [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if let item = item as? InstantPageTableItem {
|
||||||
|
if let offset = item.anchors[anchor] {
|
||||||
|
return (item, offset - 10.0, [])
|
||||||
|
}
|
||||||
|
}
|
||||||
else if let item = item as? InstantPageDetailsItem {
|
else if let item = item as? InstantPageDetailsItem {
|
||||||
if let (foundItem, offset, detailsItems) = self.findAnchorItem(anchor, items: item.items) {
|
if let (foundItem, offset, detailsItems) = self.findAnchorItem(anchor, items: item.items) {
|
||||||
var detailsItems = detailsItems
|
var detailsItems = detailsItems
|
||||||
@ -965,14 +977,13 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
if let webPage = self.webPage, case let .Loaded(content) = webPage.content, let page = content.instantPage, page.url == baseUrl, let anchor = anchor {
|
if let webPage = self.webPage, case let .Loaded(content) = webPage.content, let page = content.instantPage, page.url == baseUrl, let anchor = anchor {
|
||||||
if !anchor.isEmpty {
|
if !anchor.isEmpty {
|
||||||
if let (item, lineOffset, detailsItems) = findAnchorItem(String(anchor), items: items) {
|
if let (item, lineOffset, detailsItems) = findAnchorItem(String(anchor), items: items) {
|
||||||
var previousDetailsItem: InstantPageDetailsItem?
|
|
||||||
var previousDetailsNode: InstantPageDetailsNode?
|
var previousDetailsNode: InstantPageDetailsNode?
|
||||||
var containerOffset: CGFloat = 0.0
|
var containerOffset: CGFloat = 0.0
|
||||||
for detailsItem in detailsItems {
|
for detailsItem in detailsItems {
|
||||||
if let previousNode = previousDetailsNode, let previousDetailsItem = previousDetailsItem {
|
if let previousNode = previousDetailsNode {
|
||||||
previousNode.contentNode.updateDetailsExpanded(detailsItem.index, true, animated: false)
|
previousNode.contentNode.updateDetailsExpanded(detailsItem.index, true, animated: false)
|
||||||
let frame = previousNode.contentNode.effectiveFrameForItem(detailsItem)
|
let frame = previousNode.effectiveFrameForItem(detailsItem)
|
||||||
containerOffset += frame.minY + previousDetailsItem.titleHeight
|
containerOffset += frame.minY
|
||||||
|
|
||||||
previousDetailsNode = previousNode.contentNode.nodeForDetailsItem(detailsItem)
|
previousDetailsNode = previousNode.contentNode.nodeForDetailsItem(detailsItem)
|
||||||
previousDetailsNode?.setExpanded(true, animated: false)
|
previousDetailsNode?.setExpanded(true, animated: false)
|
||||||
@ -983,18 +994,23 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
previousDetailsNode = self.nodeForDetailsItem(detailsItem)
|
previousDetailsNode = self.nodeForDetailsItem(detailsItem)
|
||||||
previousDetailsNode?.setExpanded(true, animated: false)
|
previousDetailsNode?.setExpanded(true, animated: false)
|
||||||
previousDetailsItem = detailsItem
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let frame: CGRect
|
let frame: CGRect
|
||||||
if let previousDetailsNode = previousDetailsNode, let previousDetailsItem = previousDetailsItem {
|
if let previousDetailsNode = previousDetailsNode {
|
||||||
containerOffset += previousDetailsItem.titleHeight
|
frame = previousDetailsNode.effectiveFrameForItem(item)
|
||||||
frame = previousDetailsNode.contentNode.effectiveFrameForItem(item)
|
|
||||||
} else {
|
} else {
|
||||||
frame = self.effectiveFrameForItem(item)
|
frame = self.effectiveFrameForItem(item)
|
||||||
}
|
}
|
||||||
self.scrollNode.view.setContentOffset(CGPoint(x: 0.0, y: containerOffset + frame.minY + lineOffset - self.scrollNode.view.contentInset.top), animated: true)
|
|
||||||
|
var targetY = min(containerOffset + frame.minY + lineOffset, self.scrollNode.view.contentSize.height - self.scrollNode.frame.height)
|
||||||
|
if targetY < self.scrollNode.view.contentOffset.y {
|
||||||
|
targetY -= self.scrollNode.view.contentInset.top
|
||||||
|
} else {
|
||||||
|
targetY -= self.containerLayout?.statusBarHeight ?? 20.0
|
||||||
|
}
|
||||||
|
self.scrollNode.view.setContentOffset(CGPoint(x: 0.0, y: targetY), animated: true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.scrollNode.view.setContentOffset(CGPoint(x: 0.0, y: -self.scrollNode.view.contentInset.top), animated: true)
|
self.scrollNode.view.setContentOffset(CGPoint(x: 0.0, y: -self.scrollNode.view.contentInset.top), animated: true)
|
||||||
|
|||||||
@ -361,7 +361,7 @@ final class InstantPageDetailsContentNode : ASDisplayNode {
|
|||||||
return CGRect(origin: origin, size: tile.frame.size)
|
return CGRect(origin: origin, size: tile.frame.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
func effectiveFrameForItem(_ item: InstantPageItem) -> CGRect {
|
fileprivate func effectiveFrameForItem(_ item: InstantPageItem) -> CGRect {
|
||||||
let layoutOrigin = item.frame.origin
|
let layoutOrigin = item.frame.origin
|
||||||
var origin = layoutOrigin
|
var origin = layoutOrigin
|
||||||
|
|
||||||
@ -610,6 +610,10 @@ final class InstantPageDetailsNode: ASDisplayNode, InstantPageNode {
|
|||||||
var effectiveContentSize: CGSize {
|
var effectiveContentSize: CGSize {
|
||||||
return self.contentNode.effectiveContentSize
|
return self.contentNode.effectiveContentSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func effectiveFrameForItem(_ item: InstantPageItem) -> CGRect {
|
||||||
|
return self.contentNode.effectiveFrameForItem(item).offsetBy(dx: 0.0, dy: self.item.titleHeight)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class InstantPageDetailsArrowNodeParameters: NSObject {
|
private final class InstantPageDetailsArrowNodeParameters: NSObject {
|
||||||
|
|||||||
@ -32,11 +32,11 @@ final class InstantPageFeedbackItem: InstantPageItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func distanceThresholdGroup() -> Int? {
|
func distanceThresholdGroup() -> Int? {
|
||||||
return nil
|
return 8
|
||||||
}
|
}
|
||||||
|
|
||||||
func distanceThresholdWithGroupCount(_ count: Int) -> CGFloat {
|
func distanceThresholdWithGroupCount(_ count: Int) -> CGFloat {
|
||||||
return 0.0
|
return CGFloat.greatestFiniteMagnitude
|
||||||
}
|
}
|
||||||
|
|
||||||
func linkSelectionRects(at point: CGPoint) -> [CGRect] {
|
func linkSelectionRects(at point: CGPoint) -> [CGRect] {
|
||||||
|
|||||||
@ -269,7 +269,7 @@ func layoutInstantPageBlock(webpage: TelegramMediaWebpage, rtl: Bool, block: Ins
|
|||||||
for subBlock in blocks {
|
for subBlock in blocks {
|
||||||
let subLayout = layoutInstantPageBlock(webpage: webpage, rtl: rtl, block: subBlock, boundingWidth: boundingWidth - horizontalInset * 2.0 - indexSpacing - maxIndexWidth, horizontalInset: 0.0, safeInset: 0.0, isCover: false, previousItems: listItems, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights)
|
let subLayout = layoutInstantPageBlock(webpage: webpage, rtl: rtl, block: subBlock, boundingWidth: boundingWidth - horizontalInset * 2.0 - indexSpacing - maxIndexWidth, horizontalInset: 0.0, safeInset: 0.0, isCover: false, previousItems: listItems, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights)
|
||||||
|
|
||||||
let spacing: CGFloat = previousBlock != nil ? spacingBetweenBlocks(upper: previousBlock, lower: subBlock) : 0.0
|
let spacing: CGFloat = previousBlock != nil && subLayout.contentSize.height > 0.0 ? spacingBetweenBlocks(upper: previousBlock, lower: subBlock) : 0.0
|
||||||
let blockItems = subLayout.flattenedItemsWithOrigin(CGPoint(x: horizontalInset + indexSpacing + maxIndexWidth, y: contentSize.height + spacing))
|
let blockItems = subLayout.flattenedItemsWithOrigin(CGPoint(x: horizontalInset + indexSpacing + maxIndexWidth, y: contentSize.height + spacing))
|
||||||
if previousBlock == nil {
|
if previousBlock == nil {
|
||||||
originY += spacing
|
originY += spacing
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import TelegramCore
|
|||||||
func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?) -> CGFloat {
|
func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?) -> CGFloat {
|
||||||
if let upper = upper, let lower = lower {
|
if let upper = upper, let lower = lower {
|
||||||
switch (upper, lower) {
|
switch (upper, lower) {
|
||||||
case (_, .cover), (_, .channelBanner), (.details, .details), (.relatedArticles, nil), (.anchor, _), (_, .anchor):
|
case (_, .cover), (_, .channelBanner), (.details, .details), (.relatedArticles, nil), (_, .anchor):
|
||||||
return 0.0
|
return 0.0
|
||||||
case (.divider, _), (_, .divider):
|
case (.divider, _), (_, .divider):
|
||||||
return 25.0
|
return 25.0
|
||||||
@ -49,7 +49,7 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?) ->
|
|||||||
}
|
}
|
||||||
} else if let lower = lower {
|
} else if let lower = lower {
|
||||||
switch lower {
|
switch lower {
|
||||||
case .cover, .channelBanner, .details:
|
case .cover, .channelBanner, .details, .anchor:
|
||||||
return 0.0
|
return 0.0
|
||||||
default:
|
default:
|
||||||
return 25.0
|
return 25.0
|
||||||
|
|||||||
@ -108,6 +108,8 @@ final class InstantPageTableItem: InstantPageScrollableItem {
|
|||||||
fileprivate let cells: [InstantPageTableCellItem]
|
fileprivate let cells: [InstantPageTableCellItem]
|
||||||
private let borderWidth: CGFloat
|
private let borderWidth: CGFloat
|
||||||
|
|
||||||
|
let anchors: [String: CGFloat]
|
||||||
|
|
||||||
fileprivate init(frame: CGRect, totalWidth: CGFloat, horizontalInset: CGFloat, borderWidth: CGFloat, theme: InstantPageTheme, cells: [InstantPageTableCellItem], rtl: Bool) {
|
fileprivate init(frame: CGRect, totalWidth: CGFloat, horizontalInset: CGFloat, borderWidth: CGFloat, theme: InstantPageTheme, cells: [InstantPageTableCellItem], rtl: Bool) {
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
self.totalWidth = totalWidth
|
self.totalWidth = totalWidth
|
||||||
@ -116,6 +118,20 @@ final class InstantPageTableItem: InstantPageScrollableItem {
|
|||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.cells = cells
|
self.cells = cells
|
||||||
self.isRTL = rtl
|
self.isRTL = rtl
|
||||||
|
|
||||||
|
var anchors: [String: CGFloat] = [:]
|
||||||
|
for cell in cells {
|
||||||
|
if let textItem = cell.textItem {
|
||||||
|
for (anchor, lineIndex) in textItem.anchors {
|
||||||
|
if anchors[anchor] == nil {
|
||||||
|
let textItemFrame = textItem.frame.offsetBy(dx: cell.frame.minX, dy: cell.frame.minY)
|
||||||
|
let offset = textItemFrame.minY + textItem.lines[lineIndex].frame.minY
|
||||||
|
anchors[anchor] = offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.anchors = anchors
|
||||||
}
|
}
|
||||||
|
|
||||||
var contentSize: CGSize {
|
var contentSize: CGSize {
|
||||||
|
|||||||
@ -553,6 +553,7 @@ func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFlo
|
|||||||
var lastIndex: CFIndex = 0
|
var lastIndex: CFIndex = 0
|
||||||
var currentLineOrigin = CGPoint()
|
var currentLineOrigin = CGPoint()
|
||||||
|
|
||||||
|
var hasAnchors = false
|
||||||
var maxLineWidth: CGFloat = 0.0
|
var maxLineWidth: CGFloat = 0.0
|
||||||
var maxImageHeight: CGFloat = 0.0
|
var maxImageHeight: CGFloat = 0.0
|
||||||
var extraDescent: CGFloat = 0.0
|
var extraDescent: CGFloat = 0.0
|
||||||
@ -677,6 +678,10 @@ func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFlo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !anchorItems.isEmpty {
|
||||||
|
hasAnchors = true
|
||||||
|
}
|
||||||
|
|
||||||
if hadExtraDescent && extraDescent > 0 {
|
if hadExtraDescent && extraDescent > 0 {
|
||||||
workingLineOrigin.y += fontLineSpacing
|
workingLineOrigin.y += fontLineSpacing
|
||||||
}
|
}
|
||||||
@ -706,7 +711,7 @@ func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFlo
|
|||||||
}
|
}
|
||||||
|
|
||||||
var height: CGFloat = 0.0
|
var height: CGFloat = 0.0
|
||||||
if !lines.isEmpty {
|
if !lines.isEmpty && !(string.length == 1 && hasAnchors) {
|
||||||
height = lines.last!.frame.maxY + extraDescent
|
height = lines.last!.frame.maxY + extraDescent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -634,7 +634,7 @@ private func userInfoEntries(account: Account, presentationData: PresentationDat
|
|||||||
entries.append(UserInfoEntry.addContact(presentationData.theme, presentationData.strings.UserInfo_AddContact))
|
entries.append(UserInfoEntry.addContact(presentationData.theme, presentationData.strings.UserInfo_AddContact))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let cachedUserData = cachedPeerData as? CachedUserData, !(cachedUserData.hasAccountPeerPhone ?? false) {
|
if let cachedUserData = cachedPeerData as? CachedUserData, let hasAccountPeerPhone = cachedUserData.hasAccountPeerPhone, !hasAccountPeerPhone {
|
||||||
entries.append(UserInfoEntry.shareMyContact(presentationData.theme, presentationData.strings.UserInfo_ShareMyContactInfo))
|
entries.append(UserInfoEntry.shareMyContact(presentationData.theme, presentationData.strings.UserInfo_ShareMyContactInfo))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user