Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
overtake 2019-11-27 15:52:20 +04:00
commit cb6377bfac
159 changed files with 4982 additions and 4326 deletions

View File

@ -5114,6 +5114,7 @@ Any member of this group will be able to see messages in the channel.";
"Theme.Colors.ColorWallpaperWarning" = "Are you sure you want to change your chat wallpaper to a color?";
"Theme.Colors.ColorWallpaperWarningProceed" = "Proceed";
"ChatSettings.IntentsSettings" = "Share Sheet";
"IntentsSettings.Title" = "Share Sheet";
"IntentsSettings.MainAccount" = "Main Account";
"IntentsSettings.MainAccountInfo" = "Choose an account for Siri and share suggestions.";
@ -5146,3 +5147,9 @@ Any member of this group will be able to see messages in the channel.";
"Map.SendThisPlace" = "Send This Place";
"Map.SetThisPlace" = "Set This Place";
"Map.AddressOnMap" = "Address On Map";
"Map.PlacesNearby" = "Places Nearby";
"Map.Home" = "Home";
"Map.Work" = "Work";
"Map.HomeAndWorkTitle" = "Home & Work Addresses";
"Map.HomeAndWorkInfo" = "Telegram uses the Home and Work addresses from your Contact Card.\n\nKeep your Contact Card up to date for quick access to sending Home and Work addresses.";

View File

@ -135,9 +135,13 @@ final class PeerView: UIView {
title.append("\n")
title.append(lastName)
}
let systemFontSize = UIFont.preferredFont(forTextStyle: .body).pointSize
let fontSize = floor(systemFontSize * 11.0 / 17.0)
self.titleLabel.text = title
self.titleLabel.textColor = primaryColor
self.titleLabel.font = UIFont.systemFont(ofSize: 11.0)
self.titleLabel.font = UIFont.systemFont(ofSize: fontSize)
self.titleLabel.lineBreakMode = .byTruncatingTail
self.titleLabel.numberOfLines = 2
self.titleLabel.textAlignment = .center

View File

@ -54,10 +54,12 @@ class TodayViewController: UIViewController, NCWidgetProviding {
presentationData = WidgetPresentationData(applicationLockedString: "Unlock the app to use widget")
}
let fontSize = UIFont.preferredFont(forTextStyle: .body).pointSize
if let data = try? Data(contentsOf: URL(fileURLWithPath: appLockStatePath(rootPath: rootPath))), let state = try? JSONDecoder().decode(LockState.self, from: data), isAppLocked(state: state) {
let appLockedLabel = UILabel()
appLockedLabel.textColor = self.primaryColor
appLockedLabel.font = UIFont.systemFont(ofSize: 16.0)
appLockedLabel.font = UIFont.systemFont(ofSize: fontSize)
appLockedLabel.text = presentationData.applicationLockedString
appLockedLabel.sizeToFit()
self.appLockedLabel = appLockedLabel

View File

@ -48,7 +48,7 @@ private let avatarFont = avatarPlaceholderFont(size: 15.0)
public class ActionSheetPeerItemNode: ActionSheetItemNode {
private let theme: ActionSheetControllerTheme
public static let defaultFont: UIFont = Font.regular(20.0)
private let defaultFont: UIFont
private var item: ActionSheetPeerItem?
@ -62,6 +62,8 @@ public class ActionSheetPeerItemNode: ActionSheetItemNode {
override public init(theme: ActionSheetControllerTheme) {
self.theme = theme
self.defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.button = HighlightTrackingButton()
self.button.isAccessibilityElement = false
@ -114,8 +116,10 @@ public class ActionSheetPeerItemNode: ActionSheetItemNode {
func setItem(_ item: ActionSheetPeerItem) {
self.item = item
let defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
let textColor: UIColor = self.theme.primaryTextColor
self.label.attributedText = NSAttributedString(string: item.title, font: ActionSheetButtonNode.defaultFont, textColor: textColor)
self.label.attributedText = NSAttributedString(string: item.title, font: defaultFont, textColor: textColor)
self.avatarNode.setPeer(account: item.account, theme: item.theme, peer: item.peer)

View File

@ -42,11 +42,11 @@ final class BotCheckoutPaymentMethodSheetController: ActionSheetController {
let theme = presentationData.theme
let strings = presentationData.strings
super.init(theme: ActionSheetControllerTheme(presentationTheme: theme))
super.init(theme: ActionSheetControllerTheme(presentationData: presentationData))
self.presentationDisposable = context.sharedContext.presentationData.start(next: { [weak self] presentationData in
if let strongSelf = self {
strongSelf.theme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
strongSelf.theme = ActionSheetControllerTheme(presentationData: presentationData)
}
})
@ -137,7 +137,7 @@ public class BotCheckoutPaymentMethodItem: ActionSheetItem {
}
public class BotCheckoutPaymentMethodItemNode: ActionSheetItemNode {
public static let defaultFont: UIFont = Font.regular(20.0)
private let defaultFont: UIFont
private let theme: ActionSheetControllerTheme
@ -150,6 +150,7 @@ public class BotCheckoutPaymentMethodItemNode: ActionSheetItemNode {
public override init(theme: ActionSheetControllerTheme) {
self.theme = theme
self.defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.button = HighlightTrackingButton()
@ -201,7 +202,7 @@ public class BotCheckoutPaymentMethodItemNode: ActionSheetItemNode {
func setItem(_ item: BotCheckoutPaymentMethodItem) {
self.item = item
self.titleNode.attributedText = NSAttributedString(string: item.title, font: BotCheckoutPaymentMethodItemNode.defaultFont, textColor: self.theme.primaryTextColor)
self.titleNode.attributedText = NSAttributedString(string: item.title, font: self.defaultFont, textColor: self.theme.primaryTextColor)
self.iconNode.image = item.icon
if let value = item.value {
self.checkNode.isHidden = !value

View File

@ -16,11 +16,11 @@ final class BotCheckoutPaymentShippingOptionSheetController: ActionSheetControll
let theme = presentationData.theme
let strings = presentationData.strings
super.init(theme: ActionSheetControllerTheme(presentationTheme: theme))
super.init(theme: ActionSheetControllerTheme(presentationData: presentationData))
self.presentationDisposable = context.sharedContext.presentationData.start(next: { [weak self] presentationData in
if let strongSelf = self {
strongSelf.theme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
strongSelf.theme = ActionSheetControllerTheme(presentationData: presentationData)
}
})
@ -113,7 +113,7 @@ public class BotCheckoutPaymentShippingOptionItem: ActionSheetItem {
}
public class BotCheckoutPaymentShippingOptionItemNode: ActionSheetItemNode {
public static let defaultFont: UIFont = Font.regular(20.0)
private let defaultFont: UIFont
private let theme: ActionSheetControllerTheme
@ -126,6 +126,7 @@ public class BotCheckoutPaymentShippingOptionItemNode: ActionSheetItemNode {
public override init(theme: ActionSheetControllerTheme) {
self.theme = theme
self.defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.button = HighlightTrackingButton()
@ -178,8 +179,8 @@ public class BotCheckoutPaymentShippingOptionItemNode: ActionSheetItemNode {
func setItem(_ item: BotCheckoutPaymentShippingOptionItem) {
self.item = item
self.titleNode.attributedText = NSAttributedString(string: item.title, font: BotCheckoutPaymentShippingOptionItemNode.defaultFont, textColor: self.theme.primaryTextColor)
self.labelNode.attributedText = NSAttributedString(string: item.label, font: BotCheckoutPaymentShippingOptionItemNode.defaultFont, textColor: self.theme.primaryTextColor)
self.titleNode.attributedText = NSAttributedString(string: item.title, font: self.defaultFont, textColor: self.theme.primaryTextColor)
self.labelNode.attributedText = NSAttributedString(string: item.label, font: self.defaultFont, textColor: self.theme.primaryTextColor)
if let value = item.value {
self.checkNode.isHidden = !value
} else {

View File

@ -17,6 +17,8 @@ public enum ChatListSearchItemHeaderType: Int32 {
case phoneNumber
case exceptions
case addToExceptions
case mapAddress
case nearbyVenues
}
public final class ChatListSearchItemHeader: ListViewItemHeader {
@ -30,7 +32,7 @@ public final class ChatListSearchItemHeader: ListViewItemHeader {
public let height: CGFloat = 28.0
public init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String?, action: (() -> Void)?) {
public init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String? = nil, action: (() -> Void)? = nil) {
self.type = type
self.id = Int64(self.type.rawValue)
self.theme = theme
@ -93,6 +95,10 @@ public final class ChatListSearchItemHeaderNode: ListViewItemHeaderNode {
self.sectionHeaderNode.title = strings.GroupInfo_Permissions_Exceptions.uppercased()
case .addToExceptions:
self.sectionHeaderNode.title = strings.Exceptions_AddToExceptions.uppercased()
case .mapAddress:
self.sectionHeaderNode.title = strings.Map_AddressOnMap.uppercased()
case .nearbyVenues:
self.sectionHeaderNode.title = strings.Map_PlacesNearby.uppercased()
}
self.sectionHeaderNode.action = actionTitle

View File

@ -308,7 +308,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
if case .root = groupId, checkProxy {
if strongSelf.proxyUnavailableTooltipController == nil && !strongSelf.didShowProxyUnavailableTooltipController && strongSelf.isNodeLoaded && strongSelf.displayNode.view.window != nil {
strongSelf.didShowProxyUnavailableTooltipController = true
let tooltipController = TooltipController(content: .text(strongSelf.presentationData.strings.Proxy_TooltipUnavailable), timeout: 60.0, dismissByTapOutside: true)
let tooltipController = TooltipController(content: .text(strongSelf.presentationData.strings.Proxy_TooltipUnavailable), baseFontSize: strongSelf.presentationData.fontSize.baseDisplaySize, timeout: 60.0, dismissByTapOutside: true)
strongSelf.proxyUnavailableTooltipController = tooltipController
tooltipController.dismissed = { [weak tooltipController] _ in
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.proxyUnavailableTooltipController === tooltipController {
@ -588,7 +588,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
self.chatListDisplayNode.requestOpenRecentPeerOptions = { [weak self] peer in
if let strongSelf = self {
strongSelf.view.window?.endEditing(true)
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
actionSheet.setItemGroups([
ActionSheetItemGroup(items: [
@ -669,12 +669,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
case let .groupReference(groupReference):
let chatListController = ChatListControllerImpl(context: strongSelf.context, groupId: groupReference.groupId, controlsHistoryPreload: false, hideNetworkActivityStatus: true, previewing: true, enableDebugActions: false)
chatListController.navigationPresentation = .master
let contextController = ContextController(account: strongSelf.context.account, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, source: .controller(ContextControllerContentSourceImpl(controller: chatListController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: archiveContextMenuItems(context: strongSelf.context, groupId: groupReference.groupId, chatListController: strongSelf), reactionItems: [], gesture: gesture)
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatListController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: archiveContextMenuItems(context: strongSelf.context, groupId: groupReference.groupId, chatListController: strongSelf), reactionItems: [], gesture: gesture)
strongSelf.presentInGlobalOverlay(contextController)
case let .peer(peer):
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(peer.peer.peerId), subject: nil, botStart: nil, mode: .standard(previewing: true))
chatController.canReadHistory.set(false)
let contextController = ContextController(account: strongSelf.context.account, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: chatContextMenuItems(context: strongSelf.context, peerId: peer.peer.peerId, source: .chatList, chatListController: strongSelf), reactionItems: [], gesture: gesture)
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: chatContextMenuItems(context: strongSelf.context, peerId: peer.peer.peerId, source: .chatList, chatListController: strongSelf), reactionItems: [], gesture: gesture)
strongSelf.presentInGlobalOverlay(contextController)
}
}
@ -687,7 +687,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(peer.id), subject: nil, botStart: nil, mode: .standard(previewing: true))
chatController.canReadHistory.set(false)
let contextController = ContextController(account: strongSelf.context.account, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: chatContextMenuItems(context: strongSelf.context, peerId: peer.id, source: .search(source), chatListController: strongSelf), reactionItems: [], gesture: gesture)
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: chatContextMenuItems(context: strongSelf.context, peerId: peer.id, source: .search(source), chatListController: strongSelf), reactionItems: [], gesture: gesture)
strongSelf.presentInGlobalOverlay(contextController)
}
@ -798,7 +798,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
if hasPasscode {
let _ = ApplicationSpecificNotice.setPasscodeLockTips(accountManager: strongSelf.context.sharedContext.accountManager).start()
let tooltipController = TooltipController(content: .text(strongSelf.presentationData.strings.DialogList_PasscodeLockHelp), dismissByTapOutside: true)
let tooltipController = TooltipController(content: .text(strongSelf.presentationData.strings.DialogList_PasscodeLockHelp), baseFontSize: strongSelf.presentationData.fontSize.baseDisplaySize, dismissByTapOutside: true)
strongSelf.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceViewAndRect: { [weak self] in
if let strongSelf = self {
return (strongSelf.titleView, lockViewFrame.offsetBy(dx: 4.0, dy: 14.0))
@ -1199,7 +1199,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
self?.donePressed()
})
} else if case .right = action, !peerIds.isEmpty {
let actionSheet = ActionSheetController(presentationTheme: self.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: self.presentationData)
var items: [ActionSheetItem] = []
items.append(ActionSheetButtonItem(title: self.presentationData.strings.ChatList_DeleteConfirmation(Int32(peerIds.count)), color: .destructive, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated()
@ -1385,7 +1385,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
if let user = chatPeer as? TelegramUser, user.botInfo == nil, canRemoveGlobally {
strongSelf.maybeAskForPeerChatRemoval(peer: peer, completion: { _ in }, removed: {})
} else {
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
var items: [ActionSheetItem] = []
var canClear = true
var canStop = false
@ -1468,7 +1468,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
}
if canRemoveGlobally {
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
var items: [ActionSheetItem] = []
items.append(DeleteChatPeerActionSheetItem(context: strongSelf.context, peer: mainPeer, chatPeer: chatPeer, action: .clearHistory, strings: strongSelf.presentationData.strings, nameDisplayOrder: strongSelf.presentationData.nameDisplayOrder))
@ -1556,7 +1556,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
}
if canRemoveGlobally {
let actionSheet = ActionSheetController(presentationTheme: self.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: self.presentationData)
var items: [ActionSheetItem] = []
items.append(DeleteChatPeerActionSheetItem(context: self.context, peer: mainPeer, chatPeer: chatPeer, action: .delete, strings: self.presentationData.strings, nameDisplayOrder: self.presentationData.nameDisplayOrder))

View File

@ -774,7 +774,10 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
let enableChatListPhotos = item.context.sharedContext.immediateExperimentalUISettings.chatListPhotos
let leftInset: CGFloat = params.leftInset + 78.0
let avatarDiameter = floor(item.presentationData.fontSize.baseDisplaySize * 60.0 / 17.0)
let avatarLeftInset = 18.0 + avatarDiameter
let leftInset: CGFloat = params.leftInset + avatarLeftInset
enum ContentData {
case chat(itemPeer: RenderedPeer, peer: Peer?, hideAuthor: Bool, messageText: String)
@ -1337,7 +1340,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
transition.updateAlpha(node: strongSelf.statusNode, alpha: 1.0)
}
let avatarFrame = CGRect(origin: CGPoint(x: leftInset - 78.0 + editingOffset + 10.0 + revealOffset, y: floor((layout.contentSize.height - 60.0) / 2.0)), size: CGSize(width: 60.0, height: 60.0))
let avatarFrame = CGRect(origin: CGPoint(x: leftInset - avatarLeftInset + editingOffset + 10.0 + revealOffset, y: floor((layout.contentSize.height - avatarDiameter) / 2.0)), size: CGSize(width: avatarDiameter, height: avatarDiameter))
transition.updateFrame(node: strongSelf.avatarNode, frame: avatarFrame)
let onlineFrame = CGRect(origin: CGPoint(x: avatarFrame.maxX - onlineLayout.width - 2.0, y: avatarFrame.maxY - onlineLayout.height - 2.0), size: onlineLayout)
@ -1417,7 +1420,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
strongSelf.secretIconNode = iconNode
}
iconNode.image = currentSecretIconImage
transition.updateFrame(node: iconNode, frame: CGRect(origin: CGPoint(x: contentRect.origin.x, y: contentRect.origin.y + 4.0), size: currentSecretIconImage.size))
transition.updateFrame(node: iconNode, frame: CGRect(origin: CGPoint(x: contentRect.origin.x, y: contentRect.origin.y + floor((strongSelf.titleNode.frame.height - currentSecretIconImage.size.height) / 2.0)), size: currentSecretIconImage.size))
titleOffset += currentSecretIconImage.size.width + 3.0
} else if let secretIconNode = strongSelf.secretIconNode {
strongSelf.secretIconNode = nil
@ -1616,7 +1619,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
override func updateRevealOffset(offset: CGFloat, transition: ContainedViewLayoutTransition) {
super.updateRevealOffset(offset: offset, transition: transition)
if let _ = self.item, let params = self.layoutParams?.5, let countersSize = self.layoutParams?.6 {
if let item = self.item, let params = self.layoutParams?.5, let countersSize = self.layoutParams?.6 {
let editingOffset: CGFloat
if let selectableControlNode = self.selectableControlNode {
editingOffset = selectableControlNode.bounds.size.width
@ -1635,14 +1638,17 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
transition.updateFrame(node: reorderControlNode, frame: reorderControlFrame)
}
let leftInset: CGFloat = params.leftInset + 78.0
let avatarDiameter = floor(item.presentationData.fontSize.baseDisplaySize * 60.0 / 17.0)
let avatarLeftInset = 18.0 + avatarDiameter
let leftInset: CGFloat = params.leftInset + avatarLeftInset
let rawContentRect = CGRect(origin: CGPoint(x: 2.0, y: layoutOffset + 8.0), size: CGSize(width: params.width - leftInset - params.rightInset - 10.0 - 1.0 - editingOffset, height: self.bounds.size.height - 12.0 - 9.0))
let contentRect = rawContentRect.offsetBy(dx: editingOffset + leftInset + offset, dy: 0.0)
var avatarFrame = self.avatarNode.frame
avatarFrame.origin.x = leftInset - 78.0 + editingOffset + 10.0 + offset
avatarFrame.origin.x = leftInset - avatarLeftInset + editingOffset + 10.0 + offset
transition.updateFrame(node: self.avatarNode, frame: avatarFrame)
var onlineFrame = self.onlineNode.frame

View File

@ -40,7 +40,9 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder:
processed = true
break inner
case let .Audio(isVoice, _, title, performer, _):
if isVoice {
if !message.text.isEmpty {
messageText = "🎤 \(messageText)"
} else if isVoice {
if message.text.isEmpty {
messageText = strings.Message_Audio
} else {

View File

@ -495,7 +495,7 @@ public class ContactsController: ViewController {
}
}
let actionSheet = ActionSheetController(presentationTheme: self.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: self.presentationData)
var items: [ActionSheetItem] = []
items.append(ActionSheetTextItem(title: self.presentationData.strings.Contacts_SortBy))
items.append(ActionSheetButtonItem(title: self.presentationData.strings.Contacts_SortByName, color: .accent, action: { [weak actionSheet] in

View File

@ -193,7 +193,7 @@ final class ContactsControllerNode: ASDisplayNode {
}
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(peer.id), subject: nil, botStart: nil, mode: .standard(previewing: true))
chatController.canReadHistory.set(false)
let contextController = ContextController(account: self.context.account, theme: self.presentationData.theme, strings: self.presentationData.strings, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: contactContextMenuItems(context: self.context, peerId: peer.id, contactsController: contactsController), reactionItems: [], gesture: gesture)
let contextController = ContextController(account: self.context.account, presentationData: self.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: contactContextMenuItems(context: self.context, peerId: peer.id, contactsController: contactsController), reactionItems: [], gesture: gesture)
contactsController.presentInGlobalOverlay(contextController)
}

View File

@ -435,7 +435,8 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize)
let titleBoldFont = Font.medium(item.presentationData.fontSize.itemListBaseFontSize)
let statusFont = Font.regular(floor(item.presentationData.fontSize.itemListBaseFontSize * 13.0 / 17.0))
let badgeFont = Font.regular(floor(item.presentationData.fontSize.itemListBaseFontSize * 14.0 / 17.0))
let badgeFont = Font.regular(14.0)
let avatarDiameter = min(40.0, floor(item.presentationData.fontSize.itemListBaseFontSize * 40.0 / 17.0))
if currentItem?.presentationData.theme !== item.presentationData.theme {
updatedTheme = item.presentationData.theme
@ -611,7 +612,8 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(0.0, params.width - leftInset - rightInset - badgeSize), height: CGFloat.infinity), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let verticalInset: CGFloat = statusAttributedString == nil ? 11.0 : 6.0
let titleVerticalInset: CGFloat = statusAttributedString == nil ? 13.0 : 6.0
let verticalInset: CGFloat = statusAttributedString == nil ? 13.0 : 6.0
let statusHeightComponent: CGFloat
if statusAttributedString == nil {
@ -624,7 +626,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
let titleFrame: CGRect
if statusAttributedString != nil {
titleFrame = CGRect(origin: CGPoint(x: leftInset, y: verticalInset), size: titleLayout.size)
titleFrame = CGRect(origin: CGPoint(x: leftInset, y: titleVerticalInset), size: titleLayout.size)
} else {
titleFrame = CGRect(origin: CGPoint(x: leftInset, y: floor((nodeLayout.contentSize.height - titleLayout.size.height) / 2.0)), size: titleLayout.size)
}
@ -707,7 +709,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor
}
transition.updateFrame(node: strongSelf.avatarNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset - 50.0, y: floor((nodeLayout.contentSize.height - 40.0) / 2.0)), size: CGSize(width: 40.0, height: 40.0)))
transition.updateFrame(node: strongSelf.avatarNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset - 50.0, y: floor((nodeLayout.contentSize.height - avatarDiameter) / 2.0)), size: CGSize(width: avatarDiameter, height: avatarDiameter)))
let _ = titleApply()
transition.updateFrame(node: strongSelf.titleNode, frame: titleFrame.offsetBy(dx: revealOffset, dy: 0.0))

View File

@ -3,8 +3,6 @@ import AsyncDisplayKit
import Display
import TelegramPresentationData
private let textFont = Font.regular(17.0)
enum ContextActionSibling {
case none
case item
@ -23,17 +21,19 @@ final class ContextActionNode: ASDisplayNode {
private let iconNode: ASImageNode
private let buttonNode: HighlightTrackingButtonNode
init(theme: PresentationTheme, action: ContextMenuActionItem, getController: @escaping () -> ContextController?, actionSelected: @escaping (ContextMenuActionResult) -> Void) {
init(presentationData: PresentationData, action: ContextMenuActionItem, getController: @escaping () -> ContextController?, actionSelected: @escaping (ContextMenuActionResult) -> Void) {
self.action = action
self.getController = getController
self.actionSelected = actionSelected
let textFont = Font.regular(presentationData.fontSize.baseDisplaySize)
self.backgroundNode = ASDisplayNode()
self.backgroundNode.isAccessibilityElement = false
self.backgroundNode.backgroundColor = theme.contextMenu.itemBackgroundColor
self.backgroundNode.backgroundColor = presentationData.theme.contextMenu.itemBackgroundColor
self.highlightedBackgroundNode = ASDisplayNode()
self.highlightedBackgroundNode.isAccessibilityElement = false
self.highlightedBackgroundNode.backgroundColor = theme.contextMenu.itemHighlightedBackgroundColor
self.highlightedBackgroundNode.backgroundColor = presentationData.theme.contextMenu.itemHighlightedBackgroundColor
self.highlightedBackgroundNode.alpha = 0.0
self.textNode = ImmediateTextNode()
@ -43,9 +43,9 @@ final class ContextActionNode: ASDisplayNode {
let textColor: UIColor
switch action.textColor {
case .primary:
textColor = theme.contextMenu.primaryColor
textColor = presentationData.theme.contextMenu.primaryColor
case .destructive:
textColor = theme.contextMenu.destructiveColor
textColor = presentationData.theme.contextMenu.destructiveColor
}
self.textNode.attributedText = NSAttributedString(string: action.text, font: textFont, textColor: textColor)
@ -62,7 +62,7 @@ final class ContextActionNode: ASDisplayNode {
statusNode.isAccessibilityElement = false
statusNode.isUserInteractionEnabled = false
statusNode.displaysAsynchronously = false
statusNode.attributedText = NSAttributedString(string: value, font: textFont, textColor: theme.contextMenu.secondaryColor)
statusNode.attributedText = NSAttributedString(string: value, font: textFont, textColor: presentationData.theme.contextMenu.secondaryColor)
statusNode.maximumNumberOfLines = 1
self.statusNode = statusNode
}
@ -72,7 +72,7 @@ final class ContextActionNode: ASDisplayNode {
self.iconNode.displaysAsynchronously = false
self.iconNode.displayWithoutProcessing = true
self.iconNode.isUserInteractionEnabled = false
self.iconNode.image = action.icon(theme)
self.iconNode.image = action.icon(presentationData.theme)
self.buttonNode = HighlightTrackingButtonNode()
self.buttonNode.isAccessibilityElement = true
@ -149,27 +149,30 @@ final class ContextActionNode: ASDisplayNode {
}
}
func updateTheme(theme: PresentationTheme) {
self.backgroundNode.backgroundColor = theme.contextMenu.itemBackgroundColor
self.highlightedBackgroundNode.backgroundColor = theme.contextMenu.itemHighlightedBackgroundColor
func updateTheme(presentationData: PresentationData) {
self.backgroundNode.backgroundColor = presentationData.theme.contextMenu.itemBackgroundColor
self.highlightedBackgroundNode.backgroundColor = presentationData.theme.contextMenu.itemHighlightedBackgroundColor
let textColor: UIColor
switch action.textColor {
case .primary:
textColor = theme.contextMenu.primaryColor
textColor = presentationData.theme.contextMenu.primaryColor
case .destructive:
textColor = theme.contextMenu.destructiveColor
textColor = presentationData.theme.contextMenu.destructiveColor
}
let textFont = Font.regular(presentationData.fontSize.baseDisplaySize)
self.textNode.attributedText = NSAttributedString(string: self.action.text, font: textFont, textColor: textColor)
switch self.action.textLayout {
case let .secondLineWithValue(value):
self.statusNode?.attributedText = NSAttributedString(string: value, font: textFont, textColor: theme.contextMenu.secondaryColor)
self.statusNode?.attributedText = NSAttributedString(string: value, font: textFont, textColor: presentationData.theme.contextMenu.secondaryColor)
default:
break
}
self.iconNode.image = self.action.icon(theme)
self.iconNode.image = self.action.icon(presentationData.theme)
}
@objc private func buttonPressed() {

View File

@ -39,7 +39,7 @@ private enum ContextItemNode {
}
final class ContextActionsContainerNode: ASDisplayNode {
private let theme: PresentationTheme
private let presentationData: PresentationData
private var effectView: UIVisualEffectView?
private var itemNodes: [ContextItemNode]
private let feedbackTap: () -> Void
@ -47,23 +47,23 @@ final class ContextActionsContainerNode: ASDisplayNode {
private(set) var gesture: UIGestureRecognizer?
private var currentHighlightedActionNode: ContextActionNode?
init(theme: PresentationTheme, items: [ContextMenuItem], getController: @escaping () -> ContextController?, actionSelected: @escaping (ContextMenuActionResult) -> Void, feedbackTap: @escaping () -> Void) {
self.theme = theme
init(presentationData: PresentationData, items: [ContextMenuItem], getController: @escaping () -> ContextController?, actionSelected: @escaping (ContextMenuActionResult) -> Void, feedbackTap: @escaping () -> Void) {
self.presentationData = presentationData
self.feedbackTap = feedbackTap
var itemNodes: [ContextItemNode] = []
for i in 0 ..< items.count {
switch items[i] {
case let .action(action):
itemNodes.append(.action(ContextActionNode(theme: theme, action: action, getController: getController, actionSelected: actionSelected)))
itemNodes.append(.action(ContextActionNode(presentationData: presentationData, action: action, getController: getController, actionSelected: actionSelected)))
if i != items.count - 1, case .action = items[i + 1] {
let separatorNode = ASDisplayNode()
separatorNode.backgroundColor = theme.contextMenu.itemSeparatorColor
separatorNode.backgroundColor = presentationData.theme.contextMenu.itemSeparatorColor
itemNodes.append(.itemSeparator(separatorNode))
}
case .separator:
let separatorNode = ASDisplayNode()
separatorNode.backgroundColor = theme.contextMenu.sectionSeparatorColor
separatorNode.backgroundColor = presentationData.theme.contextMenu.sectionSeparatorColor
itemNodes.append(.separator(separatorNode))
}
}
@ -75,7 +75,7 @@ final class ContextActionsContainerNode: ASDisplayNode {
self.clipsToBounds = true
self.cornerRadius = 14.0
self.backgroundColor = theme.contextMenu.backgroundColor
self.backgroundColor = presentationData.theme.contextMenu.backgroundColor
self.itemNodes.forEach({ itemNode in
switch itemNode {
@ -133,7 +133,7 @@ final class ContextActionsContainerNode: ASDisplayNode {
if self.effectView == nil {
let effectView: UIVisualEffectView
if #available(iOS 13.0, *) {
if self.theme.overallDarkAppearance {
if self.presentationData.theme.overallDarkAppearance {
effectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterialDark))
} else {
effectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterialLight))
@ -213,19 +213,19 @@ final class ContextActionsContainerNode: ASDisplayNode {
return size
}
func updateTheme(theme: PresentationTheme) {
func updateTheme(presentationData: PresentationData) {
for itemNode in self.itemNodes {
switch itemNode {
case let .action(action):
action.updateTheme(theme: theme)
action.updateTheme(presentationData: presentationData)
case let .separator(separator):
separator.backgroundColor = theme.contextMenu.sectionSeparatorColor
separator.backgroundColor = presentationData.theme.contextMenu.sectionSeparatorColor
case let .itemSeparator(itemSeparator):
itemSeparator.backgroundColor = theme.contextMenu.itemSeparatorColor
itemSeparator.backgroundColor = presentationData.theme.contextMenu.itemSeparatorColor
}
}
self.backgroundColor = theme.contextMenu.backgroundColor
self.backgroundColor = presentationData.theme.contextMenu.backgroundColor
}
func actionNode(at point: CGPoint) -> ContextActionNode? {

View File

@ -60,8 +60,7 @@ private func convertFrame(_ frame: CGRect, from fromView: UIView, to toView: UIV
}
private final class ContextControllerNode: ViewControllerTracingNode, UIScrollViewDelegate {
private var theme: PresentationTheme
private var strings: PresentationStrings
private var presentationData: PresentationData
private let source: ContextContentSource
private var items: Signal<[ContextMenuItem], NoError>
private let beginDismiss: (ContextMenuActionResult) -> Void
@ -108,9 +107,8 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
private let itemsDisposable = MetaDisposable()
init(account: Account, controller: ContextController, theme: PresentationTheme, strings: PresentationStrings, source: ContextContentSource, items: Signal<[ContextMenuItem], NoError>, reactionItems: [ReactionContextItem], beginDismiss: @escaping (ContextMenuActionResult) -> Void, recognizer: TapLongTapOrDoubleTapGestureRecognizer?, gesture: ContextGesture?, reactionSelected: @escaping (String) -> Void, beganAnimatingOut: @escaping () -> Void, attemptTransitionControllerIntoNavigation: @escaping () -> Void) {
self.theme = theme
self.strings = strings
init(account: Account, controller: ContextController, presentationData: PresentationData, source: ContextContentSource, items: Signal<[ContextMenuItem], NoError>, reactionItems: [ReactionContextItem], beginDismiss: @escaping (ContextMenuActionResult) -> Void, recognizer: TapLongTapOrDoubleTapGestureRecognizer?, gesture: ContextGesture?, reactionSelected: @escaping (String) -> Void, beganAnimatingOut: @escaping () -> Void, attemptTransitionControllerIntoNavigation: @escaping () -> Void) {
self.presentationData = presentationData
self.source = source
self.items = items
self.beginDismiss = beginDismiss
@ -126,7 +124,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
self.effectView = UIVisualEffectView()
if #available(iOS 9.0, *) {
} else {
if theme.rootController.keyboardColor == .dark {
if presentationData.theme.rootController.keyboardColor == .dark {
self.effectView.effect = UIBlurEffect(style: .dark)
} else {
self.effectView.effect = UIBlurEffect(style: .light)
@ -135,7 +133,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
}
self.dimNode = ASDisplayNode()
self.dimNode.backgroundColor = theme.contextMenu.dimColor
self.dimNode.backgroundColor = presentationData.theme.contextMenu.dimColor
self.dimNode.alpha = 0.0
self.withoutBlurDimNode = ASDisplayNode()
@ -159,7 +157,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
var feedbackTap: (() -> Void)?
self.actionsContainerNode = ContextActionsContainerNode(theme: theme, items: [], getController: { [weak controller] in
self.actionsContainerNode = ContextActionsContainerNode(presentationData: presentationData, items: [], getController: { [weak controller] in
return controller
}, actionSelected: { result in
beginDismiss(result)
@ -168,7 +166,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
})
if !reactionItems.isEmpty {
let reactionContextNode = ReactionContextNode(account: account, theme: theme, items: reactionItems)
let reactionContextNode = ReactionContextNode(account: account, theme: presentationData.theme, items: reactionItems)
self.reactionContextNode = reactionContextNode
} else {
self.reactionContextNode = nil
@ -966,7 +964,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
self.currentItems = items
let previousActionsContainerNode = self.actionsContainerNode
self.actionsContainerNode = ContextActionsContainerNode(theme: self.theme, items: items, getController: { [weak self] in
self.actionsContainerNode = ContextActionsContainerNode(presentationData: self.presentationData, items: items, getController: { [weak self] in
return self?.getController()
}, actionSelected: { [weak self] result in
self?.beginDismiss(result)
@ -988,11 +986,11 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
}
}
func updateTheme(theme: PresentationTheme) {
self.theme = theme
func updateTheme(presentationData: PresentationData) {
self.presentationData = presentationData
self.dimNode.backgroundColor = theme.contextMenu.dimColor
self.actionsContainerNode.updateTheme(theme: theme)
self.dimNode.backgroundColor = presentationData.theme.contextMenu.dimColor
self.actionsContainerNode.updateTheme(presentationData: presentationData)
if let validLayout = self.validLayout {
self.updateLayout(layout: validLayout, transition: .immediate, previousActionsContainerNode: nil)
@ -1364,8 +1362,7 @@ public enum ContextContentSource {
public final class ContextController: ViewController, StandalonePresentableController {
private let account: Account
private var theme: PresentationTheme
private var strings: PresentationStrings
private var presentationData: PresentationData
private let source: ContextContentSource
private var items: Signal<[ContextMenuItem], NoError>
private var reactionItems: [ReactionContextItem]
@ -1387,10 +1384,9 @@ public final class ContextController: ViewController, StandalonePresentableContr
public var reactionSelected: ((String) -> Void)?
public init(account: Account, theme: PresentationTheme, strings: PresentationStrings, source: ContextContentSource, items: Signal<[ContextMenuItem], NoError>, reactionItems: [ReactionContextItem], recognizer: TapLongTapOrDoubleTapGestureRecognizer? = nil, gesture: ContextGesture? = nil) {
public init(account: Account, presentationData: PresentationData, source: ContextContentSource, items: Signal<[ContextMenuItem], NoError>, reactionItems: [ReactionContextItem], recognizer: TapLongTapOrDoubleTapGestureRecognizer? = nil, gesture: ContextGesture? = nil) {
self.account = account
self.theme = theme
self.strings = strings
self.presentationData = presentationData
self.source = source
self.items = items
self.reactionItems = reactionItems
@ -1407,7 +1403,7 @@ public final class ContextController: ViewController, StandalonePresentableContr
}
override public func loadDisplayNode() {
self.displayNode = ContextControllerNode(account: self.account, controller: self, theme: self.theme, strings: self.strings, source: self.source, items: self.items, reactionItems: self.reactionItems, beginDismiss: { [weak self] result in
self.displayNode = ContextControllerNode(account: self.account, controller: self, presentationData: self.presentationData, source: self.source, items: self.items, reactionItems: self.reactionItems, beginDismiss: { [weak self] result in
self?.dismiss(result: result, completion: nil)
}, recognizer: self.recognizer, gesture: self.gesture, reactionSelected: { [weak self] value in
guard let strongSelf = self else {
@ -1464,10 +1460,10 @@ public final class ContextController: ViewController, StandalonePresentableContr
}
}
public func updateTheme(theme: PresentationTheme) {
self.theme = theme
public func updateTheme(presentationData: PresentationData) {
self.presentationData = presentationData
if self.isNodeLoaded {
self.controllerNode.updateTheme(theme: theme)
self.controllerNode.updateTheme(presentationData: presentationData)
}
}

View File

@ -20,11 +20,11 @@ public final class DateSelectionActionSheetController: ActionSheetController {
let theme = presentationData.theme
let strings = presentationData.strings
super.init(theme: ActionSheetControllerTheme(presentationTheme: theme))
super.init(theme: ActionSheetControllerTheme(presentationData: presentationData))
self.presentationDisposable = context.sharedContext.presentationData.start(next: { [weak self] presentationData in
if let strongSelf = self {
strongSelf.theme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
strongSelf.theme = ActionSheetControllerTheme(presentationData: presentationData)
}
})

View File

@ -56,6 +56,8 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode {
self.theme = theme
self.strings = strings
let peerFont = Font.regular(floor(theme.baseFontSize * 14.0 / 17.0))
self.avatarNode = AvatarNode(font: avatarFont)
self.avatarNode.isAccessibilityElement = false
@ -88,9 +90,9 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode {
case .clearCache, .clearCacheSuggestion:
switch action {
case .clearCache:
attributedText = NSAttributedString(string: strings.ClearCache_Description, font: Font.regular(14.0), textColor: theme.primaryTextColor)
attributedText = NSAttributedString(string: strings.ClearCache_Description, font: peerFont, textColor: theme.primaryTextColor)
case .clearCacheSuggestion:
attributedText = NSAttributedString(string: strings.ClearCache_FreeSpaceDescription, font: Font.regular(14.0), textColor: theme.primaryTextColor)
attributedText = NSAttributedString(string: strings.ClearCache_FreeSpaceDescription, font: peerFont, textColor: theme.primaryTextColor)
default:
break
}
@ -115,9 +117,9 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode {
break
}
if let text = text {
var formattedAttributedText = NSMutableAttributedString(attributedString: NSAttributedString(string: text.0, font: Font.regular(14.0), textColor: theme.primaryTextColor))
var formattedAttributedText = NSMutableAttributedString(attributedString: NSAttributedString(string: text.0, font: peerFont, textColor: theme.primaryTextColor))
for (_, range) in text.1 {
formattedAttributedText.addAttribute(.font, value: Font.semibold(14.0), range: range)
formattedAttributedText.addAttribute(.font, value: peerFont, range: range)
}
attributedText = formattedAttributedText
}

View File

@ -244,7 +244,7 @@ public final class DeviceAccess {
}
}
public static func authorizeAccess(to subject: DeviceAccessSubject, registerForNotifications: ((@escaping (Bool) -> Void) -> Void)? = nil, requestSiriAuthorization: ((@escaping (Bool) -> Void) -> Void)? = nil, presentationData: PresentationData? = nil, present: @escaping (ViewController, Any?) -> Void = { _, _ in }, openSettings: @escaping () -> Void = { }, displayNotificationFromBackground: @escaping (String) -> Void = { _ in }, _ completion: @escaping (Bool) -> Void = { _ in }) {
public static func authorizeAccess(to subject: DeviceAccessSubject, registerForNotifications: ((@escaping (Bool) -> Void) -> Void)? = nil, requestSiriAuthorization: ((@escaping (Bool) -> Void) -> Void)? = nil, locationManager: CLLocationManager? = nil, presentationData: PresentationData? = nil, present: @escaping (ViewController, Any?) -> Void = { _, _ in }, openSettings: @escaping () -> Void = { }, displayNotificationFromBackground: @escaping (String) -> Void = { _ in }, _ completion: @escaping (Bool) -> Void = { _ in }) {
switch subject {
case .camera:
let status = PGCamera.cameraAuthorizationStatus()
@ -382,7 +382,14 @@ public final class DeviceAccess {
})]), nil)
}
case .notDetermined:
completion(true)
switch locationSubject {
case .send:
locationManager?.requestWhenInUseAuthorization()
case .live:
locationManager?.requestAlwaysAuthorization()
default:
break
}
@unknown default:
fatalError()
}

View File

@ -47,8 +47,8 @@ public class ActionSheetButtonItem: ActionSheetItem {
public class ActionSheetButtonNode: ActionSheetItemNode {
private let theme: ActionSheetControllerTheme
public static let defaultFont: UIFont = Font.regular(20.0)
public static let boldFont: UIFont = Font.medium(20.0)
private let defaultFont: UIFont
private let boldFont: UIFont
private var item: ActionSheetButtonItem?
@ -59,6 +59,9 @@ public class ActionSheetButtonNode: ActionSheetItemNode {
override public init(theme: ActionSheetControllerTheme) {
self.theme = theme
self.defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.boldFont = Font.medium(floor(theme.baseFontSize * 20.0 / 17.0))
self.button = HighlightTrackingButton()
self.button.isAccessibilityElement = false
@ -113,9 +116,9 @@ public class ActionSheetButtonNode: ActionSheetItemNode {
}
switch item.font {
case .default:
textFont = ActionSheetButtonNode.defaultFont
textFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
case .bold:
textFont = ActionSheetButtonNode.boldFont
textFont = Font.medium(floor(theme.baseFontSize * 20.0 / 17.0))
}
self.label.attributedText = NSAttributedString(string: item.title, font: textFont, textColor: textColor)
self.label.isAccessibilityElement = false

View File

@ -39,7 +39,7 @@ public class ActionSheetCheckboxItem: ActionSheetItem {
}
public class ActionSheetCheckboxItemNode: ActionSheetItemNode {
public static let defaultFont: UIFont = Font.regular(20.0)
private let defaultFont: UIFont
private let theme: ActionSheetControllerTheme
@ -54,6 +54,7 @@ public class ActionSheetCheckboxItemNode: ActionSheetItemNode {
override public init(theme: ActionSheetControllerTheme) {
self.theme = theme
self.defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.button = HighlightTrackingButton()
self.button.isAccessibilityElement = false
@ -118,8 +119,10 @@ public class ActionSheetCheckboxItemNode: ActionSheetItemNode {
func setItem(_ item: ActionSheetCheckboxItem) {
self.item = item
self.titleNode.attributedText = NSAttributedString(string: item.title, font: ActionSheetCheckboxItemNode.defaultFont, textColor: self.theme.primaryTextColor)
self.labelNode.attributedText = NSAttributedString(string: item.label, font: ActionSheetCheckboxItemNode.defaultFont, textColor: self.theme.secondaryTextColor)
let defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.titleNode.attributedText = NSAttributedString(string: item.title, font: defaultFont, textColor: self.theme.primaryTextColor)
self.labelNode.attributedText = NSAttributedString(string: item.label, font: defaultFont, textColor: self.theme.secondaryTextColor)
self.checkNode.isHidden = !item.value
self.accessibilityArea.accessibilityLabel = item.title

View File

@ -42,6 +42,7 @@ public class ActionSheetSwitchNode: ActionSheetItemNode {
override public init(theme: ActionSheetControllerTheme) {
self.theme = theme
let defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.button = HighlightTrackingButton()
self.button.isAccessibilityElement = false
@ -85,7 +86,9 @@ public class ActionSheetSwitchNode: ActionSheetItemNode {
func setItem(_ item: ActionSheetSwitchItem) {
self.item = item
self.label.attributedText = NSAttributedString(string: item.title, font: ActionSheetButtonNode.defaultFont, textColor: self.theme.primaryTextColor)
let defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.label.attributedText = NSAttributedString(string: item.title, font: defaultFont, textColor: self.theme.primaryTextColor)
self.label.isAccessibilityElement = false
self.switchNode.isOn = item.isOn

View File

@ -26,7 +26,7 @@ public class ActionSheetTextItem: ActionSheetItem {
}
public class ActionSheetTextNode: ActionSheetItemNode {
public static let defaultFont: UIFont = Font.regular(13.0)
private let defaultFont: UIFont
private let theme: ActionSheetControllerTheme
@ -38,6 +38,7 @@ public class ActionSheetTextNode: ActionSheetItemNode {
override public init(theme: ActionSheetControllerTheme) {
self.theme = theme
self.defaultFont = Font.regular(floor(theme.baseFontSize * 13.0 / 17.0))
self.label = ASTextNode()
self.label.isUserInteractionEnabled = false
@ -60,7 +61,9 @@ public class ActionSheetTextNode: ActionSheetItemNode {
func setItem(_ item: ActionSheetTextItem) {
self.item = item
self.label.attributedText = NSAttributedString(string: item.title, font: ActionSheetTextNode.defaultFont, textColor: self.theme.secondaryTextColor, paragraphAlignment: .center)
let defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.label.attributedText = NSAttributedString(string: item.title, font: defaultFont, textColor: self.theme.secondaryTextColor, paragraphAlignment: .center)
self.accessibilityArea.accessibilityLabel = item.title
self.setNeedsLayout()

View File

@ -21,8 +21,9 @@ public final class ActionSheetControllerTheme: Equatable {
public let switchFrameColor: UIColor
public let switchContentColor: UIColor
public let switchHandleColor: UIColor
public let baseFontSize: CGFloat
public init(dimColor: UIColor, backgroundType: ActionSheetControllerThemeBackgroundType, itemBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, standardActionTextColor: UIColor, destructiveActionTextColor: UIColor, disabledActionTextColor: UIColor, primaryTextColor: UIColor, secondaryTextColor: UIColor, controlAccentColor: UIColor, controlColor: UIColor, switchFrameColor: UIColor, switchContentColor: UIColor, switchHandleColor: UIColor) {
public init(dimColor: UIColor, backgroundType: ActionSheetControllerThemeBackgroundType, itemBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, standardActionTextColor: UIColor, destructiveActionTextColor: UIColor, disabledActionTextColor: UIColor, primaryTextColor: UIColor, secondaryTextColor: UIColor, controlAccentColor: UIColor, controlColor: UIColor, switchFrameColor: UIColor, switchContentColor: UIColor, switchHandleColor: UIColor, baseFontSize: CGFloat) {
self.dimColor = dimColor
self.backgroundType = backgroundType
self.itemBackgroundColor = itemBackgroundColor
@ -37,6 +38,7 @@ public final class ActionSheetControllerTheme: Equatable {
self.switchFrameColor = switchFrameColor
self.switchContentColor = switchContentColor
self.switchHandleColor = switchHandleColor
self.baseFontSize = min(26.0, baseFontSize)
}
public static func ==(lhs: ActionSheetControllerTheme, rhs: ActionSheetControllerTheme) -> Bool {
@ -82,6 +84,9 @@ public final class ActionSheetControllerTheme: Equatable {
if lhs.switchHandleColor != rhs.switchHandleColor {
return false
}
if lhs.baseFontSize != rhs.baseFontSize {
return false
}
return true
}
}

View File

@ -14,6 +14,7 @@ public class ImmediateTextNode: TextNode {
public var lineSpacing: CGFloat = 0.0
public var insets: UIEdgeInsets = UIEdgeInsets()
public var textShadowColor: UIColor?
public var textStroke: (UIColor, CGFloat)?
private var tapRecognizer: TapLongTapOrDoubleTapGestureRecognizer?
private var linkHighlightingNode: LinkHighlightingNode?
@ -35,7 +36,7 @@ public class ImmediateTextNode: TextNode {
public func updateLayout(_ constrainedSize: CGSize) -> CGSize {
let makeLayout = TextNode.asyncLayout(self)
let (layout, apply) = makeLayout(TextNodeLayoutArguments(attributedString: self.attributedText, backgroundColor: nil, maximumNumberOfLines: self.maximumNumberOfLines, truncationType: self.truncationType, constrainedSize: constrainedSize, alignment: self.textAlignment, lineSpacing: self.lineSpacing, cutout: nil, insets: self.insets, textShadowColor: self.textShadowColor))
let (layout, apply) = makeLayout(TextNodeLayoutArguments(attributedString: self.attributedText, backgroundColor: nil, maximumNumberOfLines: self.maximumNumberOfLines, truncationType: self.truncationType, constrainedSize: constrainedSize, alignment: self.textAlignment, lineSpacing: self.lineSpacing, cutout: nil, insets: self.insets, textShadowColor: self.textShadowColor, textStroke: self.textStroke))
let _ = apply()
if layout.numberOfLines > 1 {
self.trailingLineWidth = layout.trailingLineWidth

View File

@ -2413,7 +2413,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
//print("replay after \(self.itemNodes.map({"\($0.index) \(unsafeAddressOf($0))"}))")
}
if let scrollToItem = scrollToItem, !self.areAllItemsOnScreen() {
if let scrollToItem = scrollToItem, !self.areAllItemsOnScreen() || updateSizeAndInsets == nil {
self.stopScrolling()
for itemNode in self.itemNodes {

View File

@ -95,8 +95,9 @@ public final class TextNodeLayoutArguments {
public let insets: UIEdgeInsets
public let lineColor: UIColor?
public let textShadowColor: UIColor?
public let textStroke: (UIColor, CGFloat)?
public init(attributedString: NSAttributedString?, backgroundColor: UIColor? = nil, minimumNumberOfLines: Int = 0, maximumNumberOfLines: Int, truncationType: CTLineTruncationType, constrainedSize: CGSize, alignment: NSTextAlignment = .natural, lineSpacing: CGFloat = 0.12, cutout: TextNodeCutout? = nil, insets: UIEdgeInsets = UIEdgeInsets(), lineColor: UIColor? = nil, textShadowColor: UIColor? = nil) {
public init(attributedString: NSAttributedString?, backgroundColor: UIColor? = nil, minimumNumberOfLines: Int = 0, maximumNumberOfLines: Int, truncationType: CTLineTruncationType, constrainedSize: CGSize, alignment: NSTextAlignment = .natural, lineSpacing: CGFloat = 0.12, cutout: TextNodeCutout? = nil, insets: UIEdgeInsets = UIEdgeInsets(), lineColor: UIColor? = nil, textShadowColor: UIColor? = nil, textStroke: (UIColor, CGFloat)? = nil) {
self.attributedString = attributedString
self.backgroundColor = backgroundColor
self.minimumNumberOfLines = minimumNumberOfLines
@ -109,6 +110,7 @@ public final class TextNodeLayoutArguments {
self.insets = insets
self.lineColor = lineColor
self.textShadowColor = textShadowColor
self.textStroke = textStroke
}
}
@ -130,9 +132,10 @@ public final class TextNodeLayout: NSObject {
fileprivate let blockQuotes: [TextNodeBlockQuote]
fileprivate let lineColor: UIColor?
fileprivate let textShadowColor: UIColor?
fileprivate let textStroke: (UIColor, CGFloat)?
public let hasRTL: Bool
fileprivate init(attributedString: NSAttributedString?, maximumNumberOfLines: Int, truncationType: CTLineTruncationType, constrainedSize: CGSize, alignment: NSTextAlignment, lineSpacing: CGFloat, cutout: TextNodeCutout?, insets: UIEdgeInsets, size: CGSize, rawTextSize: CGSize, truncated: Bool, firstLineOffset: CGFloat, lines: [TextNodeLine], blockQuotes: [TextNodeBlockQuote], backgroundColor: UIColor?, lineColor: UIColor?, textShadowColor: UIColor?) {
fileprivate init(attributedString: NSAttributedString?, maximumNumberOfLines: Int, truncationType: CTLineTruncationType, constrainedSize: CGSize, alignment: NSTextAlignment, lineSpacing: CGFloat, cutout: TextNodeCutout?, insets: UIEdgeInsets, size: CGSize, rawTextSize: CGSize, truncated: Bool, firstLineOffset: CGFloat, lines: [TextNodeLine], blockQuotes: [TextNodeBlockQuote], backgroundColor: UIColor?, lineColor: UIColor?, textShadowColor: UIColor?, textStroke: (UIColor, CGFloat)?) {
self.attributedString = attributedString
self.maximumNumberOfLines = maximumNumberOfLines
self.truncationType = truncationType
@ -150,6 +153,7 @@ public final class TextNodeLayout: NSObject {
self.backgroundColor = backgroundColor
self.lineColor = lineColor
self.textShadowColor = textShadowColor
self.textStroke = textStroke
var hasRTL = false
for line in lines {
if line.isRTL {
@ -780,7 +784,7 @@ public class TextNode: ASDisplayNode {
}
}
private class func calculateLayout(attributedString: NSAttributedString?, minimumNumberOfLines: Int, maximumNumberOfLines: Int, truncationType: CTLineTruncationType, backgroundColor: UIColor?, constrainedSize: CGSize, alignment: NSTextAlignment, lineSpacingFactor: CGFloat, cutout: TextNodeCutout?, insets: UIEdgeInsets, lineColor: UIColor?, textShadowColor: UIColor?) -> TextNodeLayout {
private class func calculateLayout(attributedString: NSAttributedString?, minimumNumberOfLines: Int, maximumNumberOfLines: Int, truncationType: CTLineTruncationType, backgroundColor: UIColor?, constrainedSize: CGSize, alignment: NSTextAlignment, lineSpacingFactor: CGFloat, cutout: TextNodeCutout?, insets: UIEdgeInsets, lineColor: UIColor?, textShadowColor: UIColor?, textStroke: (UIColor, CGFloat)?) -> TextNodeLayout {
if let attributedString = attributedString {
let stringLength = attributedString.length
@ -806,7 +810,7 @@ public class TextNode: ASDisplayNode {
var maybeTypesetter: CTTypesetter?
maybeTypesetter = CTTypesetterCreateWithAttributedString(attributedString as CFAttributedString)
if maybeTypesetter == nil {
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(), rawTextSize: CGSize(), truncated: false, firstLineOffset: 0.0, lines: [], blockQuotes: [], backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor)
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(), rawTextSize: CGSize(), truncated: false, firstLineOffset: 0.0, lines: [], blockQuotes: [], backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor, textStroke: textStroke)
}
let typesetter = maybeTypesetter!
@ -1010,9 +1014,9 @@ public class TextNode: ASDisplayNode {
}
}
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(width: ceil(layoutSize.width) + insets.left + insets.right, height: ceil(layoutSize.height) + insets.top + insets.bottom), rawTextSize: CGSize(width: ceil(rawLayoutSize.width) + insets.left + insets.right, height: ceil(rawLayoutSize.height) + insets.top + insets.bottom), truncated: truncated, firstLineOffset: firstLineOffset, lines: lines, blockQuotes: blockQuotes, backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor)
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(width: ceil(layoutSize.width) + insets.left + insets.right, height: ceil(layoutSize.height) + insets.top + insets.bottom), rawTextSize: CGSize(width: ceil(rawLayoutSize.width) + insets.left + insets.right, height: ceil(rawLayoutSize.height) + insets.top + insets.bottom), truncated: truncated, firstLineOffset: firstLineOffset, lines: lines, blockQuotes: blockQuotes, backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor, textStroke: textStroke)
} else {
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(), rawTextSize: CGSize(), truncated: false, firstLineOffset: 0.0, lines: [], blockQuotes: [], backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor)
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(), rawTextSize: CGSize(), truncated: false, firstLineOffset: 0.0, lines: [], blockQuotes: [], backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor, textStroke: textStroke)
}
}
@ -1050,6 +1054,14 @@ public class TextNode: ASDisplayNode {
context.setShadow(offset: CGSize(width: 0.0, height: 1.0), blur: 0.0, color: textShadowColor.cgColor)
}
// if let (textStrokeColor, textStrokeWidth) = layout.textStroke {
// context.setBlendMode(.normal)
// context.setLineCap(.round)
// context.setLineJoin(.round)
// context.setStrokeColor(textStrokeColor.cgColor)
// context.setLineWidth(textStrokeWidth)
// }
let textMatrix = context.textMatrix
let textPosition = context.textPosition
context.textMatrix = CGAffineTransform(scaleX: 1.0, y: -1.0)
@ -1156,11 +1168,11 @@ public class TextNode: ASDisplayNode {
if stringMatch {
layout = existingLayout
} else {
layout = TextNode.calculateLayout(attributedString: arguments.attributedString, minimumNumberOfLines: arguments.minimumNumberOfLines, maximumNumberOfLines: arguments.maximumNumberOfLines, truncationType: arguments.truncationType, backgroundColor: arguments.backgroundColor, constrainedSize: arguments.constrainedSize, alignment: arguments.alignment, lineSpacingFactor: arguments.lineSpacing, cutout: arguments.cutout, insets: arguments.insets, lineColor: arguments.lineColor, textShadowColor: arguments.textShadowColor)
layout = TextNode.calculateLayout(attributedString: arguments.attributedString, minimumNumberOfLines: arguments.minimumNumberOfLines, maximumNumberOfLines: arguments.maximumNumberOfLines, truncationType: arguments.truncationType, backgroundColor: arguments.backgroundColor, constrainedSize: arguments.constrainedSize, alignment: arguments.alignment, lineSpacingFactor: arguments.lineSpacing, cutout: arguments.cutout, insets: arguments.insets, lineColor: arguments.lineColor, textShadowColor: arguments.textShadowColor, textStroke: arguments.textStroke)
updated = true
}
} else {
layout = TextNode.calculateLayout(attributedString: arguments.attributedString, minimumNumberOfLines: arguments.minimumNumberOfLines, maximumNumberOfLines: arguments.maximumNumberOfLines, truncationType: arguments.truncationType, backgroundColor: arguments.backgroundColor, constrainedSize: arguments.constrainedSize, alignment: arguments.alignment, lineSpacingFactor: arguments.lineSpacing, cutout: arguments.cutout, insets: arguments.insets, lineColor: arguments.lineColor, textShadowColor: arguments.textShadowColor)
layout = TextNode.calculateLayout(attributedString: arguments.attributedString, minimumNumberOfLines: arguments.minimumNumberOfLines, maximumNumberOfLines: arguments.maximumNumberOfLines, truncationType: arguments.truncationType, backgroundColor: arguments.backgroundColor, constrainedSize: arguments.constrainedSize, alignment: arguments.alignment, lineSpacingFactor: arguments.lineSpacing, cutout: arguments.cutout, insets: arguments.insets, lineColor: arguments.lineColor, textShadowColor: arguments.textShadowColor, textStroke: arguments.textStroke)
updated = true
}

View File

@ -62,6 +62,7 @@ open class TooltipController: ViewController, StandalonePresentableController {
}
public private(set) var content: TooltipControllerContent
private let baseFontSize: CGFloat
open func updateContent(_ content: TooltipControllerContent, animated: Bool, extendTimer: Bool, arrowOnBottom: Bool = true) {
if self.content != content {
@ -89,8 +90,9 @@ open class TooltipController: ViewController, StandalonePresentableController {
public var dismissed: ((Bool) -> Void)?
public init(content: TooltipControllerContent, timeout: Double = 2.0, dismissByTapOutside: Bool = false, dismissByTapOutsideSource: Bool = false, dismissImmediatelyOnLayoutUpdate: Bool = false, arrowOnBottom: Bool = true) {
public init(content: TooltipControllerContent, baseFontSize: CGFloat, timeout: Double = 2.0, dismissByTapOutside: Bool = false, dismissByTapOutsideSource: Bool = false, dismissImmediatelyOnLayoutUpdate: Bool = false, arrowOnBottom: Bool = true) {
self.content = content
self.baseFontSize = baseFontSize
self.timeout = timeout
self.dismissByTapOutside = dismissByTapOutside
self.dismissByTapOutsideSource = dismissByTapOutsideSource
@ -111,7 +113,7 @@ open class TooltipController: ViewController, StandalonePresentableController {
}
override open func loadDisplayNode() {
self.displayNode = TooltipControllerNode(content: self.content, dismiss: { [weak self] tappedInside in
self.displayNode = TooltipControllerNode(content: self.content, baseFontSize: self.baseFontSize, dismiss: { [weak self] tappedInside in
self?.dismiss(tappedInside: tappedInside)
}, dismissByTapOutside: self.dismissByTapOutside, dismissByTapOutsideSource: self.dismissByTapOutsideSource)
self.controllerNode.arrowOnBottom = self.initialArrowOnBottom

View File

@ -3,6 +3,8 @@ import UIKit
import AsyncDisplayKit
final class TooltipControllerNode: ASDisplayNode {
private let baseFontSize: CGFloat
private let dismiss: (Bool) -> Void
private var validLayout: ContainerViewLayout?
@ -19,7 +21,9 @@ final class TooltipControllerNode: ASDisplayNode {
private var dismissedByTouchOutside = false
private var dismissByTapOutsideSource = false
init(content: TooltipControllerContent, dismiss: @escaping (Bool) -> Void, dismissByTapOutside: Bool, dismissByTapOutsideSource: Bool) {
init(content: TooltipControllerContent, baseFontSize: CGFloat, dismiss: @escaping (Bool) -> Void, dismissByTapOutside: Bool, dismissByTapOutsideSource: Bool) {
self.baseFontSize = baseFontSize
self.dismissByTapOutside = dismissByTapOutside
self.dismissByTapOutsideSource = dismissByTapOutsideSource
@ -33,7 +37,7 @@ final class TooltipControllerNode: ASDisplayNode {
if case let .attributedText(text) = content {
self.textNode.attributedText = text
} else {
self.textNode.attributedText = NSAttributedString(string: content.text, font: Font.regular(14.0), textColor: .white, paragraphAlignment: .center)
self.textNode.attributedText = NSAttributedString(string: content.text, font: Font.regular(floor(baseFontSize * 14.0 / 17.0)), textColor: .white, paragraphAlignment: .center)
}
self.textNode.isUserInteractionEnabled = false
self.textNode.displaysAsynchronously = false
@ -58,7 +62,7 @@ final class TooltipControllerNode: ASDisplayNode {
})
self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.12)
}
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(14.0), textColor: .white, paragraphAlignment: .center)
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(floor(self.baseFontSize * 14.0 / 17.0)), textColor: .white, paragraphAlignment: .center)
if let layout = self.validLayout {
self.containerLayoutUpdated(layout, transition: transition)
}

View File

@ -529,7 +529,11 @@ public enum ViewControllerNavigationPresentation {
}
open func dismiss(completion: (() -> Void)? = nil) {
(self.navigationController as? NavigationController)?.filterController(self, animated: true)
if let navigationController = self.navigationController as? NavigationController {
navigationController.filterController(self, animated: true)
} else {
self.presentingViewController?.dismiss(animated: false, completion: nil)
}
}
@available(iOSApplicationExtension 9.0, iOS 9.0, *)

View File

@ -272,6 +272,8 @@ public class Window1 {
public var previewThemeAccentColor: UIColor = .blue
public var previewThemeDarkBlur: Bool = false
private var shouldNotAnimateLikelyKeyboardAutocorrectionSwitch: Bool = false
public private(set) var forceInCallStatusBarText: String? = nil
public var inCallNavigate: (() -> Void)? {
didSet {
@ -522,7 +524,15 @@ public class Window1 {
transitionCurve = .easeInOut
}
strongSelf.updateLayout { $0.update(inputHeight: keyboardHeight.isLessThanOrEqualTo(0.0) ? nil : keyboardHeight, transition: .animated(duration: duration, curve: transitionCurve), overrideTransition: false) }
var transition: ContainedViewLayoutTransition = .animated(duration: duration, curve: transitionCurve)
if strongSelf.shouldNotAnimateLikelyKeyboardAutocorrectionSwitch, let inputHeight = strongSelf.windowLayout.inputHeight {
if abs(inputHeight - keyboardHeight) <= 44.1 {
transition = .immediate
}
}
strongSelf.updateLayout { $0.update(inputHeight: keyboardHeight.isLessThanOrEqualTo(0.0) ? nil : keyboardHeight, transition: transition, overrideTransition: false) }
}
})
@ -1203,4 +1213,11 @@ public class Window1 {
}
}
}
public func doNotAnimateLikelyKeyboardAutocorrectionSwitch() {
self.shouldNotAnimateLikelyKeyboardAutocorrectionSwitch = true
DispatchQueue.main.async {
self.shouldNotAnimateLikelyKeyboardAutocorrectionSwitch = false
}
}
}

View File

@ -106,6 +106,7 @@ class CaptionScrollWrapperNode: ASDisplayNode {
final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScrollViewDelegate {
private let context: AccountContext
private var presentationData: PresentationData
private var theme: PresentationTheme
private var strings: PresentationStrings
private var nameOrder: PresentationPersonNameOrder
@ -243,6 +244,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
init(context: AccountContext, presentationData: PresentationData) {
self.context = context
self.presentationData = presentationData
self.theme = presentationData.theme
self.strings = presentationData.strings
self.nameOrder = presentationData.nameDisplayOrder
@ -757,7 +759,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
}
}
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
let items: [ActionSheetItem] = [
ActionSheetButtonItem(title: singleText, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
@ -787,7 +789,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
private func commitDeleteMessages(_ messages: [Message], ask: Bool) {
self.messageContextDisposable.set((self.context.sharedContext.chatAvailableMessageActions(postbox: self.context.account.postbox, accountPeerId: self.context.account.peerId, messageIds: Set(messages.map { $0.id })) |> deliverOnMainQueue).start(next: { [weak self] actions in
if let strongSelf = self, let controllerInteration = strongSelf.controllerInteraction, !actions.options.isEmpty {
let actionSheet = ActionSheetController(presentationTheme: strongSelf.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
var items: [ActionSheetItem] = []
var personalPeerName: String?
var isChannel = false
@ -947,7 +949,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
}
}
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
let items: [ActionSheetItem] = [
ActionSheetButtonItem(title: singleText, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()

View File

@ -609,7 +609,7 @@ public class GalleryController: ViewController, StandalonePresentableController
} else if canOpenIn {
openText = strongSelf.presentationData.strings.Conversation_FileOpenIn
}
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
var items: [ActionSheetItem] = []
items.append(ActionSheetTextItem(title: cleanUrl))
@ -652,7 +652,7 @@ public class GalleryController: ViewController, StandalonePresentableController
])])
strongSelf.present(actionSheet, in: .window(.root))
case let .peerMention(peerId, mention):
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
var items: [ActionSheetItem] = []
if !mention.isEmpty {
items.append(ActionSheetTextItem(title: mention))
@ -677,7 +677,7 @@ public class GalleryController: ViewController, StandalonePresentableController
])])
strongSelf.present(actionSheet, in: .window(.root))
case let .textMention(mention):
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: mention),
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, color: .accent, action: { [weak actionSheet] in
@ -698,7 +698,7 @@ public class GalleryController: ViewController, StandalonePresentableController
])])
strongSelf.present(actionSheet, in: .window(.root))
case let .botCommand(command):
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
var items: [ActionSheetItem] = []
items.append(ActionSheetTextItem(title: command))
items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogCopy, color: .accent, action: { [weak actionSheet] in
@ -712,7 +712,7 @@ public class GalleryController: ViewController, StandalonePresentableController
])])
strongSelf.present(actionSheet, in: .window(.root))
case let .hashtag(peerName, hashtag):
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: hashtag),
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, color: .accent, action: { [weak actionSheet] in
@ -734,7 +734,7 @@ public class GalleryController: ViewController, StandalonePresentableController
])
strongSelf.present(actionSheet, in: .window(.root))
case let .timecode(timecode, text):
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: text),
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, color: .accent, action: { [weak actionSheet] in

View File

@ -2,6 +2,19 @@ import Foundation
import CoreLocation
import SwiftSignalKit
public func geocodeLocation(address: String) -> Signal<[CLPlacemark]?, NoError> {
return Signal { subscriber in
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) { (placemarks, _) in
subscriber.putNext(placemarks)
subscriber.putCompletion()
}
return ActionDisposable {
geocoder.cancelGeocode()
}
}
}
public func geocodeLocation(dictionary: [String: String]) -> Signal<(Double, Double)?, NoError> {
return Signal { subscriber in
let geocoder = CLGeocoder()

View File

@ -260,7 +260,7 @@ public class InstantPageGalleryController: ViewController, StandalonePresentable
if let strongSelf = self {
let canOpenIn = availableOpenInOptions(context: context, item: .url(url: url.url)).count > 1
let openText = canOpenIn ? strongSelf.presentationData.strings.Conversation_FileOpenIn : strongSelf.presentationData.strings.Conversation_LinkDialogOpen
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: url.url),
ActionSheetButtonItem(title: openText, color: .accent, action: { [weak actionSheet] in

View File

@ -323,7 +323,7 @@ func instantPageThemeForType(_ type: InstantPageThemeType, settings: InstantPage
extension ActionSheetControllerTheme {
convenience init(instantPageTheme: InstantPageTheme) {
self.init(dimColor: UIColor(white: 0.0, alpha: 0.4), backgroundType: instantPageTheme.type != .dark ? .light : .dark, itemBackgroundColor: instantPageTheme.overlayPanelColor, itemHighlightedBackgroundColor: instantPageTheme.panelHighlightedBackgroundColor, standardActionTextColor: instantPageTheme.panelAccentColor, destructiveActionTextColor: instantPageTheme.panelAccentColor, disabledActionTextColor: instantPageTheme.panelAccentColor, primaryTextColor: instantPageTheme.textCategories.paragraph.color, secondaryTextColor: instantPageTheme.textCategories.caption.color, controlAccentColor: instantPageTheme.panelAccentColor, controlColor: instantPageTheme.tableBorderColor, switchFrameColor: .white, switchContentColor: .white, switchHandleColor: .white)
self.init(dimColor: UIColor(white: 0.0, alpha: 0.4), backgroundType: instantPageTheme.type != .dark ? .light : .dark, itemBackgroundColor: instantPageTheme.overlayPanelColor, itemHighlightedBackgroundColor: instantPageTheme.panelHighlightedBackgroundColor, standardActionTextColor: instantPageTheme.panelAccentColor, destructiveActionTextColor: instantPageTheme.panelAccentColor, disabledActionTextColor: instantPageTheme.panelAccentColor, primaryTextColor: instantPageTheme.textCategories.paragraph.color, secondaryTextColor: instantPageTheme.textCategories.caption.color, controlAccentColor: instantPageTheme.panelAccentColor, controlColor: instantPageTheme.tableBorderColor, switchFrameColor: .white, switchContentColor: .white, switchHandleColor: .white, baseFontSize: 17.0)
}
}

View File

@ -178,22 +178,7 @@ public final class ItemListPresentationData: Equatable {
public extension PresentationFontSize {
var itemListBaseHeaderFontSize: CGFloat {
switch self {
case .extraSmall:
return 13.0
case .small:
return 14.0
case .medium:
return 15.0
case .regular:
return 16.0
case .large:
return 18.0
case .extraLarge:
return 22.0
case .extraLargeX2:
return 25.0
}
return floor(self.itemListBaseFontSize * 13.0 / 17.0)
}
var itemListBaseFontSize: CGFloat {

View File

@ -14,24 +14,46 @@ public final class ItemListVenueItem: ListViewItem, ItemListItem {
let presentationData: ItemListPresentationData
let account: Account
let venue: TelegramMediaMap
public let sectionId: ItemListSectionId
let title: String?
let subtitle: String?
let style: ItemListStyle
let action: (() -> Void)?
let infoAction: (() -> Void)?
public init(presentationData: ItemListPresentationData, account: Account, venue: TelegramMediaMap, sectionId: ItemListSectionId, style: ItemListStyle, action: (() -> Void)?) {
public let sectionId: ItemListSectionId
let header: ListViewItemHeader?
public init(presentationData: ItemListPresentationData, account: Account, venue: TelegramMediaMap, title: String? = nil, subtitle: String? = nil, sectionId: ItemListSectionId = 0, style: ItemListStyle, action: (() -> Void)?, infoAction: (() -> Void)? = nil, header: ListViewItemHeader? = nil) {
self.presentationData = presentationData
self.account = account
self.venue = venue
self.title = title
self.subtitle = subtitle
self.sectionId = sectionId
self.style = style
self.action = action
self.infoAction = infoAction
self.header = header
}
public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
async {
var firstWithHeader = false
var last = false
if self.style == .plain {
if previousItem == nil {
firstWithHeader = true
} else if let previousItem = previousItem as? ItemListVenueItem, self.header != nil && previousItem.header?.id != self.header?.id {
firstWithHeader = true
}
if nextItem == nil {
last = true
} else if let nextItem = nextItem as? ItemListVenueItem, self.header != nil && nextItem.header?.id != self.header?.id {
last = true
}
}
let node = ItemListVenueItemNode()
let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem), firstWithHeader, last)
node.contentSize = layout.contentSize
node.insets = layout.insets
@ -55,7 +77,21 @@ public final class ItemListVenueItem: ListViewItem, ItemListItem {
}
async {
let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
var firstWithHeader = false
var last = false
if self.style == .plain {
if previousItem == nil {
firstWithHeader = true
} else if let previousItem = previousItem as? ItemListVenueItem, self.header != nil && previousItem.header?.id != self.header?.id {
firstWithHeader = true
}
if nextItem == nil {
last = true
} else if let nextItem = nextItem as? ItemListVenueItem, self.header != nil && nextItem.header?.id != self.header?.id {
last = true
}
}
let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem), firstWithHeader, last)
Queue.mainQueue().async {
completion(layout, { _ in
apply()
@ -84,8 +120,10 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
private let iconNode: TransformImageNode
private let titleNode: TextNode
private let addressNode: TextNode
private let infoButton: HighlightableButtonNode
private var layoutParams: (ItemListVenueItem, ListViewItemLayoutParams, ItemListNeighbors)?
private var item: ItemListVenueItem?
private var layoutParams: (ItemListVenueItem, ListViewItemLayoutParams, ItemListNeighbors, Bool, Bool)?
public var tag: ItemListItemTag?
@ -119,6 +157,8 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
self.addressNode.isUserInteractionEnabled = false
self.addressNode.contentMode = .left
self.addressNode.contentsScale = UIScreen.main.scale
self.infoButton = HighlightableButtonNode()
self.highlightedBackgroundNode = ASDisplayNode()
self.highlightedBackgroundNode.isLayerBacked = true
@ -130,16 +170,19 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
self.addSubnode(self.iconNode)
self.addSubnode(self.titleNode)
self.addSubnode(self.addressNode)
self.addSubnode(self.infoButton)
self.infoButton.addTarget(self, action: #selector(self.infoPressed), forControlEvents: .touchUpInside)
}
public func asyncLayout() -> (_ item: ItemListVenueItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
public func asyncLayout() -> (_ item: ItemListVenueItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors, _ firstWithHeader: Bool, _ last: Bool) -> (ListViewItemNodeLayout, () -> Void) {
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
let makeAddressLayout = TextNode.asyncLayout(self.addressNode)
let iconLayout = self.iconNode.asyncLayout()
let currentItem = self.layoutParams?.0
return { item, params, neighbors in
return { item, params, neighbors, firstWithHeader, last in
var updatedTheme: PresentationTheme?
var updatedVenueType: String?
@ -155,11 +198,29 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
updatedVenueType = venueType
}
let titleAttributedString = NSAttributedString(string: item.venue.venue?.title ?? "", font: titleFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor)
let addressAttributedString = NSAttributedString(string: item.venue.venue?.address ?? "", font: addressFont, textColor: item.presentationData.theme.list.itemSecondaryTextColor)
let title: String
if let venueTitle = item.venue.venue?.title {
title = venueTitle
} else if let customTitle = item.title {
title = customTitle
} else {
title = ""
}
let subtitle: String
if let address = item.venue.venue?.address {
subtitle = address
} else if let customSubtitle = item.subtitle {
subtitle = customSubtitle
} else {
subtitle = ""
}
let titleAttributedString = NSAttributedString(string: title, font: titleFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor)
let addressAttributedString = NSAttributedString(string: subtitle, font: addressFont, textColor: item.presentationData.theme.list.itemSecondaryTextColor)
let leftInset: CGFloat = 65.0 + params.leftInset
let rightInset: CGFloat = 16.0 + params.rightInset
let rightInset: CGFloat = 16.0 + params.rightInset + (item.infoAction != nil ? 48.0 : 0.0)
let verticalInset: CGFloat = addressAttributedString.string.isEmpty ? 14.0 : 8.0
let iconSize: CGFloat = 40.0
@ -179,6 +240,7 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
itemBackgroundColor = item.presentationData.theme.list.plainBackgroundColor
itemSeparatorColor = item.presentationData.theme.list.itemPlainSeparatorColor
insets = itemListNeighborsPlainInsets(neighbors)
insets.top = firstWithHeader ? 29.0 : 0.0
insets.bottom = 0.0
case .blocks:
itemBackgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
@ -193,7 +255,8 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
return (layout, { [weak self] in
if let strongSelf = self {
strongSelf.layoutParams = (item, params, neighbors)
strongSelf.item = item
strongSelf.layoutParams = (item, params, neighbors, firstWithHeader, last)
strongSelf.accessibilityLabel = titleAttributedString.string
strongSelf.accessibilityValue = addressAttributedString.string
@ -203,6 +266,7 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
strongSelf.bottomStripeNode.backgroundColor = itemSeparatorColor
strongSelf.backgroundNode.backgroundColor = itemBackgroundColor
strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor
strongSelf.infoButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Location/InfoIcon"), color: item.presentationData.theme.list.itemAccentColor), for: .normal)
}
let transition = ContainedViewLayoutTransition.immediate
@ -239,7 +303,7 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
stripeInset = leftInset
}
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: stripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - stripeInset, height: separatorHeight))
strongSelf.bottomStripeNode.isHidden = false
strongSelf.bottomStripeNode.isHidden = last
case .blocks:
if strongSelf.backgroundNode.supernode == nil {
strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
@ -287,6 +351,9 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
transition.updateFrame(node: strongSelf.iconNode, frame: CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: floorToScreenPixels((layout.contentSize.height - iconSize) / 2.0)), size: CGSize(width: iconSize, height: iconSize)))
transition.updateFrame(node: strongSelf.infoButton, frame: CGRect(x: layout.contentSize.width - params.rightInset - 60.0, y: 0.0, width: 60.0, height: layout.contentSize.height))
strongSelf.infoButton.isHidden = item.infoAction == nil
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: contentSize.height + UIScreenPixel + UIScreenPixel))
}
})
@ -338,4 +405,12 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
override public func animateRemoved(_ currentTimestamp: Double, duration: Double) {
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
}
@objc private func infoPressed() {
self.item?.infoAction?()
}
override public func header() -> ListViewItemHeader? {
return self.item?.header
}
}

View File

@ -257,7 +257,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
if (_cameraView)
[_collectionView addSubview:_cameraView];
_sendMediaItemView = [[TGMenuSheetButtonItemView alloc] initWithTitle:nil type:TGMenuSheetButtonTypeSend action:^
_sendMediaItemView = [[TGMenuSheetButtonItemView alloc] initWithTitle:nil type:TGMenuSheetButtonTypeSend fontSize:20.0 action:^
{
__strong TGAttachmentCarouselItemView *strongSelf = weakSelf;
if (strongSelf != nil && strongSelf.sendPressed != nil)
@ -272,7 +272,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
if (!_document)
{
_sendFileItemView = [[TGMenuSheetButtonItemView alloc] initWithTitle:nil type:TGMenuSheetButtonTypeDefault action:^
_sendFileItemView = [[TGMenuSheetButtonItemView alloc] initWithTitle:nil type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGAttachmentCarouselItemView *strongSelf = weakSelf;
if (strongSelf != nil && strongSelf.sendPressed != nil)

View File

@ -1050,7 +1050,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
NSArray *items = @
[
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Camera.Discard") type:TGMenuSheetButtonTypeDefault action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Camera.Discard") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)
@ -1063,7 +1063,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
[strongController dismissAnimated:true manual:false completion:nil];
[strongSelf beginTransitionOutWithVelocity:0.0f];
}],
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController != nil)

View File

@ -64,7 +64,7 @@
sendTitle = [NSString stringWithFormat:format, [NSString stringWithFormat:@"%ld", photosCount]];
}
TGMenuSheetButtonItemView *sendItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:sendTitle type:TGMenuSheetButtonTypeSend action:^
TGMenuSheetButtonItemView *sendItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:sendTitle type:TGMenuSheetButtonTypeSend fontSize:20.0 action:^
{
__strong TGClipboardPreviewItemView *strongPreviewItem = weakPreviewItem;
completed(strongPreviewItem.selectionContext, strongPreviewItem.editingContext, nil);
@ -90,7 +90,7 @@
[strongPreviewItem setCollapsed:count == 0 animated:true];
};
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
[strongController dismissAnimated:true];

View File

@ -167,12 +167,14 @@ const CGFloat TGLocationInfoCellHeight = 134.0f;
_titleLabel.text = location.venue.title.length > 0 ? location.venue.title : TGLocalized(@"Map.Location");
UIColor *pinColor = _pallete != nil ? _pallete.iconColor : [UIColor whiteColor];
if (color != nil) {
[_circleView setImage:TGTintedImage([TGLocationVenueCell circleImage], color)];
pinColor = [UIColor whiteColor];
}
if (location.venue.type.length > 0 && [location.venue.provider isEqualToString:@"foursquare"])
[_iconView loadUri:[NSString stringWithFormat:@"location-venue-icon://type=%@&width=%d&height=%d&color=%d", location.venue.type, 48, 48, TGColorHexCode(_pallete != nil ? _pallete.iconColor : [UIColor whiteColor])] withOptions:nil];
[_iconView loadUri:[NSString stringWithFormat:@"location-venue-icon://type=%@&width=%d&height=%d&color=%d", location.venue.type, 48, 48, TGColorHexCode(pinColor)] withOptions:nil];
SSignal *addressSignal = [SSignal single:@""];
if (location.venue.address.length > 0)

View File

@ -23,7 +23,7 @@
{
bool isUser = [peer isKindOfClass:[TGUser class]];
NSString *title = isUser ? ((TGUser *)peer).displayName : ((TGConversation *)peer).chatTitle;
self = [super initWithTitle:@"" type:TGMenuSheetButtonTypeDefault action:action];
self = [super initWithTitle:@"" type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:action];
if (self != nil)
{
_label = [[UILabel alloc] init];

View File

@ -491,7 +491,7 @@ const CGFloat TGLocationMapInset = 100.0f;
[itemViews addObject:titleItem];
__weak TGMenuSheetController *weakController = controller;
TGMenuSheetButtonItemView *for15MinutesItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.LiveLocationFor15Minutes") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *for15MinutesItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.LiveLocationFor15Minutes") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGLocationMapViewController *strongSelf = weakSelf;
if (strongSelf == nil)
@ -508,7 +508,7 @@ const CGFloat TGLocationMapInset = 100.0f;
}];
[itemViews addObject:for15MinutesItem];
TGMenuSheetButtonItemView *for1HourItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.LiveLocationFor1Hour") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *for1HourItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.LiveLocationFor1Hour") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGLocationMapViewController *strongSelf = weakSelf;
if (strongSelf == nil)
@ -525,7 +525,7 @@ const CGFloat TGLocationMapInset = 100.0f;
}];
[itemViews addObject:for1HourItem];
TGMenuSheetButtonItemView *for8HoursItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.LiveLocationFor8Hours") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *for8HoursItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.LiveLocationFor8Hours") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGLocationMapViewController *strongSelf = weakSelf;
if (strongSelf == nil)
@ -542,7 +542,7 @@ const CGFloat TGLocationMapInset = 100.0f;
}];
[itemViews addObject:for8HoursItem];
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)

View File

@ -266,14 +266,16 @@ NSString *const TGLocationPinAnnotationKind = @"TGLocationPinAnnotation";
_iconView.hidden = false;
UIColor *color = _pallete != nil ? _pallete.locationColor : UIColorRGB(0x008df2);
UIColor *pinColor = _pallete != nil ? _pallete.iconColor : [UIColor whiteColor];
if (locationAnnotation.color != nil) {
color = locationAnnotation.color;
pinColor = [UIColor whiteColor];
}
_backgroundView.image = TGTintedImage(TGComponentsImageNamed(@"LocationPinBackground"), color);
if (location.venue.type.length > 0)
{
[_iconView loadUri:[NSString stringWithFormat:@"location-venue-icon://type=%@&width=%d&height=%d&color=%d", location.venue.type, 64, 64, TGColorHexCode(_pallete != nil ? _pallete.iconColor : [UIColor whiteColor])] withOptions:nil];
[_iconView loadUri:[NSString stringWithFormat:@"location-venue-icon://type=%@&width=%d&height=%d&color=%d", location.venue.type, 64, 64, TGColorHexCode(pinColor)] withOptions:nil];
}
else
{

View File

@ -742,7 +742,7 @@
NSMutableArray *itemViews = [[NSMutableArray alloc] init];
__weak TGMenuSheetController *weakController = controller;
TGMenuSheetButtonItemView *openItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.OpenInMaps") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *openItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.OpenInMaps") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGLocationViewController *strongSelf = weakSelf;
if (strongSelf == nil)
@ -757,7 +757,7 @@
}];
[itemViews addObject:openItem];
TGMenuSheetButtonItemView *shareItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Conversation.ContextMenuShare") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *shareItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Conversation.ContextMenuShare") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)
@ -770,7 +770,7 @@
}];
[itemViews addObject:shareItem];
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)
@ -870,7 +870,7 @@
__weak TGMenuSheetController *weakController = controller;
NSArray *items = @
[
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.GetDirections") type:TGMenuSheetButtonTypeDefault action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Map.GetDirections") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)
@ -879,7 +879,7 @@
[strongController dismissAnimated:true];
block();
}],
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController != nil)

View File

@ -128,7 +128,7 @@
};
[itemViews addObject:carouselItem];
TGMenuSheetButtonItemView *galleryItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.ChoosePhoto") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *galleryItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.ChoosePhoto") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMediaAvatarMenuMixin *strongSelf = weakSelf;
if (strongSelf == nil)
@ -145,7 +145,7 @@
if (_hasSearchButton)
{
TGMenuSheetButtonItemView *viewItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"AttachmentMenu.WebSearch") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *viewItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"AttachmentMenu.WebSearch") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMediaAvatarMenuMixin *strongSelf = weakSelf;
if (strongSelf == nil)
@ -164,7 +164,7 @@
if (_hasViewButton)
{
TGMenuSheetButtonItemView *viewItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Settings.ViewPhoto") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *viewItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Settings.ViewPhoto") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMediaAvatarMenuMixin *strongSelf = weakSelf;
if (strongSelf == nil)
@ -182,7 +182,7 @@
if (_hasDeleteButton)
{
TGMenuSheetButtonItemView *deleteItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"GroupInfo.SetGroupPhotoDelete") type:TGMenuSheetButtonTypeDestructive action:^
TGMenuSheetButtonItemView *deleteItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"GroupInfo.SetGroupPhotoDelete") type:TGMenuSheetButtonTypeDestructive fontSize:20.0 action:^
{
__strong TGMediaAvatarMenuMixin *strongSelf = weakSelf;
if (strongSelf == nil)
@ -198,7 +198,7 @@
[itemViews addObject:deleteItem];
}
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMediaAvatarMenuMixin *strongSelf = weakSelf;
if (strongSelf == nil)

View File

@ -609,7 +609,7 @@
NSArray *items = @
[
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Camera.Discard") type:TGMenuSheetButtonTypeDefault action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Camera.Discard") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)
@ -624,7 +624,7 @@
[strongController dismissAnimated:true manual:false completion:nil];
}],
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController != nil)

View File

@ -21,7 +21,7 @@ typedef enum
@property (nonatomic, copy) void (^action)(void);
@property (nonatomic, assign) bool thickDivider;
- (instancetype)initWithTitle:(NSString *)title type:(TGMenuSheetButtonType)type action:(void (^)(void))action;
- (instancetype)initWithTitle:(NSString *)title type:(TGMenuSheetButtonType)type fontSize:(CGFloat)fontSize action:(void (^)(void))action;
@property (nonatomic, assign) bool collapsed;
- (void)setCollapsed:(bool)collapsed animated:(bool)animated;

View File

@ -16,6 +16,7 @@ const CGFloat TGMenuSheetButtonItemViewHeight = 57.0f;
bool _dark;
bool _requiresDivider;
UIView *_customDivider;
CGFloat _fontSize;
TGMenuSheetPallete *_pallete;
}
@ -23,12 +24,13 @@ const CGFloat TGMenuSheetButtonItemViewHeight = 57.0f;
@implementation TGMenuSheetButtonItemView
- (instancetype)initWithTitle:(NSString *)title type:(TGMenuSheetButtonType)type action:(void (^)(void))action
- (instancetype)initWithTitle:(NSString *)title type:(TGMenuSheetButtonType)type fontSize:(CGFloat)fontSize action:(void (^)(void))action
{
self = [super initWithType:(type == TGMenuSheetButtonTypeCancel) ? TGMenuSheetItemTypeFooter : TGMenuSheetItemTypeDefault];
if (self != nil)
{
self.action = action;
_fontSize = fontSize;
_buttonType = type;
_requiresDivider = true;
@ -115,7 +117,7 @@ const CGFloat TGMenuSheetButtonItemViewHeight = 57.0f;
- (void)_updateForType:(TGMenuSheetButtonType)type
{
_button.titleLabel.font = (type == TGMenuSheetButtonTypeCancel || type == TGMenuSheetButtonTypeSend) ? TGMediumSystemFontOfSize(20) : TGSystemFontOfSize(20);
_button.titleLabel.font = (type == TGMenuSheetButtonTypeCancel || type == TGMenuSheetButtonTypeSend) ? TGMediumSystemFontOfSize(_fontSize) : TGSystemFontOfSize(_fontSize);
UIColor *accentColor = _dark ? UIColorRGB(0x4fbcff) : TGAccentColor();
if (_pallete != nil)
accentColor = _pallete.accentColor;

View File

@ -84,7 +84,7 @@
};
[itemViews addObject:carouselItem];
TGMenuSheetButtonItemView *galleryItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.ChoosePhoto") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *galleryItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.ChoosePhoto") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)
@ -101,7 +101,7 @@
if (iosMajorVersion() >= 8 && intent != TGPassportAttachIntentSelfie)
{
TGMenuSheetButtonItemView *icloudItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Conversation.FileICloudDrive") type:TGMenuSheetButtonTypeDefault action:^
TGMenuSheetButtonItemView *icloudItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Conversation.FileICloudDrive") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)
@ -124,7 +124,7 @@
}
carouselItem.remainingHeight = TGMenuSheetButtonItemViewHeight * (itemViews.count - 1);
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
TGMenuSheetButtonItemView *cancelItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)

View File

@ -625,8 +625,8 @@ NSString * const TGPhotoCropOriginalAspectRatio = @"original";
};
NSMutableArray *items = [[NSMutableArray alloc] init];
[items addObject:[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"PhotoEditor.CropAspectRatioOriginal") type:TGMenuSheetButtonTypeDefault action:^{ action(TGPhotoCropOriginalAspectRatio); }]];
[items addObject:[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"PhotoEditor.CropAspectRatioSquare") type:TGMenuSheetButtonTypeDefault action:^{ action(@"1.0"); }]];
[items addObject:[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"PhotoEditor.CropAspectRatioOriginal") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^{ action(TGPhotoCropOriginalAspectRatio); }]];
[items addObject:[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"PhotoEditor.CropAspectRatioSquare") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^{ action(@"1.0"); }]];
CGSize croppedImageSize = _cropView.cropRect.size;
if (_cropView.cropOrientation == UIImageOrientationLeft || _cropView.cropOrientation == UIImageOrientationRight)
@ -666,10 +666,10 @@ NSString * const TGPhotoCropOriginalAspectRatio = @"original";
ratio = heightComponent / widthComponent;
[items addObject:[[TGMenuSheetButtonItemView alloc] initWithTitle:[NSString stringWithFormat:@"%d:%d", (int)widthComponent, (int)heightComponent] type:TGMenuSheetButtonTypeDefault action:^{ action([NSString stringWithFormat:@"%f", ratio]); }]];
[items addObject:[[TGMenuSheetButtonItemView alloc] initWithTitle:[NSString stringWithFormat:@"%d:%d", (int)widthComponent, (int)heightComponent] type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^{ action([NSString stringWithFormat:@"%f", ratio]); }]];
}
[items addObject:[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
[items addObject:[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController != nil)

View File

@ -1341,7 +1341,7 @@
NSArray *items = @
[
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"PhotoEditor.DiscardChanges") type:TGMenuSheetButtonTypeDefault action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"PhotoEditor.DiscardChanges") type:TGMenuSheetButtonTypeDefault fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)
@ -1352,7 +1352,7 @@
dismiss();
}];
}],
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController != nil)

View File

@ -550,7 +550,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
__weak TGPhotoPaintController *weakSelf = self;
NSArray *items = @
[
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Paint.ClearConfirm") type:TGMenuSheetButtonTypeDestructive action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Paint.ClearConfirm") type:TGMenuSheetButtonTypeDestructive fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController == nil)
@ -570,7 +570,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
[strongController dismissAnimated:true manual:false completion:nil];
}],
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel action:^
[[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Cancel") type:TGMenuSheetButtonTypeCancel fontSize:20.0 action:^
{
__strong TGMenuSheetController *strongController = weakController;
if (strongController != nil)

View File

@ -37,7 +37,7 @@
__weak TGMenuSheetController *weakController = controller;
__weak TGSecretTimerPickerItemView *weakTimerItem = timerItem;
TGMenuSheetButtonItemView *doneItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Done") type:TGMenuSheetButtonTypeSend action:^
TGMenuSheetButtonItemView *doneItem = [[TGMenuSheetButtonItemView alloc] initWithTitle:TGLocalized(@"Common.Done") type:TGMenuSheetButtonTypeSend fontSize:20.0 action:^
{
__strong TGSecretTimerPickerItemView *strongTimerItem = weakTimerItem;
if (strongTimerItem != nil)

View File

@ -22,6 +22,8 @@ public struct LegacyAttachmentMenuMediaEditing: OptionSet {
}
public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, canSendPolls: Bool, presentationData: PresentationData, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void) -> TGMenuSheetController {
let actionSheetTheme = ActionSheetControllerTheme(presentationData: presentationData)
let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat
let controller = TGMenuSheetController(context: parentController.context, dark: false)!
@ -99,7 +101,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
carouselItem.editingContext.setInitialCaption(initialCaption, entities: [])
itemViews.append(carouselItem)
let galleryItem = TGMenuSheetButtonItemView(title: editing ? presentationData.strings.Conversation_EditingMessageMediaChange : presentationData.strings.AttachmentMenu_PhotoOrVideo, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
let galleryItem = TGMenuSheetButtonItemView(title: editing ? presentationData.strings.Conversation_EditingMessageMediaChange : presentationData.strings.AttachmentMenu_PhotoOrVideo, type: TGMenuSheetButtonTypeDefault, fontSize: actionSheetTheme.baseFontSize, action: { [weak controller] in
controller?.dismiss(animated: true)
openGallery()
})!
@ -117,7 +119,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
}
if !editing {
let fileItem = TGMenuSheetButtonItemView(title: presentationData.strings.AttachmentMenu_File, type: TGMenuSheetButtonTypeDefault, action: {[weak controller] in
let fileItem = TGMenuSheetButtonItemView(title: presentationData.strings.AttachmentMenu_File, type: TGMenuSheetButtonTypeDefault, fontSize: actionSheetTheme.baseFontSize, action: {[weak controller] in
controller?.dismiss(animated: true)
openFileGallery()
})!
@ -126,7 +128,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
}
if canEditCurrent {
let fileItem = TGMenuSheetButtonItemView(title: presentationData.strings.AttachmentMenu_File, type: TGMenuSheetButtonTypeDefault, action: {[weak controller] in
let fileItem = TGMenuSheetButtonItemView(title: presentationData.strings.AttachmentMenu_File, type: TGMenuSheetButtonTypeDefault, fontSize: actionSheetTheme.baseFontSize, action: {[weak controller] in
controller?.dismiss(animated: true)
openFileGallery()
})!
@ -134,21 +136,21 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
}
if editMediaOptions == nil {
let locationItem = TGMenuSheetButtonItemView(title: presentationData.strings.Conversation_Location, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
let locationItem = TGMenuSheetButtonItemView(title: presentationData.strings.Conversation_Location, type: TGMenuSheetButtonTypeDefault, fontSize: actionSheetTheme.baseFontSize, action: { [weak controller] in
controller?.dismiss(animated: true)
openMap()
})!
itemViews.append(locationItem)
if (peer is TelegramGroup || peer is TelegramChannel) && canSendMessagesToPeer(peer) && canSendPolls {
let pollItem = TGMenuSheetButtonItemView(title: presentationData.strings.AttachmentMenu_Poll, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
let pollItem = TGMenuSheetButtonItemView(title: presentationData.strings.AttachmentMenu_Poll, type: TGMenuSheetButtonTypeDefault, fontSize: actionSheetTheme.baseFontSize, action: { [weak controller] in
controller?.dismiss(animated: true)
openPoll()
})!
itemViews.append(pollItem)
}
let contactItem = TGMenuSheetButtonItemView(title: presentationData.strings.Conversation_Contact, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
let contactItem = TGMenuSheetButtonItemView(title: presentationData.strings.Conversation_Contact, type: TGMenuSheetButtonTypeDefault, fontSize: actionSheetTheme.baseFontSize, action: { [weak controller] in
controller?.dismiss(animated: true)
openContacts()
})!
@ -162,7 +164,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
let peer = recentlyUsedInlineBots[i]
let addressName = peer.addressName
if let addressName = addressName {
let botItem = TGMenuSheetButtonItemView(title: "@" + addressName, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
let botItem = TGMenuSheetButtonItemView(title: "@" + addressName, type: TGMenuSheetButtonTypeDefault, fontSize: actionSheetTheme.baseFontSize, action: { [weak controller] in
controller?.dismiss(animated: true)
selectRecentlyUsedInlineBot(peer)
@ -175,7 +177,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
carouselItemView?.remainingHeight = TGMenuSheetButtonItemViewHeight * CGFloat(itemViews.count - 1)
let cancelItem = TGMenuSheetButtonItemView(title: presentationData.strings.Common_Cancel, type: TGMenuSheetButtonTypeCancel, action: { [weak controller] in
let cancelItem = TGMenuSheetButtonItemView(title: presentationData.strings.Common_Cancel, type: TGMenuSheetButtonTypeCancel, fontSize: actionSheetTheme.baseFontSize, action: { [weak controller] in
controller?.dismiss(animated: true)
})!
itemViews.append(cancelItem)

View File

@ -134,9 +134,14 @@ private let venueColors: [String: UIColor] = [
"parks_outdoors": UIColor(rgb: 0x6cc039),
"shops": UIColor(rgb: 0xffb300),
"travel": UIColor(rgb: 0x1c9fff),
"work": UIColor(rgb: 0xad7854),
"home": UIColor(rgb: 0x00aeef)
]
public func venueIconColor(type: String) -> UIColor {
if type.isEmpty {
return UIColor(rgb: 0x008df2)
}
if let color = venueColors[type] {
return color
}
@ -150,7 +155,8 @@ public func venueIconColor(type: String) -> UIColor {
}
public func venueIcon(postbox: Postbox, type: String, background: Bool) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
let data: Signal<Data?, NoError> = type.isEmpty ? .single(nil) : venueIconData(postbox: postbox, resource: VenueIconResource(type: type))
let isBuiltinIcon = ["", "home", "work"].contains(type)
let data: Signal<Data?, NoError> = isBuiltinIcon ? .single(nil) : venueIconData(postbox: postbox, resource: VenueIconResource(type: type))
return data |> map { data in
return { arguments in
let context = DrawingContext(size: arguments.drawingSize, clear: true)
@ -172,8 +178,21 @@ public func venueIcon(postbox: Postbox, type: String, background: Bool) -> Signa
let boundsSize = CGSize(width: arguments.drawingRect.size.width - 4.0 * 2.0, height: arguments.drawingRect.size.height - 4.0 * 2.0)
let fittedSize = image.size.aspectFitted(boundsSize)
c.draw(cgImage, in: CGRect(origin: CGPoint(x: floor((arguments.drawingRect.width - fittedSize.width) / 2.0), y: floor((arguments.drawingRect.height - fittedSize.height) / 2.0)), size: fittedSize))
} else if type.isEmpty, let pinImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/LocationPinForeground"), color: foregroundColor), let cgImage = pinImage.cgImage {
c.draw(cgImage, in: CGRect(origin: CGPoint(x: floor((arguments.drawingRect.width - pinImage.size.width) / 2.0), y: floor((arguments.drawingRect.height - pinImage.size.height) / 2.0)), size: pinImage.size))
} else if isBuiltinIcon {
let image: UIImage?
switch type {
case "":
image = UIImage(bundleImageName: "Chat/Message/LocationPinForeground")
case "home":
image = UIImage(bundleImageName: "Location/HomeIcon")
case "work":
image = UIImage(bundleImageName: "Location/WorkIcon")
default:
image = nil
}
if let image = image, let pinImage = generateTintedImage(image: image, color: foregroundColor), let cgImage = pinImage.cgImage {
c.draw(cgImage, in: CGRect(origin: CGPoint(x: floor((arguments.drawingRect.width - pinImage.size.width) / 2.0), y: floor((arguments.drawingRect.height - pinImage.size.height) / 2.0)), size: pinImage.size))
}
}
}

View File

@ -29,6 +29,9 @@ static_library(
"//submodules/MergeLists:MergeLists",
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
"//submodules/SearchBarNode:SearchBarNode",
"//submodules/PresentationDataUtils:PresentationDataUtils",
"//submodules/DeviceAccess:DeviceAccess",
"//submodules/ChatListSearchItemHeader:ChatListSearchItemHeader",
],
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",

View File

@ -80,6 +80,7 @@ class LocationPinAnnotationView: MKAnnotationView {
let smallIconNode: TransformImageNode
let dotNode: ASImageNode
var avatarNode: AvatarNode?
var labelNode: ImmediateTextNode?
var appeared = false
var animating = false
@ -226,6 +227,29 @@ class LocationPinAnnotationView: MKAnnotationView {
self.dotNode.alpha = 1.0
self.dotNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
if let annotation = self.annotation as? LocationPinAnnotation, let venue = annotation.location?.venue {
let labelNode = ImmediateTextNode()
labelNode.displaysAsynchronously = false
labelNode.isUserInteractionEnabled = false
labelNode.attributedText = NSAttributedString(string: venue.title, font: Font.medium(10), textColor: .black)
labelNode.maximumNumberOfLines = 2
labelNode.textAlignment = .center
labelNode.truncationType = .end
labelNode.textStroke = (UIColor.white, 1.0)
self.labelNode = labelNode
self.addSubnode(labelNode)
let size = labelNode.updateLayout(CGSize(width: 120.0, height: CGFloat.greatestFiniteMagnitude))
labelNode.bounds = CGRect(origin: CGPoint(), size: size)
labelNode.position = CGPoint(x: 0.0, y: 10.0)
labelNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
} else {
self.labelNode?.removeFromSupernode()
self.labelNode = nil
}
} else {
let avatarSnapshot = self.avatarNode?.view.snapshotContentTree()
if let avatarSnapshot = avatarSnapshot, let avatarNode = self.avatarNode {
@ -268,6 +292,13 @@ class LocationPinAnnotationView: MKAnnotationView {
let previousAlpha = self.dotNode.alpha
self.dotNode.alpha = 0.0
self.dotNode.layer.animateAlpha(from: previousAlpha, to: 0.0, duration: 0.2)
if let labelNode = self.labelNode {
self.labelNode = nil
labelNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { _ in
labelNode.removeFromSupernode()
})
}
}
} else {
self.smallNode.isHidden = selected
@ -279,50 +310,13 @@ class LocationPinAnnotationView: MKAnnotationView {
}
}
override func layoutSubviews() {
super.layoutSubviews()
guard !self.animating else {
return
}
self.dotNode.position = CGPoint()
self.smallNode.position = CGPoint()
self.shadowNode.position = CGPoint(x: UIScreenPixel, y: -36.0)
self.backgroundNode.position = CGPoint(x: self.shadowNode.frame.width / 2.0, y: self.shadowNode.frame.height / 2.0)
self.iconNode.position = CGPoint(x: self.shadowNode.frame.width / 2.0, y: self.shadowNode.frame.height / 2.0 - 5.0)
let smallIconLayout = self.smallIconNode.asyncLayout()
let smallIconApply = smallIconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: self.smallIconNode.bounds.size, boundingSize: self.smallIconNode.bounds.size, intrinsicInsets: UIEdgeInsets()))
smallIconApply()
let iconLayout = self.iconNode.asyncLayout()
let iconApply = iconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: self.iconNode.bounds.size, boundingSize: self.iconNode.bounds.size, intrinsicInsets: UIEdgeInsets()))
iconApply()
if let avatarNode = self.avatarNode {
avatarNode.position = self.isSelected ? CGPoint(x: UIScreenPixel, y: -41.0) : CGPoint()
avatarNode.transform = self.isSelected ? CATransform3DIdentity : CATransform3DMakeScale(0.64, 0.64, 1.0)
avatarNode.view.superview?.bringSubviewToFront(avatarNode.view)
}
if !self.appeared {
self.appeared = true
self.smallNode.transform = CATransform3DMakeScale(0.1, 0.1, 1.0)
UIView.animate(withDuration: 0.55, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.5, options: [], animations: {
self.smallNode.transform = CATransform3DIdentity
}) { _ in
}
}
}
func setPeer(account: Account, theme: PresentationTheme, peer: Peer) {
let avatarNode: AvatarNode
if let currentAvatarNode = self.avatarNode {
avatarNode = currentAvatarNode
} else {
avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 24.0))
avatarNode.isLayerBacked = false
avatarNode.bounds = CGRect(origin: CGPoint(), size: CGSize(width: 55.0, height: 55.0))
avatarNode.position = CGPoint()
self.avatarNode = avatarNode
@ -332,19 +326,23 @@ class LocationPinAnnotationView: MKAnnotationView {
avatarNode.setPeer(account: account, theme: theme, peer: peer)
}
private var raised = false
var isRaised = false
func setRaised(_ raised: Bool, animated: Bool, completion: @escaping () -> Void = {}) {
guard raised != self.raised else {
guard raised != self.isRaised else {
return
}
self.raised = raised
self.isRaised = raised
self.shadowNode.layer.removeAllAnimations()
if animated {
self.animating = true
if raised {
let previousPosition = self.shadowNode.position
self.shadowNode.layer.animatePosition(from: previousPosition, to: CGPoint(x: UIScreenPixel, y: -66.0), duration: 0.2, delay: 0.0, timingFunction: kCAMediaTimingFunctionSpring) { finished in
self.shadowNode.position = CGPoint(x: UIScreenPixel, y: -66.0)
self.shadowNode.layer.animatePosition(from: previousPosition, to: self.shadowNode.position, duration: 0.2, delay: 0.0, timingFunction: kCAMediaTimingFunctionSpring) { finished in
self.animating = false
if finished {
completion()
}
@ -353,6 +351,7 @@ class LocationPinAnnotationView: MKAnnotationView {
UIView.animate(withDuration: 0.2, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.0, options: [.allowAnimatedContent], animations: {
self.shadowNode.position = CGPoint(x: UIScreenPixel, y: -36.0)
}) { finished in
self.animating = false
if finished {
completion()
}
@ -396,7 +395,6 @@ class LocationPinAnnotationView: MKAnnotationView {
self.addSubnode(avatarNode)
}
self.animating = false
self.setNeedsLayout()
}
}
@ -405,4 +403,42 @@ class LocationPinAnnotationView: MKAnnotationView {
self.dotNode.isHidden = !custom
}
override func layoutSubviews() {
super.layoutSubviews()
guard !self.animating else {
return
}
self.dotNode.position = CGPoint()
self.smallNode.position = CGPoint()
self.shadowNode.position = CGPoint(x: UIScreenPixel, y: self.isRaised ? -66.0 : -36.0)
self.backgroundNode.position = CGPoint(x: self.shadowNode.frame.width / 2.0, y: self.shadowNode.frame.height / 2.0)
self.iconNode.position = CGPoint(x: self.shadowNode.frame.width / 2.0, y: self.shadowNode.frame.height / 2.0 - 5.0)
let smallIconLayout = self.smallIconNode.asyncLayout()
let smallIconApply = smallIconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: self.smallIconNode.bounds.size, boundingSize: self.smallIconNode.bounds.size, intrinsicInsets: UIEdgeInsets()))
smallIconApply()
let iconLayout = self.iconNode.asyncLayout()
let iconApply = iconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: self.iconNode.bounds.size, boundingSize: self.iconNode.bounds.size, intrinsicInsets: UIEdgeInsets()))
iconApply()
if let avatarNode = self.avatarNode {
avatarNode.position = self.isSelected ? CGPoint(x: UIScreenPixel, y: -41.0) : CGPoint()
avatarNode.transform = self.isSelected ? CATransform3DIdentity : CATransform3DMakeScale(0.64, 0.64, 1.0)
avatarNode.view.superview?.bringSubviewToFront(avatarNode.view)
}
if !self.appeared {
self.appeared = true
self.smallNode.transform = CATransform3DMakeScale(0.1, 0.1, 1.0)
UIView.animate(withDuration: 0.55, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.5, options: [], animations: {
self.smallNode.transform = CATransform3DIdentity
}) { _ in
}
}
}
}

View File

@ -100,19 +100,21 @@ final class LocationMapHeaderNode: ASDisplayNode {
self.shadowNode.image = generateShadowImage(theme: presentationData.theme, highlighted: false)
}
func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, padding: CGFloat, size: CGSize, transition: ContainedViewLayoutTransition) {
transition.updateFrame(node: self.mapNode, frame: CGRect(x: 0.0, y: floorToScreenPixels((size.height - layout.size.height + navigationBarHeight) / 2.0), width: size.width, height: layout.size.height))
func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, topPadding: CGFloat, offset: CGFloat, size: CGSize, transition: ContainedViewLayoutTransition) {
let mapHeight: CGFloat = floor(layout.size.height * 1.5)
let mapFrame = CGRect(x: 0.0, y: floorToScreenPixels((size.height - mapHeight + navigationBarHeight) / 2.0) + offset, width: size.width, height: mapHeight)
transition.updateFrame(node: self.mapNode, frame: mapFrame)
self.mapNode.updateLayout(size: mapFrame.size)
transition.updateFrame(node: self.shadowNode, frame: CGRect(x: 0.0, y: size.height - 14.0, width: size.width, height: 14.0))
let inset: CGFloat = 6.0
transition.updateFrame(node: self.optionsBackgroundNode, frame: CGRect(x: size.width - inset - panelSize.width - panelInset * 2.0, y: navigationBarHeight + padding + inset, width: panelSize.width + panelInset * 2.0, height: panelSize.height + panelInset * 2.0))
transition.updateFrame(node: self.optionsBackgroundNode, frame: CGRect(x: size.width - inset - panelSize.width - panelInset * 2.0, y: navigationBarHeight + topPadding + inset, width: panelSize.width + panelInset * 2.0, height: panelSize.height + panelInset * 2.0))
transition.updateFrame(node: self.infoButtonNode, frame: CGRect(x: panelInset, y: panelInset, width: panelSize.width, height: panelSize.height / 2.0))
transition.updateFrame(node: self.locationButtonNode, frame: CGRect(x: panelInset, y: panelInset + panelSize.height / 2.0, width: panelSize.width, height: panelSize.height / 2.0))
let alphaTransition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
let optionsAlpha: CGFloat = size.height > 124.0 + navigationBarHeight ? 1.0 : 0.0
let optionsAlpha: CGFloat = size.height > 160.0 + navigationBarHeight ? 1.0 : 0.0
alphaTransition.updateAlpha(node: self.optionsBackgroundNode, alpha: optionsAlpha)
}

View File

@ -39,10 +39,13 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
private let pickerAnnotationContainerView: PickerAnnotationContainerView
private weak var userLocationAnnotationView: MKAnnotationView?
private let pinDisposable = MetaDisposable()
private var mapView: MKMapView? {
return self.view as? MKMapView
}
var returnedToUserLocation = true
var ignoreRegionChanges = false
var isDragging = false
var beganInteractiveDragging: (() -> Void)?
@ -101,6 +104,11 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
self.mapView?.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsets(top: offset.y, left: offset.x, bottom: 0.0, right: 0.0), animated: animated)
}
self.ignoreRegionChanges = false
if isUserLocation && !self.returnedToUserLocation {
self.returnedToUserLocation = true
self.pickerAnnotationView?.setRaised(true, animated: true)
}
}
func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
@ -111,13 +119,18 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
for gestureRecognizer in gestureRecognizers {
if gestureRecognizer.state == .began || gestureRecognizer.state == .ended {
self.isDragging = true
self.returnedToUserLocation = false
self.beganInteractiveDragging?()
if self.hasPickerAnnotation {
self.customUserLocationAnnotationView?.isHidden = true
self.pickerAnnotationContainerView.isHidden = false
self.pickerAnnotationView?.setCustom(true, animated: true)
if let pickerAnnotationView = self.pickerAnnotationView, !pickerAnnotationView.isRaised {
pickerAnnotationView.setCustom(true, animated: true)
pickerAnnotationView.setRaised(true, animated: true)
}
self.resetAnnotationSelection()
self.resetScheduledPin()
}
break
}
@ -125,9 +138,18 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
if self.isDragging, let coordinate = self.mapCenterCoordinate {
let wasDragging = self.isDragging
if self.isDragging {
self.isDragging = false
self.endedInteractiveDragging?(coordinate)
if let coordinate = self.mapCenterCoordinate {
self.endedInteractiveDragging?(coordinate)
}
}
if let pickerAnnotationView = self.pickerAnnotationView {
if pickerAnnotationView.isRaised && (wasDragging || self.returnedToUserLocation) {
self.schedulePin(wasDragging: wasDragging)
}
}
}
@ -293,12 +315,41 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
}
}
override func layout() {
super.layout()
self.pickerAnnotationContainerView.frame = CGRect(x: 0.0, y: floorToScreenPixels((self.frame.size.height - self.frame.size.width) / 2.0), width: self.frame.size.width, height: self.frame.size.width)
private func schedulePin(wasDragging: Bool) {
let timeout: Double = wasDragging ? 0.38 : 0.05
let signal: Signal<Never, NoError> = .complete()
|> delay(timeout, queue: Queue.mainQueue())
self.pinDisposable.set(signal.start(completed: { [weak self] in
guard let strongSelf = self, let pickerAnnotationView = strongSelf.pickerAnnotationView else {
return
}
pickerAnnotationView.setRaised(false, animated: true) { [weak self] in
guard let strongSelf = self else {
return
}
if strongSelf.returnedToUserLocation {
strongSelf.pickerAnnotationContainerView.isHidden = true
strongSelf.customUserLocationAnnotationView?.isHidden = false
}
}
if strongSelf.returnedToUserLocation {
pickerAnnotationView.setCustom(false, animated: true)
}
}))
}
private func resetScheduledPin() {
self.pinDisposable.set(nil)
}
func updateLayout(size: CGSize) {
self.pickerAnnotationContainerView.frame = CGRect(x: 0.0, y: floorToScreenPixels((size.height - size.width) / 2.0), width: size.width, height: size.width)
if let pickerAnnotationView = self.pickerAnnotationView {
pickerAnnotationView.center = CGPoint(x: self.pickerAnnotationContainerView.frame.width / 2.0, y: self.pickerAnnotationContainerView.frame.height / 2.0 + 16.0)
pickerAnnotationView.center = CGPoint(x: self.pickerAnnotationContainerView.frame.width / 2.0, y: self.pickerAnnotationContainerView.frame.height / 2.0)
}
}
}

View File

@ -10,6 +10,8 @@ import TelegramPresentationData
import AccountContext
import AppBundle
import CoreLocation
import PresentationDataUtils
import DeviceAccess
public enum LocationPickerMode {
case share(peer: Peer?, selfPeer: Peer?, hasLiveLocation: Bool)
@ -23,24 +25,28 @@ class LocationPickerInteraction {
let toggleMapModeSelection: () -> Void
let updateMapMode: (LocationMapMode) -> Void
let goToUserLocation: () -> Void
let goToCoordinate: (CLLocationCoordinate2D) -> Void
let openSearch: () -> Void
let updateSearchQuery: (String) -> Void
let dismissSearch: () -> Void
let dismissInput: () -> Void
let updateSendActionHighlight: (Bool) -> Void
let openHomeWorkInfo: () -> Void
init(sendLocation: @escaping (CLLocationCoordinate2D) -> Void, sendLiveLocation: @escaping (CLLocationCoordinate2D) -> Void, sendVenue: @escaping (TelegramMediaMap) -> Void, toggleMapModeSelection: @escaping () -> Void, updateMapMode: @escaping (LocationMapMode) -> Void, goToUserLocation: @escaping () -> Void, openSearch: @escaping () -> Void, updateSearchQuery: @escaping (String) -> Void, dismissSearch: @escaping () -> Void, dismissInput: @escaping () -> Void, updateSendActionHighlight: @escaping (Bool) -> Void) {
init(sendLocation: @escaping (CLLocationCoordinate2D) -> Void, sendLiveLocation: @escaping (CLLocationCoordinate2D) -> Void, sendVenue: @escaping (TelegramMediaMap) -> Void, toggleMapModeSelection: @escaping () -> Void, updateMapMode: @escaping (LocationMapMode) -> Void, goToUserLocation: @escaping () -> Void, goToCoordinate: @escaping (CLLocationCoordinate2D) -> Void, openSearch: @escaping () -> Void, updateSearchQuery: @escaping (String) -> Void, dismissSearch: @escaping () -> Void, dismissInput: @escaping () -> Void, updateSendActionHighlight: @escaping (Bool) -> Void, openHomeWorkInfo: @escaping () -> Void) {
self.sendLocation = sendLocation
self.sendLiveLocation = sendLiveLocation
self.sendVenue = sendVenue
self.toggleMapModeSelection = toggleMapModeSelection
self.updateMapMode = updateMapMode
self.goToUserLocation = goToUserLocation
self.goToCoordinate = goToCoordinate
self.openSearch = openSearch
self.updateSearchQuery = updateSearchQuery
self.dismissSearch = dismissSearch
self.dismissInput = dismissInput
self.updateSendActionHighlight = updateSendActionHighlight
self.openHomeWorkInfo = openHomeWorkInfo
}
}
@ -56,6 +62,10 @@ public final class LocationPickerController: ViewController {
private var presentationDataDisposable: Disposable?
private var searchNavigationContentNode: LocationSearchNavigationContentNode?
private var isSearchingDisposable = MetaDisposable()
private let locationManager = CLLocationManager()
private var permissionDisposable: Disposable?
private var interaction: LocationPickerInteraction?
@ -88,6 +98,29 @@ public final class LocationPickerController: ViewController {
strongSelf.controllerNode.updatePresentationData(presentationData)
})
self.permissionDisposable = (DeviceAccess.authorizationStatus(subject: .location(.send))
|> deliverOnMainQueue).start(next: { [weak self] next in
guard let strongSelf = self else {
return
}
switch next {
case .notDetermined:
DeviceAccess.authorizeAccess(to: .location(.send), locationManager: strongSelf.locationManager, presentationData: strongSelf.presentationData, present: { c, a in
strongSelf.present(c, in: .window(.root), with: a)
}, openSettings: {
strongSelf.context.sharedContext.applicationBindings.openSettings()
})
case .denied:
strongSelf.controllerNode.updateState { state in
var state = state
state.forceSelection = true
return state
}
default:
break
}
})
let locationWithTimeout: (CLLocationCoordinate2D, Int32?) -> TelegramMediaMap = { coordinate, timeout in
return TelegramMediaMap(latitude: coordinate.latitude, longitude: coordinate.longitude, geoPlace: nil, venue: nil, liveBroadcastingTimeout: timeout)
}
@ -102,7 +135,7 @@ public final class LocationPickerController: ViewController {
guard let strongSelf = self else {
return
}
let controller = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let controller = ActionSheetController(presentationData: strongSelf.presentationData)
var title = strongSelf.presentationData.strings.Map_LiveLocationGroupDescription
if case let .share(peer, _, _) = strongSelf.mode, let receiver = peer {
title = strongSelf.presentationData.strings.Map_LiveLocationPrivateDescription(receiver.compactDisplayTitle).0
@ -143,7 +176,12 @@ public final class LocationPickerController: ViewController {
guard let strongSelf = self else {
return
}
completion(venue, nil)
let venueType = venue.venue?.type ?? ""
if ["home", "work"].contains(venueType) {
completion(TelegramMediaMap(latitude: venue.latitude, longitude: venue.longitude, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil), nil)
} else {
completion(venue, nil)
}
strongSelf.dismiss()
}, toggleMapModeSelection: { [weak self] in
guard let strongSelf = self else {
@ -174,6 +212,16 @@ public final class LocationPickerController: ViewController {
state.selectedLocation = .none
return state
}
}, goToCoordinate: { [weak self] coordinate in
guard let strongSelf = self else {
return
}
strongSelf.controllerNode.updateState { state in
var state = state
state.displayingMapModeOptions = false
state.selectedLocation = .location(coordinate, nil)
return state
}
}, openSearch: { [weak self] in
guard let strongSelf = self, let interaction = strongSelf.interaction, let navigationBar = strongSelf.navigationBar else {
return
@ -186,8 +234,15 @@ public final class LocationPickerController: ViewController {
let contentNode = LocationSearchNavigationContentNode(presentationData: strongSelf.presentationData, interaction: interaction)
strongSelf.searchNavigationContentNode = contentNode
navigationBar.setContentNode(contentNode, animated: true)
strongSelf.controllerNode.activateSearch(navigationBar: navigationBar)
let isSearching = strongSelf.controllerNode.activateSearch(navigationBar: navigationBar)
contentNode.activate()
strongSelf.isSearchingDisposable.set((isSearching
|> deliverOnMainQueue).start(next: { [weak self] value in
if let strongSelf = self, let searchNavigationContentNode = strongSelf.searchNavigationContentNode {
searchNavigationContentNode.updateActivity(value)
}
}))
}, updateSearchQuery: { [weak self] query in
guard let strongSelf = self else {
return
@ -197,6 +252,7 @@ public final class LocationPickerController: ViewController {
guard let strongSelf = self, let navigationBar = strongSelf.navigationBar else {
return
}
strongSelf.isSearchingDisposable.set(nil)
strongSelf.searchNavigationContentNode?.deactivate()
strongSelf.searchNavigationContentNode = nil
navigationBar.setContentNode(nil, animated: true)
@ -211,6 +267,13 @@ public final class LocationPickerController: ViewController {
return
}
strongSelf.controllerNode.updateSendActionHighlight(highlighted)
}, openHomeWorkInfo: { [weak self] in
guard let strongSelf = self else {
return
}
let controller = textAlertController(context: strongSelf.context, title: strongSelf.presentationData.strings.Map_HomeAndWorkTitle, text: strongSelf.presentationData.strings.Map_HomeAndWorkInfo, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})])
strongSelf.present(controller, in: .window(.root))
})
self.scrollToTop = { [weak self] in
@ -218,8 +281,6 @@ public final class LocationPickerController: ViewController {
strongSelf.controllerNode.scrollToTop()
}
}
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
}
required public init(coder aDecoder: NSCoder) {
@ -228,6 +289,8 @@ public final class LocationPickerController: ViewController {
deinit {
self.presentationDataDisposable?.dispose()
self.permissionDisposable?.dispose()
self.isSearchingDisposable.dispose()
}
override public func loadDisplayNode() {

View File

@ -151,9 +151,12 @@ private enum LocationPickerEntry: Comparable, Identifiable {
case let .header(theme, title):
return LocationSectionHeaderItem(presentationData: ItemListPresentationData(presentationData), title: title)
case let .venue(theme, venue, _):
return ItemListVenueItem(presentationData: ItemListPresentationData(presentationData), account: account, venue: venue, sectionId: 0, style: .plain, action: {
let venueType = venue.venue?.type ?? ""
return ItemListVenueItem(presentationData: ItemListPresentationData(presentationData), account: account, venue: venue, style: .plain, action: {
interaction?.sendVenue(venue)
})
}, infoAction: ["home", "work"].contains(venueType) ? {
interaction?.openHomeWorkInfo()
} : nil)
case let .attribution(theme):
return LocationAttributionItem(presentationData: ItemListPresentationData(presentationData))
}
@ -220,11 +223,13 @@ struct LocationPickerState {
var mapMode: LocationMapMode
var displayingMapModeOptions: Bool
var selectedLocation: LocationPickerLocation
var forceSelection: Bool
init() {
self.mapMode = .map
self.displayingMapModeOptions = false
self.selectedLocation = .none
self.forceSelection = false
}
}
@ -415,10 +420,23 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
strongSelf.headerNode.mapNode.resetAnnotationSelection()
case .selecting:
strongSelf.headerNode.mapNode.resetAnnotationSelection()
case let .location(coordinate, _):
var updateMap = false
switch previousState.selectedLocation {
case .none, .venue:
updateMap = true
case let .location(previousCoordinate, address):
if previousCoordinate != coordinate {
updateMap = true
}
default:
break
}
if updateMap {
strongSelf.headerNode.mapNode.setMapCenter(coordinate: coordinate, isUserLocation: false, animated: true)
}
case let .venue(venue):
strongSelf.headerNode.mapNode.setMapCenter(coordinate: venue.coordinate, animated: true)
default:
break
}
let annotations: [LocationPinAnnotation]
@ -482,7 +500,7 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
strongSelf.listOffset = max(0.0, offset)
let headerFrame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: max(0.0, offset + overlap)))
listTransition.updateFrame(node: strongSelf.headerNode, frame: headerFrame)
strongSelf.headerNode.updateLayout(layout: layout, navigationBarHeight: navigationBarHeight, padding: strongSelf.state.displayingMapModeOptions ? 38.0 : 0.0, size: headerFrame.size, transition: listTransition)
strongSelf.headerNode.updateLayout(layout: layout, navigationBarHeight: navigationBarHeight, topPadding: strongSelf.state.displayingMapModeOptions ? 38.0 : 0.0, offset: 0.0, size: headerFrame.size, transition: listTransition)
strongSelf.layoutActivityIndicator(transition: listTransition)
}
@ -590,9 +608,9 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
})
}
func activateSearch(navigationBar: NavigationBar) {
func activateSearch(navigationBar: NavigationBar) -> Signal<Bool, NoError> {
guard let (layout, navigationBarHeight) = self.validLayout, self.searchContainerNode == nil, let coordinate = self.headerNode.mapNode.mapCenterCoordinate else {
return
return .complete()
}
let searchContainerNode = LocationSearchContainerNode(context: self.context, coordinate: coordinate, interaction: self.interaction)
@ -602,6 +620,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
searchContainerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
self.containerLayoutUpdated(layout, navigationHeight: navigationBarHeight, transition: .immediate)
return searchContainerNode.isSearching
}
func deactivateSearch() {
@ -643,10 +663,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
let isFirstLayout = self.validLayout == nil
self.validLayout = (layout, navigationHeight)
let isPickingLocation = self.state.selectedLocation.isCustom || self.state.forceSelection
let optionsHeight: CGFloat = 38.0
let pickingCustomLocation = self.state.selectedLocation.isCustom
var actionHeight: CGFloat?
self.listNode.forEachItemNode { itemNode in
if let itemNode = itemNode as? LocationActionListItemNode {
@ -659,7 +677,7 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
let topInset: CGFloat = floor((layout.size.height - navigationHeight) / 2.0 + navigationHeight)
let overlap: CGFloat = 6.0
let headerHeight: CGFloat
if pickingCustomLocation, let actionHeight = actionHeight {
if isPickingLocation, let actionHeight = actionHeight {
self.listOffset = topInset
headerHeight = layout.size.height - actionHeight - layout.intrinsicInsets.bottom + overlap - 2.0
} else if let listOffset = self.listOffset {
@ -669,26 +687,29 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
}
let headerFrame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: headerHeight))
transition.updateFrame(node: self.headerNode, frame: headerFrame)
self.headerNode.updateLayout(layout: layout, navigationBarHeight: navigationHeight, padding: self.state.displayingMapModeOptions ? optionsHeight : 0.0, size: headerFrame.size, transition: transition)
self.headerNode.updateLayout(layout: layout, navigationBarHeight: navigationHeight, topPadding: self.state.displayingMapModeOptions ? optionsHeight : 0.0, offset: 0.0, size: headerFrame.size, transition: transition)
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
let scrollToItem: ListViewScrollToItem?
if pickingCustomLocation {
if isPickingLocation {
scrollToItem = ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: curve, directionHint: .Up)
} else {
scrollToItem = nil
}
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: scrollToItem, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: layout.size, insets: UIEdgeInsets(top: topInset, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), headerInsets: UIEdgeInsets(top: navigationHeight, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), scrollIndicatorInsets: UIEdgeInsets(top: topInset + 3.0, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), duration: duration, curve: curve), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
self.listNode.scrollEnabled = !pickingCustomLocation
let insets = UIEdgeInsets(top: topInset, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom, right: layout.safeInsets.right)
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: scrollToItem, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: layout.size, insets: insets, headerInsets: UIEdgeInsets(top: navigationHeight, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), scrollIndicatorInsets: UIEdgeInsets(top: topInset + 3.0, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), duration: duration, curve: curve), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
self.listNode.scrollEnabled = !isPickingLocation
var listFrame: CGRect = CGRect(origin: CGPoint(), size: layout.size)
if pickingCustomLocation {
if isPickingLocation {
listFrame.origin.y = headerHeight - topInset - overlap
}
transition.updateFrame(node: self.listNode, frame: listFrame)
transition.updateAlpha(node: self.shadeNode, alpha: pickingCustomLocation ? 1.0 : 0.0)
transition.updateAlpha(node: self.shadeNode, alpha: isPickingLocation ? 1.0 : 0.0)
transition.updateFrame(node: self.shadeNode, frame: CGRect(x: 0.0, y: listFrame.minY + topInset + (actionHeight ?? 0.0) - 3.0, width: layout.size.width, height: 10000.0))
self.shadeNode.isUserInteractionEnabled = pickingCustomLocation
self.shadeNode.isUserInteractionEnabled = isPickingLocation
self.innerShadeNode.frame = CGRect(x: 0.0, y: 4.0, width: layout.size.width, height: 10000.0)
self.innerShadeNode.alpha = layout.intrinsicInsets.bottom > 0.0 ? 1.0 : 0.0

View File

@ -13,14 +13,18 @@ import AccountContext
import ItemListVenueItem
import ItemListUI
import MapKit
import Geocoding
import ChatListSearchItemHeader
private struct LocationSearchEntry: Identifiable, Comparable {
let index: Int
let theme: PresentationTheme
let venue: TelegramMediaMap
let location: TelegramMediaMap
let title: String?
let distance: Double
var stableId: String {
return self.venue.venue?.id ?? ""
return self.location.venue?.id ?? ""
}
static func ==(lhs: LocationSearchEntry, rhs: LocationSearchEntry) -> Bool {
@ -30,7 +34,13 @@ private struct LocationSearchEntry: Identifiable, Comparable {
if lhs.theme !== rhs.theme {
return false
}
if lhs.venue.venue?.id != rhs.venue.venue?.id {
if lhs.location.venue?.id != rhs.location.venue?.id {
return false
}
if lhs.title != rhs.title {
return false
}
if lhs.distance != rhs.distance {
return false
}
return true
@ -41,10 +51,19 @@ private struct LocationSearchEntry: Identifiable, Comparable {
}
func item(account: Account, presentationData: PresentationData, sendVenue: @escaping (TelegramMediaMap) -> Void) -> ListViewItem {
let venue = self.venue
return ItemListVenueItem(presentationData: ItemListPresentationData(presentationData), account: account, venue: self.venue, sectionId: 0, style: .plain, action: {
let venue = self.location
let header: ChatListSearchItemHeader
let subtitle: String?
if let _ = venue.venue {
header = ChatListSearchItemHeader(type: .nearbyVenues, theme: presentationData.theme, strings: presentationData.strings)
subtitle = nil
} else {
header = ChatListSearchItemHeader(type: .mapAddress, theme: presentationData.theme, strings: presentationData.strings)
subtitle = presentationData.strings.Map_DistanceAway(stringForDistance(strings: presentationData.strings, distance: self.distance)).0
}
return ItemListVenueItem(presentationData: ItemListPresentationData(presentationData), account: account, venue: self.location, title: self.title, subtitle: subtitle, style: .plain, action: {
sendVenue(venue)
})
}, header: header)
}
}
@ -81,10 +100,17 @@ final class LocationSearchContainerNode: ASDisplayNode {
private var containerViewLayout: (ContainerViewLayout, CGFloat)?
private var enqueuedTransitions: [LocationSearchContainerTransition] = []
private let _isSearching = ValuePromise<Bool>(false, ignoreRepeated: true)
var isSearching: Signal<Bool, NoError> {
return self._isSearching.get()
}
public init(context: AccountContext, coordinate: CLLocationCoordinate2D, interaction: LocationPickerInteraction) {
self.context = context
self.interaction = interaction
let currentLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
@ -107,6 +133,7 @@ final class LocationSearchContainerNode: ASDisplayNode {
let themeAndStringsPromise = self.themeAndStringsPromise
let isSearching = self._isSearching
let searchItems = self.searchQuery.get()
|> mapToSignal { query -> Signal<String?, NoError> in
if let query = query, !query.isEmpty {
@ -119,19 +146,43 @@ final class LocationSearchContainerNode: ASDisplayNode {
|> mapToSignal { query -> Signal<[LocationSearchEntry]?, NoError> in
if let query = query, !query.isEmpty {
let foundVenues = nearbyVenues(account: context.account, latitude: coordinate.latitude, longitude: coordinate.longitude, query: query)
return combineLatest(foundVenues, themeAndStringsPromise.get())
|> afterCompleted {
isSearching.set(false)
}
let foundPlacemarks = geocodeLocation(address: query)
return combineLatest(foundVenues, foundPlacemarks, themeAndStringsPromise.get())
|> delay(0.1, queue: Queue.concurrentDefaultQueue())
|> map { venues, themeAndStrings -> [LocationSearchEntry] in
|> beforeStarted {
isSearching.set(true)
}
|> map { venues, placemarks, themeAndStrings -> [LocationSearchEntry] in
var entries: [LocationSearchEntry] = []
var index: Int = 0
if let placemarks = placemarks {
for placemark in placemarks {
guard let placemarkLocation = placemark.location else {
continue
}
let location = TelegramMediaMap(latitude: placemarkLocation.coordinate.latitude, longitude: placemarkLocation.coordinate.longitude, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil)
entries.append(LocationSearchEntry(index: index, theme: themeAndStrings.0, location: location, title: placemark.name ?? "Name", distance: placemarkLocation.distance(from: currentLocation)))
index += 1
}
}
for venue in venues {
entries.append(LocationSearchEntry(index: index, theme: themeAndStrings.0, venue: venue))
entries.append(LocationSearchEntry(index: index, theme: themeAndStrings.0, location: venue, title: nil, distance: 0.0))
index += 1
}
return entries
}
} else {
return .single(nil)
|> afterCompleted {
isSearching.set(true)
}
}
}
@ -141,7 +192,12 @@ final class LocationSearchContainerNode: ASDisplayNode {
if let strongSelf = self {
let previousItems = previousSearchItems.swap(items ?? [])
let transition = locationSearchContainerPreparedTransition(from: previousItems, to: items ?? [], isSearching: items != nil, account: context.account, presentationData: strongSelf.presentationData, sendVenue: { venue in self?.listNode.clearHighlightAnimated(true)
self?.interaction.sendVenue(venue)
if let _ = venue.venue {
self?.interaction.sendVenue(venue)
} else {
self?.interaction.goToCoordinate(venue.coordinate)
self?.interaction.dismissSearch()
}
})
strongSelf.enqueueTransition(transition)
}

View File

@ -54,6 +54,10 @@ final class LocationSearchNavigationContentNode: NavigationBarContentNode {
self.searchBar.deactivate(clear: false)
}
func updateActivity(_ activity: Bool) {
self.searchBar.activity = activity
}
func updatePresentationData(_ presentationData: PresentationData) {
self.presentationData = presentationData
self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: false), strings: presentationData.strings)

View File

@ -22,7 +22,7 @@
- (void)contextDatacenterAddressSetUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId addressSet:(MTDatacenterAddressSet *)addressSet;
- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo;
- (void)contextDatacenterAuthTokenUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authToken:(id)authToken;
- (void)contextDatacenterTransportSchemesUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId;
- (void)contextDatacenterTransportSchemesUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId shouldReset:(bool)shouldReset;
- (void)contextIsPasswordRequiredUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId;
- (void)contextDatacenterPublicKeysUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId publicKeys:(NSArray<NSDictionary *> *)publicKeys;
- (MTSignal *)fetchContextDatacenterPublicKeys:(MTContext *)context datacenterId:(NSInteger)datacenterId;

View File

@ -491,10 +491,11 @@ static int32_t fixedTimeDifferenceValue = 0;
[listener contextDatacenterAddressSetUpdated:self datacenterId:datacenterId addressSet:addressSet];
}
if (previousAddressSetWasEmpty || updateSchemes || true) {
if (true) {
bool shouldReset = previousAddressSetWasEmpty || updateSchemes;
for (id<MTContextChangeListener> listener in currentListeners) {
if ([listener respondsToSelector:@selector(contextDatacenterTransportSchemesUpdated:datacenterId:)]) {
[listener contextDatacenterTransportSchemesUpdated:self datacenterId:datacenterId];
if ([listener respondsToSelector:@selector(contextDatacenterTransportSchemesUpdated:datacenterId:shouldReset:)]) {
[listener contextDatacenterTransportSchemesUpdated:self datacenterId:datacenterId shouldReset:shouldReset];
}
}
} else {
@ -664,8 +665,8 @@ static int32_t fixedTimeDifferenceValue = 0;
}
for (id<MTContextChangeListener> listener in currentListeners) {
if ([listener respondsToSelector:@selector(contextDatacenterTransportSchemesUpdated:datacenterId:)])
[listener contextDatacenterTransportSchemesUpdated:self datacenterId:datacenterId];
if ([listener respondsToSelector:@selector(contextDatacenterTransportSchemesUpdated:datacenterId:shouldReset:)])
[listener contextDatacenterTransportSchemesUpdated:self datacenterId:datacenterId shouldReset:true];
}
}
}];

View File

@ -2715,15 +2715,20 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
}
}
- (void)contextDatacenterTransportSchemesUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId {
- (void)contextDatacenterTransportSchemesUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId shouldReset:(bool)shouldReset {
[[MTProto managerQueue] dispatchOnQueue:^ {
if (context == _context && datacenterId == _datacenterId && ![self isStopped]) {
bool resolvedShouldReset = shouldReset;
if (_mtState & MTProtoStateAwaitingDatacenterScheme) {
[self setMtState:_mtState & (~MTProtoStateAwaitingDatacenterScheme)];
resolvedShouldReset = true;
}
[self resetTransport];
[self requestTransportTransaction];
if (resolvedShouldReset) {
[self resetTransport];
[self requestTransportTransaction];
}
}
}];
}

View File

@ -23,7 +23,7 @@ public struct NotificationSoundSettings {
}
public func notificationMuteSettingsController(presentationData: PresentationData, notificationSettings: MessageNotificationSettings, soundSettings: NotificationSoundSettings?, openSoundSettings: @escaping () -> Void, updateSettings: @escaping (Int32?) -> Void) -> ViewController {
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -35,11 +35,11 @@ public final class OpenInActionSheetController: ActionSheetController {
let theme = presentationData.theme
let strings = presentationData.strings
super.init(theme: ActionSheetControllerTheme(presentationTheme: theme))
super.init(theme: ActionSheetControllerTheme(presentationData: presentationData))
self.presentationDisposable = context.sharedContext.presentationData.start(next: { [weak self] presentationData in
if let strongSelf = self {
strongSelf.theme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
strongSelf.theme = ActionSheetControllerTheme(presentationData: presentationData)
}
})
@ -116,9 +116,6 @@ private final class OpenInActionSheetItem: ActionSheetItem {
}
}
private let titleFont = Font.medium(20.0)
private let textFont = Font.regular(11.0)
private final class OpenInActionSheetItemNode: ActionSheetItemNode {
let theme: ActionSheetControllerTheme
let strings: PresentationStrings
@ -132,6 +129,9 @@ private final class OpenInActionSheetItemNode: ActionSheetItemNode {
self.theme = theme
self.strings = strings
let titleFont = Font.medium(floor(theme.baseFontSize * 20.0 / 17.0))
let textFont = Font.regular(floor(theme.baseFontSize * 11.0 / 17.0))
self.titleNode = ASTextNode()
self.titleNode.isUserInteractionEnabled = false
self.titleNode.displaysAsynchronously = true
@ -216,6 +216,7 @@ private final class OpenInAppNode : ASDisplayNode {
}
func setup(postbox: Postbox, context: AccountContext, theme: ActionSheetControllerTheme, option: OpenInOption, invokeAction: @escaping (OpenInAction) -> Void) {
let textFont = Font.regular(floor(theme.baseFontSize * 11.0 / 17.0))
self.textNode.attributedText = NSAttributedString(string: option.title, font: textFont, textColor: theme.primaryTextColor, paragraphAlignment: .center)
let iconSize = CGSize(width: 60.0, height: 60.0)

View File

@ -59,7 +59,7 @@ public final class PasscodeSetupController: ViewController {
return
}
let controller = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let controller = ActionSheetController(presentationData: strongSelf.presentationData)
let dismissAction: () -> Void = { [weak controller] in
self?.controllerNode.activateInput()
controller?.dismissAnimated()

View File

@ -727,7 +727,7 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
}
if let currentValue = currentValue {
let controller = ActionSheetController(presentationTheme: self.presentationData.theme)
let controller = ActionSheetController(presentationData: self.presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -847,7 +847,7 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
return
}
let controller = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
let controller = ActionSheetController(presentationData: strongSelf.presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -916,7 +916,7 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
]
}
let controller = ActionSheetController(presentationTheme: self.presentationData.theme)
let controller = ActionSheetController(presentationData: self.presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -961,7 +961,7 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
}
private func deleteAllValues() {
let controller = ActionSheetController(presentationTheme: self.presentationData.theme)
let controller = ActionSheetController(presentationData: self.presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -2143,6 +2143,7 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
return self._itemParams!
}
private var presentationData: PresentationData
private var theme: PresentationTheme
private var strings: PresentationStrings
@ -2161,6 +2162,7 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
private let hiddenItemDisposable = MetaDisposable()
required init(initParams: SecureIdDocumentFormControllerNodeInitParams, presentationData: PresentationData) {
self.presentationData = presentationData
self.theme = presentationData.theme
self.strings = presentationData.strings
self.context = initParams.context
@ -2414,7 +2416,7 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
strongSelf.view.endEditing(true)
strongSelf.present(controller, nil)
case .gender:
let controller = ActionSheetController(presentationTheme: strongSelf.theme)
let controller = ActionSheetController(presentationData: strongSelf.presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -2756,7 +2758,7 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
return
}
let controller = ActionSheetController(presentationTheme: theme)
let controller = ActionSheetController(presentationData: self.presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -2816,7 +2818,7 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
}
private func openDocument(document: SecureIdVerificationDocument) {
let controller = ActionSheetController(presentationTheme: theme)
let controller = ActionSheetController(presentationData: self.presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -143,7 +143,7 @@ final class SecureIdDocumentGalleryFooterContentNode: GalleryFooterContentNode {
@objc func deleteButtonPressed() {
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
let items: [ActionSheetItem] = [
ActionSheetButtonItem(title: presentationData.strings.Common_Delete, color: .destructive, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated()

View File

@ -89,11 +89,11 @@ final class SecureIdDocumentTypeSelectionController: ActionSheetController {
self.completion = completion
super.init(theme: ActionSheetControllerTheme(presentationTheme: theme))
super.init(theme: ActionSheetControllerTheme(presentationData: presentationData))
self.presentationDisposable = context.sharedContext.presentationData.start(next: { [weak self] presentationData in
if let strongSelf = self {
strongSelf.theme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
strongSelf.theme = ActionSheetControllerTheme(presentationData: presentationData)
}
})

View File

@ -505,12 +505,12 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega
self.backgroundNode = ASImageNode()
self.backgroundNode.displaysAsynchronously = false
self.backgroundNode.displayWithoutProcessing = true
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 20.0, color: theme.actionSheet.inputBackgroundColor)
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 20.0, color: theme.list.freePlainInputField.backgroundColor)
self.inputNode = TextFieldNode()
self.inputNode.textField.font = Font.regular(17.0)
self.inputNode.textField.textColor = theme.actionSheet.inputTextColor
self.inputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(17.0), textColor: theme.actionSheet.inputPlaceholderColor)
self.inputNode.textField.textColor = theme.list.freePlainInputField.primaryColor
self.inputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(17.0), textColor: theme.list.freePlainInputField.placeholderColor)
self.hideButtonNode = HighlightableButtonNode()
@ -548,10 +548,10 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega
}
self.inputNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
self.hideButtonNode.setImage(generateTextHiddenImage(color: theme.actionSheet.inputClearButtonColor, on: false), for: [])
self.hideButtonNode.setImage(generateTextHiddenImage(color: theme.list.freePlainInputField.controlColor, on: false), for: [])
self.clearButtonNode = HighlightableButtonNode()
self.clearButtonNode.setImage(generateClearImage(color: theme.actionSheet.inputClearButtonColor), for: [])
self.clearButtonNode.setImage(generateClearImage(color: theme.list.freePlainInputField.controlColor), for: [])
self.clearButtonNode.isHidden = true
super.init()
@ -1198,11 +1198,27 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
transition.updateFrame(node: self.skipActionButtonNode, frame: buttonFrame)
transition.updateFrame(node: self.skipActionTitleNode, frame: CGRect(origin: CGPoint(x: buttonFrame.minX + floor((buttonFrame.width - skipActionSize.width) / 2.0), y: buttonFrame.minY + floor((buttonFrame.height - skipActionSize.height) / 2.0)), size: skipActionSize))
transition.updateFrame(node: self.changeEmailActionButtonNode, frame: CGRect(origin: CGPoint(x: buttonFrame.minX, y: buttonFrame.minY), size: CGSize(width: floor(buttonFrame.width / 2.0), height: buttonFrame.height)))
transition.updateFrame(node: self.resendCodeActionButtonNode, frame: CGRect(origin: CGPoint(x: buttonFrame.maxX - floor(buttonFrame.width / 2.0), y: buttonFrame.minY), size: CGSize(width: floor(buttonFrame.width / 2.0), height: buttonFrame.height)))
let changeEmailActionFrame: CGRect
let changeEmailActionButtonFrame: CGRect
let resendCodeActionFrame: CGRect
let resendCodeActionButtonFrame: CGRect
if changeEmailActionSize.width + resendCodeActionSize.width > layout.size.width - 24.0 {
changeEmailActionButtonFrame = CGRect(origin: CGPoint(x: buttonFrame.minX, y: buttonFrame.minY), size: CGSize(width: buttonFrame.width, height: buttonFrame.height))
changeEmailActionFrame = CGRect(origin: CGPoint(x: changeEmailActionButtonFrame.minX + floor((changeEmailActionButtonFrame.width - changeEmailActionSize.width) / 2.0), y: changeEmailActionButtonFrame.minY + floor((changeEmailActionButtonFrame.height - changeEmailActionSize.height) / 2.0)), size: changeEmailActionSize)
resendCodeActionButtonFrame = CGRect(origin: CGPoint(x: buttonFrame.minX, y: buttonFrame.maxY), size: CGSize(width: buttonFrame.width, height: buttonFrame.height))
resendCodeActionFrame = CGRect(origin: CGPoint(x: resendCodeActionButtonFrame.minX + floor((resendCodeActionButtonFrame.width - resendCodeActionSize.width) / 2.0), y: resendCodeActionButtonFrame.minY + floor((resendCodeActionButtonFrame.height - resendCodeActionSize.height) / 2.0)), size: resendCodeActionSize)
} else {
changeEmailActionButtonFrame = CGRect(origin: CGPoint(x: buttonFrame.minX, y: buttonFrame.minY), size: CGSize(width: floor(buttonFrame.width / 2.0), height: buttonFrame.height))
changeEmailActionFrame = CGRect(origin: CGPoint(x: changeEmailActionButtonFrame.minX, y: changeEmailActionButtonFrame.minY + floor((changeEmailActionButtonFrame.height - changeEmailActionSize.height) / 2.0)), size: changeEmailActionSize)
resendCodeActionButtonFrame = CGRect(origin: CGPoint(x: buttonFrame.maxX - floor(buttonFrame.width / 2.0), y: buttonFrame.minY), size: CGSize(width: floor(buttonFrame.width / 2.0), height: buttonFrame.height))
resendCodeActionFrame = CGRect(origin: CGPoint(x: resendCodeActionButtonFrame.maxX - resendCodeActionSize.width, y: resendCodeActionButtonFrame.minY + floor((resendCodeActionButtonFrame.height - resendCodeActionSize.height) / 2.0)), size: resendCodeActionSize)
}
transition.updateFrame(node: self.changeEmailActionTitleNode, frame: CGRect(origin: CGPoint(x: buttonFrame.minX, y: buttonFrame.minY + floor((buttonFrame.height - changeEmailActionSize.height) / 2.0)), size: changeEmailActionSize))
transition.updateFrame(node: self.resendCodeActionTitleNode, frame: CGRect(origin: CGPoint(x: buttonFrame.maxX - resendCodeActionSize.width, y: buttonFrame.minY + floor((buttonFrame.height - resendCodeActionSize.height) / 2.0)), size: resendCodeActionSize))
transition.updateFrame(node: self.changeEmailActionButtonNode, frame: changeEmailActionButtonFrame)
transition.updateFrame(node: self.resendCodeActionButtonNode, frame: resendCodeActionButtonFrame)
transition.updateFrame(node: self.changeEmailActionTitleNode, frame: changeEmailActionFrame)
transition.updateFrame(node: self.resendCodeActionTitleNode, frame: resendCodeActionFrame)
transition.animateView {
self.scrollNode.view.contentInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: layout.insets(options: [.input]).bottom, right: 0.0)

View File

@ -148,7 +148,7 @@ final class AvatarGalleryItemFooterContentNode: GalleryFooterContentNode {
@objc private func deleteButtonPressed() {
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
let items: [ActionSheetItem] = [
ActionSheetButtonItem(title: presentationData.strings.Common_Delete, color: .destructive, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated()

View File

@ -868,7 +868,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
}
}, dismissAdmin: {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
var items: [ActionSheetItem] = []
items.append(ActionSheetButtonItem(title: presentationData.strings.Channel_Moderator_AccessLevelRevoke, color: .destructive, font: .default, enabled: true, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()

View File

@ -461,7 +461,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
})
}, openTimeout: {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
let intervals: [Int32] = [
1 * 60 * 60 * 24,
7 * 60 * 60 * 24,
@ -499,7 +499,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
presentControllerImpl?(actionSheet, nil)
}, delete: {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
var items: [ActionSheetItem] = []
items.append(ActionSheetButtonItem(title: presentationData.strings.GroupPermission_Delete, color: .destructive, font: .default, enabled: true, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
@ -703,7 +703,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
var items: [ActionSheetItem] = []
items.append(ActionSheetTextItem(title: presentationData.strings.GroupPermission_ApplyAlertText(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0))
items.append(ActionSheetButtonItem(title: presentationData.strings.GroupPermission_ApplyAlertAction, color: .accent, font: .default, enabled: true, action: { [weak actionSheet] in

View File

@ -359,7 +359,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
return
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
var items: [ActionSheetItem] = []
if !participant.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder).isEmpty {
items.append(ActionSheetTextItem(title: participant.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)))

View File

@ -75,9 +75,13 @@ private final class ChannelDiscussionGroupActionSheetItemNode: ActionSheetItemNo
} else {
text = strings.Channel_DiscussionGroup_PrivateChannelLink(groupPeer.displayTitle(strings: strings, displayOrder: nameDisplayOrder), channelPeer.displayTitle(strings: strings, displayOrder: nameDisplayOrder))
}
let attributedText = NSMutableAttributedString(attributedString: NSAttributedString(string: text.0, font: Font.regular(14.0), textColor: theme.primaryTextColor))
let textFont = Font.regular(floor(theme.baseFontSize * 14.0 / 17.0))
let boldFont = Font.semibold(floor(theme.baseFontSize * 14.0 / 17.0))
let attributedText = NSMutableAttributedString(attributedString: NSAttributedString(string: text.0, font: textFont, textColor: theme.primaryTextColor))
for (_, range) in text.1 {
attributedText.addAttribute(.font, value: Font.semibold(14.0), range: range)
attributedText.addAttribute(.font, value: boldFont, range: range)
}
self.textNode.attributedText = attributedText

View File

@ -305,7 +305,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ChannelDiscussionGroupActionSheetItem(context: context, channelPeer: channelPeer, groupPeer: groupPeer, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder),
ActionSheetButtonItem(title: presentationData.strings.Channel_DiscussionGroup_LinkGroup, color: .accent, action: { [weak actionSheet] in

View File

@ -905,7 +905,7 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi
return
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -929,7 +929,7 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi
return
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -922,7 +922,7 @@ public func channelVisibilityController(context: AccountContext, peerId: PeerId,
})
}, revokePrivateLink: {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -869,7 +869,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
|> deliverOnMainQueue).start(next: { user in
if let user = user, let phone = user.phone, formatPhoneNumber(phone) == formatPhoneNumber(number) {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -992,7 +992,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
inviteAction(subject.contactData.basicData.phoneNumbers[0].value)
} else {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -1402,7 +1402,7 @@ private func addContactToExisting(context: AccountContext, parentController: Vie
func addContactOptionsController(context: AccountContext, peer: Peer?, contactData: DeviceContactExtendedData) -> ActionSheetController {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -1998,7 +1998,7 @@ public func groupInfoController(context: AccountContext, peerId originalPeerId:
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
if let channel = peerView.peers[peerView.peerId] as? TelegramChannel, channel.flags.contains(.isCreator), stateValue.with({ $0 }).editingState != nil {
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -2015,7 +2015,7 @@ public func groupInfoController(context: AccountContext, peerId originalPeerId:
])
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
} else if let peer = peerView.peers[peerView.peerId] {
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -208,7 +208,7 @@ public func groupsInCommonController(context: AccountContext, peerId: PeerId) ->
arguments.openPeer(peer.id)
}))
]
let contextController = ContextController(account: context.account, theme: presentationData.theme, strings: presentationData.strings, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: .single(items), reactionItems: [], gesture: gesture)
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: .single(items), reactionItems: [], gesture: gesture)
controller.presentInGlobalOverlay(contextController)
}
return controller

View File

@ -23,13 +23,13 @@ final class PeerBanTimeoutController: ActionSheetController {
let theme = presentationData.theme
let strings = presentationData.strings
super.init(theme: ActionSheetControllerTheme(presentationTheme: theme))
super.init(theme: ActionSheetControllerTheme(presentationData: presentationData))
self._ready.set(.single(true))
self.presentationDisposable = context.sharedContext.presentationData.start(next: { [weak self] presentationData in
if let strongSelf = self {
strongSelf.theme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
strongSelf.theme = ActionSheetControllerTheme(presentationData: presentationData)
}
})

View File

@ -111,7 +111,7 @@ public func presentPeerReportOptions(context: AccountContext, parent: ViewContro
public func peerReportOptionsController(context: AccountContext, subject: PeerReportSubject, present: @escaping (ViewController, Any?) -> Void, push: @escaping (ViewController) -> Void, completion: @escaping (Bool) -> Void) -> ViewController {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(theme: ActionSheetControllerTheme(presentationTheme: presentationData.theme))
let controller = ActionSheetController(theme: ActionSheetControllerTheme(presentationData: presentationData))
let options: [PeerReportOption] = [
.spam,

View File

@ -990,7 +990,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Pe
} else {
if value {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -1046,7 +1046,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Pe
})
}, deleteContact: {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -1112,7 +1112,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Pe
|> deliverOnMainQueue).start(next: { peer, _ in
if let peer = peer as? TelegramUser, let peerPhoneNumber = peer.phone, formatPhoneNumber(number) == formatPhoneNumber(peerPhoneNumber) {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -1584,7 +1584,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Pe
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let text: String = presentationData.strings.UserInfo_TapToCall
let tooltipController = TooltipController(content: .text(text), dismissByTapOutside: true)
let tooltipController = TooltipController(content: .text(text), baseFontSize: presentationData.fontSize.baseDisplaySize, dismissByTapOutside: true)
controller.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: { [weak resultItemNode] in
if let resultItemNode = resultItemNode {
return (resultItemNode, callButtonFrame)

View File

@ -468,7 +468,9 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat
entries.append(.useLessVoiceData(presentationData.theme, presentationData.strings.CallSettings_UseLessData, stringForUseLessDataSetting(dataSaving, strings: presentationData.strings)))
entries.append(.otherHeader(presentationData.theme, presentationData.strings.ChatSettings_Other))
entries.append(.shareSheet(presentationData.theme, "Share Sheet"))
if #available(iOSApplicationExtension 13.2, iOS 13.2, *) {
entries.append(.shareSheet(presentationData.theme, presentationData.strings.ChatSettings_IntentsSettings))
}
entries.append(.saveIncomingPhotos(presentationData.theme, presentationData.strings.Settings_SaveIncomingPhotos))
entries.append(.saveEditedPhotos(presentationData.theme, presentationData.strings.Settings_SaveEditedPhotos, data.generatedMediaStoreSettings.storeEditedPhotos))
entries.append(.openLinksIn(presentationData.theme, presentationData.strings.ChatSettings_OpenLinksIn, defaultWebBrowser))
@ -554,7 +556,7 @@ func dataAndStorageController(context: AccountContext, focusOnItemTag: DataAndSt
pushControllerImpl?(autodownloadMediaConnectionTypeController(context: context, connectionType: connectionType))
}, resetAutomaticDownload: {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: presentationData.strings.AutoDownloadSettings_ResetHelp),
ActionSheetButtonItem(title: presentationData.strings.AutoDownloadSettings_Reset, color: .destructive, action: { [weak actionSheet] in

View File

@ -150,7 +150,6 @@ private enum IntentsSettingsControllerEntry: ItemListNodeEntry {
} else {
return false
}
case let .suggestHeader(lhsTheme, lhsText):
if case let .suggestHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
@ -272,7 +271,7 @@ public func intentsSettingsController(context: AccountContext) -> ViewController
let _ = updateIntentsSettingsInteractively(accountManager: context.sharedContext.accountManager, f).start()
}, resetAll: {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.IntentsSettings_Reset, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()

View File

@ -389,7 +389,7 @@ func networkUsageStatsController(context: AccountContext) -> ViewController {
let arguments = NetworkUsageStatsControllerArguments(resetStatistics: { [weak stats] section in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -216,7 +216,7 @@ private enum ProxySettingsControllerEntry: ItemListNodeEntry {
case let .serversHeader(theme, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .addServer(theme, text, _):
return ProxySettingsActionItem(theme: theme, title: text, icon: .add, sectionId: self.section, editing: false, action: {
return ProxySettingsActionItem(presentationData: presentationData, title: text, icon: .add, sectionId: self.section, editing: false, action: {
arguments.addNewServer()
})
case let .server(_, theme, strings, settings, active, status, editing, enabled):
@ -230,7 +230,7 @@ private enum ProxySettingsControllerEntry: ItemListNodeEntry {
arguments.removeServer(settings)
})
case let .shareProxyList(theme, text):
return ProxySettingsActionItem(theme: theme, title: text, sectionId: self.section, editing: false, action: {
return ProxySettingsActionItem(presentationData: presentationData, title: text, sectionId: self.section, editing: false, action: {
arguments.shareProxyList()
})
case let .useForCalls(theme, text, value):

View File

@ -29,7 +29,7 @@ public final class ProxyServerActionSheetController: ActionSheetController {
}
public init(presentationData: PresentationData, accountManager: AccountManager, postbox: Postbox, network: Network, server: ProxyServerSettings, updatedPresentationData: Signal<PresentationData, NoError>?) {
let sheetTheme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
let sheetTheme = ActionSheetControllerTheme(presentationData: presentationData)
super.init(theme: sheetTheme)
self._ready.set(.single(true))
@ -63,7 +63,7 @@ public final class ProxyServerActionSheetController: ActionSheetController {
if let updatedPresentationData = updatedPresentationData {
self.presentationDisposable = updatedPresentationData.start(next: { [weak self] presentationData in
if let strongSelf = self {
strongSelf.theme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
strongSelf.theme = ActionSheetControllerTheme(presentationData: presentationData)
}
})
}
@ -97,8 +97,6 @@ private final class ProxyServerInfoItem: ActionSheetItem {
}
}
private let textFont = Font.regular(16.0)
private enum ProxyServerInfoStatusType {
case generic(String)
case failed(String)
@ -107,6 +105,7 @@ private enum ProxyServerInfoStatusType {
private final class ProxyServerInfoItemNode: ActionSheetItemNode {
private let theme: ActionSheetControllerTheme
private let strings: PresentationStrings
private let textFont: UIFont
private let network: Network
private let server: ProxyServerSettings
@ -122,6 +121,8 @@ private final class ProxyServerInfoItemNode: ActionSheetItemNode {
self.network = network
self.server = server
self.textFont = Font.regular(floor(theme.baseFontSize * 16.0 / 17.0))
var fieldNodes: [(ImmediateTextNode, ImmediateTextNode)] = []
let serverTitleNode = ImmediateTextNode()
serverTitleNode.isUserInteractionEnabled = false
@ -317,10 +318,12 @@ private final class ProxyServerActionItemNode: ActionSheetItemNode {
self.dismiss = dismiss
self.present = present
let titleFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0))
self.titleNode = ImmediateTextNode()
self.titleNode.isUserInteractionEnabled = false
self.titleNode.displaysAsynchronously = false
self.titleNode.attributedText = NSAttributedString(string: presentationData.strings.SocksProxySetup_ConnectAndSave, font: Font.regular(20.0), textColor: theme.controlAccentColor)
self.titleNode.attributedText = NSAttributedString(string: presentationData.strings.SocksProxySetup_ConnectAndSave, font: titleFont, textColor: theme.controlAccentColor)
self.activityIndicator = ActivityIndicator(type: .custom(theme.controlAccentColor, 22.0, 1.5, false))
self.activityIndicator.isHidden = true

View File

@ -13,15 +13,15 @@ enum ProxySettingsActionIcon {
}
final class ProxySettingsActionItem: ListViewItem, ItemListItem {
let theme: PresentationTheme
let presentationData: ItemListPresentationData
let title: String
let icon: ProxySettingsActionIcon
let editing: Bool
let sectionId: ItemListSectionId
let action: () -> Void
init(theme: PresentationTheme, title: String, icon: ProxySettingsActionIcon = .none, sectionId: ItemListSectionId, editing: Bool, action: @escaping () -> Void) {
self.theme = theme
init(presentationData: ItemListPresentationData, title: String, icon: ProxySettingsActionIcon = .none, sectionId: ItemListSectionId, editing: Bool, action: @escaping () -> Void) {
self.presentationData = presentationData
self.title = title
self.icon = icon
self.editing = editing
@ -75,8 +75,6 @@ final class ProxySettingsActionItem: ListViewItem, ItemListItem {
}
}
private let titleFont = Font.regular(17.0)
private final class ProxySettingsActionItemNode: ListViewItemNode {
private let backgroundNode: ASDisplayNode
private let topStripeNode: ASDisplayNode
@ -130,24 +128,26 @@ private final class ProxySettingsActionItemNode: ListViewItemNode {
return { item, params, neighbors in
var updatedTheme: PresentationTheme?
if currentItem?.theme !== item.theme {
updatedTheme = item.theme
let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize)
if currentItem?.presentationData.theme !== item.presentationData.theme {
updatedTheme = item.presentationData.theme
}
let leftInset: CGFloat = (item.icon != .none ? 50.0 : 16.0) + params.leftInset
let editingOffset: CGFloat = (item.editing ? 38.0 : 0.0)
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.title, font: titleFont, textColor: item.theme.list.itemAccentColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - editingOffset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.title, font: titleFont, textColor: item.presentationData.theme.list.itemAccentColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - editingOffset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let separatorHeight = UIScreenPixel
let insets = itemListNeighborsGroupedInsets(neighbors)
let contentSize = CGSize(width: params.width, height: 44.0)
let contentSize = CGSize(width: params.width, height: 22.0 + titleLayout.size.height)
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
let layoutSize = layout.size
let icon = item.icon == .add ? PresentationResourcesItemList.plusIconImage(item.theme) : nil
let icon = item.icon == .add ? PresentationResourcesItemList.plusIconImage(item.presentationData.theme) : nil
return (layout, { [weak self] animated in
if let strongSelf = self {
@ -156,10 +156,10 @@ private final class ProxySettingsActionItemNode: ListViewItemNode {
strongSelf.accessibilityLabel = item.title
if let _ = updatedTheme {
strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor
strongSelf.highlightedBackgroundNode.backgroundColor = item.theme.list.itemHighlightedBackgroundColor
strongSelf.topStripeNode.backgroundColor = item.presentationData.theme.list.itemBlocksSeparatorColor
strongSelf.bottomStripeNode.backgroundColor = item.presentationData.theme.list.itemBlocksSeparatorColor
strongSelf.backgroundNode.backgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor
}
let _ = titleApply()
@ -213,7 +213,7 @@ private final class ProxySettingsActionItemNode: ListViewItemNode {
strongSelf.bottomStripeNode.isHidden = hasCorners
}
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)

View File

@ -22,7 +22,7 @@ public final class ShareProxyServerActionSheetController: ActionSheetController
private var isDismissed: Bool = false
public init(presentationData: PresentationData, updatedPresentationData: Signal<PresentationData, NoError>, link: String) {
let sheetTheme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
let sheetTheme = ActionSheetControllerTheme(presentationData: presentationData)
super.init(theme: sheetTheme)
let presentActivityController: (Any) -> Void = { [weak self] item in
@ -67,7 +67,7 @@ public final class ShareProxyServerActionSheetController: ActionSheetController
self.presentationDisposable = updatedPresentationData.start(next: { [weak self] presentationData in
if let strongSelf = self {
strongSelf.theme = ActionSheetControllerTheme(presentationTheme: presentationData.theme)
strongSelf.theme = ActionSheetControllerTheme(presentationData: presentationData)
}
})
}
@ -119,13 +119,15 @@ private final class ProxyServerQRCodeItemNode: ActionSheetItemNode {
self.link = link
self.ready = ready
let textFont = Font.regular(floor(theme.baseFontSize * 13.0 / 17.0))
self.label = ASTextNode()
self.label.isUserInteractionEnabled = false
self.label.maximumNumberOfLines = 0
self.label.displaysAsynchronously = false
self.label.truncationMode = .byTruncatingTail
self.label.isUserInteractionEnabled = false
self.label.attributedText = NSAttributedString(string: strings.SocksProxySetup_ShareQRCodeInfo, font: ActionSheetTextNode.defaultFont, textColor: self.theme.secondaryTextColor, paragraphAlignment: .center)
self.label.attributedText = NSAttributedString(string: strings.SocksProxySetup_ShareQRCodeInfo, font: textFont, textColor: self.theme.secondaryTextColor, paragraphAlignment: .center)
self.imageNode = TransformImageNode()
self.imageNode.clipsToBounds = true

View File

@ -402,7 +402,7 @@ public func storageUsageController(context: AccountContext, cacheUsagePromise: P
|> deliverOnMainQueue).start(next: { [weak statsPromise] result in
if let result = result, case let .result(stats) = result {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
@ -624,7 +624,7 @@ public func storageUsageController(context: AccountContext, cacheUsagePromise: P
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -113,7 +113,7 @@ public func debugAccountsController(context: AccountContext, accountManager: Acc
}).start()
}, loginNewAccount: {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme)
let controller = ActionSheetController(presentationData: presentationData)
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}

View File

@ -155,7 +155,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
let _ = (Logger.shared.collectLogs()
|> deliverOnMainQueue).start(next: { logs in
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
var items: [ActionSheetButtonItem] = []
@ -206,7 +206,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
let _ = (Logger.shared.collectLogs()
|> deliverOnMainQueue).start(next: { logs in
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
var items: [ActionSheetButtonItem] = []
@ -284,7 +284,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
let _ = (Logger.shared.collectShortLogFiles()
|> deliverOnMainQueue).start(next: { logs in
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
var items: [ActionSheetButtonItem] = []
@ -409,7 +409,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
case let .resetData(theme):
return ItemListActionItem(presentationData: presentationData, title: "Reset Data", kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: {
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: "All data will be lost."),
ActionSheetButtonItem(title: "Reset Data", color: .destructive, action: { [weak actionSheet] in
@ -431,7 +431,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
return
}
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
let actionSheet = ActionSheetController(presentationData: presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: "All secret chats will be lost."),
ActionSheetButtonItem(title: "Clear Database", color: .destructive, action: { [weak actionSheet] in

Some files were not shown because too many files have changed in this diff Show More