mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-15 18:59:54 +00:00
Added tooltip when tapping on forwarded messages from private channels
Various UI fixes
This commit is contained in:
parent
2c17ccdd7d
commit
fe3d243272
@ -71,7 +71,7 @@ final class ChatBackgroundNode: ASDisplayNode {
|
||||
private var backgroundImageForWallpaper: (TelegramWallpaper, Bool, UIImage)?
|
||||
private var serviceBackgroundColorForWallpaper: (TelegramWallpaper, UIColor)?
|
||||
|
||||
func chatControllerBackgroundImage(wallpaper: TelegramWallpaper, mediaBox: MediaBox) -> UIImage? {
|
||||
func chatControllerBackgroundImage(wallpaper: TelegramWallpaper, mediaBox: MediaBox, composed: Bool = false) -> UIImage? {
|
||||
var backgroundImage: UIImage?
|
||||
if wallpaper == backgroundImageForWallpaper?.0, (wallpaper.settings?.blur ?? false) == backgroundImageForWallpaper?.1 {
|
||||
backgroundImage = backgroundImageForWallpaper?.2
|
||||
@ -88,7 +88,7 @@ func chatControllerBackgroundImage(wallpaper: TelegramWallpaper, mediaBox: Media
|
||||
})
|
||||
case let .image(representations, settings):
|
||||
if let largest = largestImageRepresentation(representations) {
|
||||
if settings.blur {
|
||||
if settings.blur && composed {
|
||||
var image: UIImage?
|
||||
let _ = mediaBox.cachedResourceRepresentation(largest.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true, attemptSynchronously: true).start(next: { data in
|
||||
if data.complete {
|
||||
@ -111,7 +111,7 @@ func chatControllerBackgroundImage(wallpaper: TelegramWallpaper, mediaBox: Media
|
||||
})
|
||||
backgroundImage = image
|
||||
} else {
|
||||
if file.settings.blur {
|
||||
if file.settings.blur && composed {
|
||||
var image: UIImage?
|
||||
let _ = mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true, attemptSynchronously: true).start(next: { data in
|
||||
if data.complete {
|
||||
|
||||
@ -830,7 +830,6 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
|
||||
})
|
||||
#endif
|
||||
|
||||
|
||||
if let lockViewFrame = self.titleView.lockViewFrame, !self.didShowPasscodeLockTooltipController {
|
||||
self.passcodeLockTooltipDisposable.set(combineLatest(queue: .mainQueue(), ApplicationSpecificNotice.getPasscodeLockTips(accountManager: self.context.sharedContext.accountManager), self.context.sharedContext.accountManager.accessChallengeData() |> take(1)).start(next: { [weak self] tooltipValue, passcodeView in
|
||||
if let strongSelf = self {
|
||||
@ -1069,16 +1068,6 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
|
||||
return nil
|
||||
}
|
||||
|
||||
var isEditing = false
|
||||
self.chatListDisplayNode.chatListNode.updateState { state in
|
||||
isEditing = state.editing
|
||||
return state
|
||||
}
|
||||
|
||||
if isEditing {
|
||||
return nil
|
||||
}
|
||||
|
||||
let listLocation = self.view.convert(location, to: self.chatListDisplayNode.chatListNode.view)
|
||||
|
||||
var selectedNode: ChatListItemNode?
|
||||
|
||||
@ -837,9 +837,9 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
if !mentionBadgeLayout.width.isZero {
|
||||
if !badgeSize.isZero {
|
||||
badgeSize += badgeLayout.width + 4.0
|
||||
badgeSize += mentionBadgeLayout.width + 4.0
|
||||
} else {
|
||||
badgeSize += badgeLayout.width + 5.0
|
||||
badgeSize += mentionBadgeLayout.width + 5.0
|
||||
}
|
||||
}
|
||||
if let currentPinnedIconImage = currentPinnedIconImage {
|
||||
|
||||
@ -159,14 +159,15 @@ final class ChatListSearchRecentPeersNode: ASDisplayNode {
|
||||
let peersDisposable = DisposableSet()
|
||||
|
||||
let recent: Signal<([Peer], [PeerId: UnreadSearchBadge], [PeerId : PeerPresence]), NoError> = recentPeers(account: account)
|
||||
|> filter { value -> Bool in
|
||||
switch value {
|
||||
case .disabled:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
} |> mapToSignal { recent in
|
||||
|> filter { value -> Bool in
|
||||
switch value {
|
||||
case .disabled:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|> mapToSignal { recent in
|
||||
switch recent {
|
||||
case .disabled:
|
||||
return .single(([], [:], [:]))
|
||||
|
||||
@ -317,10 +317,12 @@ private class ChatListStatusChecksNode: ChatListStatusContentNode {
|
||||
default:
|
||||
break
|
||||
}
|
||||
var animating = false
|
||||
if let previousState = self.state, case .delivered = previousState, case .read = state, animated {
|
||||
animating = true
|
||||
self.animateProgress(from: 1.0, to: 2.0)
|
||||
}
|
||||
if !animated {
|
||||
if !animating {
|
||||
if case .delivered = state {
|
||||
self.effectiveProgress = 1.0
|
||||
} else if case .read = state {
|
||||
|
||||
@ -5,8 +5,6 @@ final class ChatListTitleLockView: UIView {
|
||||
private let topView: UIImageView
|
||||
private let bottomView: UIImageView
|
||||
|
||||
private var isLocked: Bool = false
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.topView = UIImageView()
|
||||
self.bottomView = UIImageView()
|
||||
@ -21,58 +19,15 @@ final class ChatListTitleLockView: UIView {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func setIsLocked( _ isLocked: Bool, theme: PresentationTheme, animated: Bool) {
|
||||
self.isLocked = isLocked
|
||||
if animated {
|
||||
let topViewCopy = UIImageView(image: self.topView.image)
|
||||
topViewCopy.frame = self.topView.frame
|
||||
self.addSubview(topViewCopy)
|
||||
|
||||
let bottomViewCopy = UIImageView(image: self.bottomView.image)
|
||||
bottomViewCopy.frame = self.bottomView.frame
|
||||
self.addSubview(bottomViewCopy)
|
||||
|
||||
self.topView.image = self.isLocked ? PresentationResourcesChatList.lockTopLockedImage(theme) : PresentationResourcesChatList.lockTopUnlockedImage(theme)
|
||||
self.bottomView.image = self.isLocked ? PresentationResourcesChatList.lockBottomLockedImage(theme) : PresentationResourcesChatList.lockBottomUnlockedImage(theme)
|
||||
|
||||
self.topView.alpha = 0.5
|
||||
self.bottomView.alpha = 0.5
|
||||
|
||||
let block: () -> Void = {
|
||||
self.layoutItems()
|
||||
topViewCopy.frame = self.topView.frame
|
||||
bottomViewCopy.frame = self.bottomView.frame
|
||||
}
|
||||
|
||||
UIView.animate(withDuration: 0.1, animations: {
|
||||
topViewCopy.alpha = 0.0
|
||||
bottomViewCopy.alpha = 0.0
|
||||
|
||||
self.topView.alpha = 1.0
|
||||
self.bottomView.alpha = 1.0
|
||||
})
|
||||
|
||||
UIView.animate(withDuration: 0.3, delay: 0.0, usingSpringWithDamping: 0.39, initialSpringVelocity: 0.0, options: [], animations: {
|
||||
block()
|
||||
}, completion: { _ in
|
||||
topViewCopy.removeFromSuperview()
|
||||
bottomViewCopy.removeFromSuperview()
|
||||
})
|
||||
} else {
|
||||
self.topView.image = self.isLocked ? PresentationResourcesChatList.lockTopLockedImage(theme) : PresentationResourcesChatList.lockTopUnlockedImage(theme)
|
||||
self.bottomView.image = self.isLocked ? PresentationResourcesChatList.lockBottomLockedImage(theme) : PresentationResourcesChatList.lockBottomUnlockedImage(theme)
|
||||
self.layoutItems()
|
||||
}
|
||||
func updateTheme(_ theme: PresentationTheme) {
|
||||
self.topView.image = PresentationResourcesChatList.lockTopUnlockedImage(theme)
|
||||
self.bottomView.image = PresentationResourcesChatList.lockBottomUnlockedImage(theme)
|
||||
self.layoutItems()
|
||||
}
|
||||
|
||||
private func layoutItems() {
|
||||
if self.isLocked {
|
||||
self.topView.frame = CGRect(x: floorToScreenPixels((10.0 - 7.0) / 2.0), y: 0.0, width: 7.0, height: 6.0)
|
||||
self.bottomView.frame = CGRect(x: 0.0, y: 6.0, width: 10.0, height: 7.0)
|
||||
} else {
|
||||
self.topView.frame = CGRect(x: 6.0, y: 0.0, width: 7.0, height: 6.0)
|
||||
self.bottomView.frame = CGRect(x: 0.0, y: 6.0, width: 10.0, height: 7.0)
|
||||
}
|
||||
self.topView.frame = CGRect(x: 6.0, y: 0.0, width: 7.0, height: 6.0)
|
||||
self.bottomView.frame = CGRect(x: 0.0, y: 6.0, width: 10.0, height: 8.0)
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
|
||||
@ -39,11 +39,10 @@ final class ChatListTitleView: UIView, NavigationBarTitleView, NavigationBarTitl
|
||||
self.buttonView.isHidden = !self.title.isPasscodeSet
|
||||
if self.title.isPasscodeSet && !self.title.activity {
|
||||
self.lockView.isHidden = false
|
||||
self.lockView.setIsLocked(self.title.isManuallyLocked, theme: self.theme, animated: !self.bounds.size.width.isZero)
|
||||
} else {
|
||||
self.lockView.isHidden = true
|
||||
self.lockView.setIsLocked(false, theme: self.theme, animated: false)
|
||||
}
|
||||
self.lockView.updateTheme(self.theme)
|
||||
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
@ -60,11 +59,7 @@ final class ChatListTitleView: UIView, NavigationBarTitleView, NavigationBarTitl
|
||||
didSet {
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.title.text, font: Font.bold(17.0), textColor: self.theme.rootController.navigationBar.primaryTextColor)
|
||||
|
||||
if self.isPasscodeSet {
|
||||
self.lockView.setIsLocked(self.isManuallyLocked, theme: self.theme, animated: false)
|
||||
} else {
|
||||
self.lockView.setIsLocked(false, theme: self.theme, animated: false)
|
||||
}
|
||||
self.lockView.updateTheme(self.theme)
|
||||
|
||||
self.activityIndicator.type = .custom(self.theme.rootController.navigationBar.primaryTextColor, 22.0, 1.5, false)
|
||||
self.proxyNode.theme = self.theme
|
||||
@ -202,7 +197,7 @@ final class ChatListTitleView: UIView, NavigationBarTitleView, NavigationBarTitl
|
||||
let buttonX = max(0.0, titleFrame.minX - 10.0)
|
||||
self.buttonView.frame = CGRect(origin: CGPoint(x: buttonX, y: 0.0), size: CGSize(width: min(titleFrame.maxX + 28.0, size.width) - buttonX, height: size.height))
|
||||
|
||||
self.lockView.frame = CGRect(x: titleFrame.maxX + 6.0, y: titleFrame.minY + 3.0, width: 2.0, height: 2.0)
|
||||
self.lockView.frame = CGRect(x: titleFrame.maxX + 6.0, y: titleFrame.minY + 2.0, width: 2.0, height: 2.0)
|
||||
|
||||
self.activityIndicator.frame = CGRect(origin: CGPoint(x: titleFrame.minX - indicatorSize.width - 4.0, y: titleFrame.minY - 1.0), size: indicatorSize)
|
||||
}
|
||||
|
||||
@ -429,6 +429,13 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
|
||||
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
|
||||
} else {
|
||||
if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil {
|
||||
if case .member = channel.participationStatus {
|
||||
} else {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame)
|
||||
return
|
||||
}
|
||||
}
|
||||
item.controllerInteraction.openPeer(item.effectiveAuthorId ?? author.id, navigate, item.message)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1654,6 +1654,13 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
||||
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
|
||||
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
|
||||
} else {
|
||||
if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil {
|
||||
if case .member = channel.participationStatus {
|
||||
} else {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame)
|
||||
return
|
||||
}
|
||||
}
|
||||
item.controllerInteraction.openPeer(item.effectiveAuthorId ?? author.id, navigate, item.message)
|
||||
}
|
||||
}
|
||||
@ -1696,6 +1703,13 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
||||
if let forwardInfoNode = self.forwardInfoNode, forwardInfoNode.frame.contains(location) {
|
||||
if let item = self.item, let forwardInfo = item.message.forwardInfo {
|
||||
if let sourceMessageId = forwardInfo.sourceMessageId {
|
||||
if let channel = forwardInfo.author as? TelegramChannel, channel.username == nil {
|
||||
if case .member = channel.participationStatus {
|
||||
} else {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
|
||||
} else if let id = forwardInfo.source?.id ?? forwardInfo.author?.id {
|
||||
item.controllerInteraction.openPeer(id, .info, nil)
|
||||
|
||||
@ -2,6 +2,7 @@ import Foundation
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
|
||||
private let prefixFont = Font.regular(13.0)
|
||||
private let peerFont = Font.medium(13.0)
|
||||
@ -48,9 +49,21 @@ class ChatMessageForwardInfoNode: ASDisplayNode {
|
||||
completeSourceString = strings.Message_ForwardedMessageShort(peerString)
|
||||
}
|
||||
|
||||
var highlight = true
|
||||
if let peer = peer {
|
||||
if let channel = peer as? TelegramChannel, channel.username == nil {
|
||||
if case .member = channel.participationStatus {
|
||||
} else {
|
||||
highlight = false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
highlight = false
|
||||
}
|
||||
|
||||
let completeString: NSString = completeSourceString.0 as NSString
|
||||
let string = NSMutableAttributedString(string: completeString as String, attributes: [NSAttributedStringKey.foregroundColor: titleColor, NSAttributedStringKey.font: prefixFont])
|
||||
if peer != nil, let range = completeSourceString.1.first?.1 {
|
||||
if highlight, let range = completeSourceString.1.first?.1 {
|
||||
string.addAttributes([NSAttributedStringKey.font: peerFont], range: range)
|
||||
}
|
||||
let (textLayout, textApply) = textNodeLayout(TextNodeLayoutArguments(attributedString: string, backgroundColor: nil, maximumNumberOfLines: 2, truncationType: .end, constrainedSize: constrainedSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
@ -534,6 +534,13 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
|
||||
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
|
||||
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
|
||||
} else {
|
||||
if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil {
|
||||
if case .member = channel.participationStatus {
|
||||
} else {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
item.controllerInteraction.openPeer(item.effectiveAuthorId ?? author.id, navigate, item.message)
|
||||
}
|
||||
}
|
||||
@ -554,6 +561,13 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
|
||||
if let forwardInfoNode = self.forwardInfoNode, forwardInfoNode.frame.contains(location) {
|
||||
if let item = self.item, let forwardInfo = item.message.forwardInfo {
|
||||
if let sourceMessageId = forwardInfo.sourceMessageId {
|
||||
if let channel = forwardInfo.author as? TelegramChannel, channel.username == nil {
|
||||
if case .member = channel.participationStatus {
|
||||
} else {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
|
||||
} else if let id = forwardInfo.source?.id ?? forwardInfo.author?.id {
|
||||
item.controllerInteraction.openPeer(id, .chat(textInputState: nil, messageId: nil), nil)
|
||||
|
||||
@ -563,6 +563,13 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
||||
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
|
||||
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
|
||||
} else {
|
||||
if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil {
|
||||
if case .member = channel.participationStatus {
|
||||
} else {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame)
|
||||
return
|
||||
}
|
||||
}
|
||||
item.controllerInteraction.openPeer(item.effectiveAuthorId ?? author.id, navigate, item.message)
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,6 +120,8 @@ final class HorizontalPeerItemNode: ListViewItemNode {
|
||||
func asyncLayout() -> (HorizontalPeerItem, ListViewItemLayoutParams) -> (ListViewItemNodeLayout, (Bool) -> Void) {
|
||||
let badgeTextLayout = TextNode.asyncLayout(self.badgeTextNode)
|
||||
let onlineLayout = self.onlineNode.asyncLayout()
|
||||
|
||||
let currentItem = self.item
|
||||
|
||||
return { [weak self] item, params in
|
||||
let itemLayout = ListViewItemNodeLayout(contentSize: CGSize(width: 92.0, height: item.customWidth ?? 80.0), insets: UIEdgeInsets())
|
||||
@ -177,6 +179,10 @@ final class HorizontalPeerItemNode: ListViewItemNode {
|
||||
}
|
||||
|
||||
let (onlineLayout, onlineApply) = onlineLayout(online)
|
||||
var animateContent = false
|
||||
if let currentItem = currentItem, currentItem.peer.id == item.peer.id {
|
||||
animateContent = true
|
||||
}
|
||||
|
||||
return (itemLayout, { animated in
|
||||
if let strongSelf = self {
|
||||
@ -207,7 +213,7 @@ final class HorizontalPeerItemNode: ListViewItemNode {
|
||||
strongSelf.onlineNode.frame = CGRect(x: itemLayout.size.width - onlineLayout.width - 18.0, y: itemLayout.size.height - onlineLayout.height - 18.0, width: onlineLayout.width, height: onlineLayout.height)
|
||||
|
||||
let _ = badgeApply()
|
||||
let _ = onlineApply(true)
|
||||
let _ = onlineApply(animateContent)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -43,13 +43,13 @@ private func chatMessageGalleryControllerData(context: AccountContext, message:
|
||||
} else if let image = media as? TelegramMediaImage {
|
||||
galleryMedia = image
|
||||
} else if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content {
|
||||
if let file = content.file {
|
||||
galleryMedia = file
|
||||
} else if let image = content.image {
|
||||
if ["photo", "document", "video", "gif"].contains(content.type) {
|
||||
galleryMedia = image
|
||||
}
|
||||
if let file = content.file {
|
||||
galleryMedia = file
|
||||
} else if let image = content.image {
|
||||
if ["photo", "document", "video", "gif", "telegram_album"].contains(content.type) {
|
||||
galleryMedia = image
|
||||
}
|
||||
}
|
||||
|
||||
if let instantPage = content.instantPage, let galleryMedia = galleryMedia {
|
||||
switch instantPageType(of: content) {
|
||||
|
||||
@ -4,6 +4,16 @@ import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
|
||||
final public class PasscodeEntryControllerPresentationArguments {
|
||||
let animated: Bool
|
||||
let lockIconInitialFrame: () -> CGRect
|
||||
|
||||
public init(animated: Bool = true, lockIconInitialFrame: @escaping () -> CGRect) {
|
||||
self.animated = animated
|
||||
self.lockIconInitialFrame = lockIconInitialFrame
|
||||
}
|
||||
}
|
||||
|
||||
final public class PasscodeEntryController: ViewController {
|
||||
private var controllerNode: PasscodeEntryControllerNode {
|
||||
return self.displayNode as! PasscodeEntryControllerNode
|
||||
@ -15,18 +25,18 @@ final public class PasscodeEntryController: ViewController {
|
||||
|
||||
private let challengeData: PostboxAccessChallengeData
|
||||
private let enableBiometrics: Bool
|
||||
private let animated: Bool
|
||||
private let arguments: PasscodeEntryControllerPresentationArguments
|
||||
|
||||
public var presentationCompleted: (() -> Void)?
|
||||
|
||||
private let biometricsDisposable = MetaDisposable()
|
||||
|
||||
public init(context: AccountContext, challengeData: PostboxAccessChallengeData, enableBiometrics: Bool, animated: Bool = false) {
|
||||
public init(context: AccountContext, challengeData: PostboxAccessChallengeData, enableBiometrics: Bool, arguments: PasscodeEntryControllerPresentationArguments) {
|
||||
self.context = context
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.challengeData = challengeData
|
||||
self.enableBiometrics = enableBiometrics
|
||||
self.animated = animated
|
||||
self.arguments = arguments
|
||||
|
||||
super.init(navigationBarPresentationData: nil)
|
||||
|
||||
@ -123,7 +133,7 @@ final public class PasscodeEntryController: ViewController {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
self.controllerNode.activateInput()
|
||||
if self.animated {
|
||||
if self.arguments.animated {
|
||||
Queue.mainQueue().after(0.5) {
|
||||
serviceSoundManager.playLockSound()
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
||||
|
||||
switch self.wallpaper {
|
||||
case .image, .file:
|
||||
if let image = chatControllerBackgroundImage(wallpaper: self.wallpaper, mediaBox: self.context.sharedContext.accountManager.mediaBox) {
|
||||
if let image = chatControllerBackgroundImage(wallpaper: self.wallpaper, mediaBox: self.context.sharedContext.accountManager.mediaBox, composed: false) {
|
||||
self.background = ImageBasedPasscodeBackground(image: image, size: validLayout.size)
|
||||
} else {
|
||||
self.background = DefaultPasscodeBackground(size: validLayout.size)
|
||||
@ -210,7 +210,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
||||
transition.updateFrame(view: self.effectView, frame: bounds)
|
||||
|
||||
let iconSize = CGSize(width: 35.0, height: 37.0)
|
||||
transition.updateFrame(node: self.iconNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0) + 11.0, y: layout.insets(options: .statusBar).top + 15.0), size: iconSize))
|
||||
transition.updateFrame(node: self.iconNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0) + 6.0, y: layout.insets(options: .statusBar).top + 15.0), size: iconSize))
|
||||
|
||||
let titleSize = self.titleNode.updateLayout(layout: layout, transition: transition)
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 123.0), size: titleSize))
|
||||
|
||||
@ -3,8 +3,17 @@ import Display
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
|
||||
private let titleFont = Font.regular(40.0)
|
||||
private let subtitleFont: UIFont = {
|
||||
private let regularTitleFont = Font.regular(36.0)
|
||||
private let regularSubtitleFont: UIFont = {
|
||||
if #available(iOS 8.2, *) {
|
||||
return UIFont.systemFont(ofSize: 10.0, weight: UIFont.Weight.bold)
|
||||
} else {
|
||||
return CTFontCreateWithName("HelveticaNeue-Bold" as CFString, 10.0, nil)
|
||||
}
|
||||
}()
|
||||
|
||||
private let largeTitleFont = Font.regular(40.0)
|
||||
private let largeSubtitleFont: UIFont = {
|
||||
if #available(iOS 8.2, *) {
|
||||
return UIFont.systemFont(ofSize: 12.0, weight: UIFont.Weight.bold)
|
||||
} else {
|
||||
@ -35,13 +44,32 @@ private func generateButtonImage(background: PasscodeBackground, frame: CGRect,
|
||||
context.setAlpha(1.0)
|
||||
context.textMatrix = .identity
|
||||
|
||||
var offset: CGFloat = -11.0
|
||||
if subtitle.isEmpty {
|
||||
offset -= 7.0
|
||||
let titleFont: UIFont
|
||||
let subtitleFont: UIFont
|
||||
let titleOffset: CGFloat
|
||||
let subtitleOffset: CGFloat
|
||||
if size.width > 80.0 {
|
||||
titleFont = largeTitleFont
|
||||
subtitleFont = largeSubtitleFont
|
||||
if subtitle.isEmpty {
|
||||
titleOffset = -18.0
|
||||
} else {
|
||||
titleOffset = -11.0
|
||||
}
|
||||
subtitleOffset = -54.0
|
||||
} else {
|
||||
titleFont = regularTitleFont
|
||||
subtitleFont = regularSubtitleFont
|
||||
if subtitle.isEmpty {
|
||||
titleOffset = -17.0
|
||||
} else {
|
||||
titleOffset = -10.0
|
||||
}
|
||||
subtitleOffset = -48.0
|
||||
}
|
||||
|
||||
let titlePath = CGMutablePath()
|
||||
titlePath.addRect(bounds.offsetBy(dx: 0.0, dy: offset))
|
||||
titlePath.addRect(bounds.offsetBy(dx: 0.0, dy: titleOffset))
|
||||
let titleString = NSAttributedString(string: title, font: titleFont, textColor: .white, paragraphAlignment: .center)
|
||||
let titleFramesetter = CTFramesetterCreateWithAttributedString(titleString as CFAttributedString)
|
||||
let titleFrame = CTFramesetterCreateFrame(titleFramesetter, CFRangeMake(0, titleString.length), titlePath, nil)
|
||||
@ -49,7 +77,7 @@ private func generateButtonImage(background: PasscodeBackground, frame: CGRect,
|
||||
|
||||
if !subtitle.isEmpty {
|
||||
let subtitlePath = CGMutablePath()
|
||||
subtitlePath.addRect(bounds.offsetBy(dx: 0.0, dy: -54.0))
|
||||
subtitlePath.addRect(bounds.offsetBy(dx: 0.0, dy: subtitleOffset))
|
||||
let subtitleString = NSAttributedString(string: subtitle, font: subtitleFont, textColor: .white, paragraphAlignment: .center)
|
||||
let subtitleFramesetter = CTFramesetterCreateWithAttributedString(subtitleString as CFAttributedString)
|
||||
let subtitleFrame = CTFramesetterCreateFrame(subtitleFramesetter, CFRangeMake(0, subtitleString.length), subtitlePath, nil)
|
||||
@ -205,75 +233,85 @@ final class PasscodeEntryKeyboardNode: ASDisplayNode {
|
||||
let size: CGSize
|
||||
let offset: CGFloat
|
||||
|
||||
let height = Int(max(layout.size.width, layout.size.height))
|
||||
switch height {
|
||||
case 1024, 1194, 1366:
|
||||
buttonSize = 81.0
|
||||
horizontalSecond = 106.0
|
||||
horizontalThird = 212.0
|
||||
verticalSecond = 100.0 + UIScreenPixel
|
||||
verticalThird = 202.0
|
||||
verticalFourth = 303.0
|
||||
size = CGSize(width: 293.0, height: 384.0)
|
||||
offset = 0.0
|
||||
case 896:
|
||||
buttonSize = 85.0
|
||||
horizontalSecond = 115.0
|
||||
horizontalThird = 230.0
|
||||
verticalSecond = 100.0
|
||||
verticalThird = 200.0
|
||||
verticalFourth = 300.0
|
||||
size = CGSize(width: 315.0, height: 385.0)
|
||||
offset = 240.0
|
||||
case 812:
|
||||
buttonSize = 85.0
|
||||
horizontalSecond = 115.0
|
||||
horizontalThird = 230.0
|
||||
verticalSecond = 100.0
|
||||
verticalThird = 200.0
|
||||
verticalFourth = 300.0
|
||||
size = CGSize(width: 315.0, height: 385.0)
|
||||
offset = 240.0
|
||||
case 736:
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 103.5
|
||||
horizontalThird = 206.0
|
||||
verticalSecond = 90.0
|
||||
verticalThird = 180.0
|
||||
verticalFourth = 270.0
|
||||
size = CGSize(width: 281.0, height: 345.0)
|
||||
offset = 0.0
|
||||
case 667:
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 103.5
|
||||
horizontalThird = 206.0
|
||||
verticalSecond = 90.0
|
||||
verticalThird = 180.0
|
||||
verticalFourth = 270.0
|
||||
size = CGSize(width: 281.0, height: 345.0)
|
||||
offset = 0.0
|
||||
case 568:
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 95.0
|
||||
horizontalThird = 190.0
|
||||
verticalSecond = 88.0
|
||||
verticalThird = 176.0
|
||||
verticalFourth = 264.0
|
||||
size = CGSize(width: 265.0, height: 339.0)
|
||||
offset = 0.0
|
||||
default:
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 95.0
|
||||
horizontalThird = 190.0
|
||||
verticalSecond = 88.0
|
||||
verticalThird = 176.0
|
||||
verticalFourth = 264.0
|
||||
size = CGSize(width: 265.0, height: 339.0)
|
||||
offset = 0.0
|
||||
let metrics = DeviceMetrics.forScreenSize(layout.size)
|
||||
if let metrics = metrics {
|
||||
switch metrics {
|
||||
case .iPhone4:
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 95.0
|
||||
horizontalThird = 190.0
|
||||
verticalSecond = 88.0
|
||||
verticalThird = 176.0
|
||||
verticalFourth = 264.0
|
||||
size = CGSize(width: 265.0, height: 339.0)
|
||||
offset = 0.0
|
||||
case .iPhone5:
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 95.0
|
||||
horizontalThird = 190.0
|
||||
verticalSecond = 88.0
|
||||
verticalThird = 176.0
|
||||
verticalFourth = 264.0
|
||||
size = CGSize(width: 265.0, height: 339.0)
|
||||
offset = 0.0
|
||||
case .iPhone6:
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 103.0
|
||||
horizontalThird = 206.0
|
||||
verticalSecond = 90.0
|
||||
verticalThird = 180.0
|
||||
verticalFourth = 270.0
|
||||
size = CGSize(width: 281.0, height: 345.0)
|
||||
offset = 0.0
|
||||
case .iPhone6Plus:
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 103.0
|
||||
horizontalThird = 206.0
|
||||
verticalSecond = 90.0
|
||||
verticalThird = 180.0
|
||||
verticalFourth = 270.0
|
||||
size = CGSize(width: 281.0, height: 345.0)
|
||||
offset = 0.0
|
||||
case .iPhoneX:
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 103.0
|
||||
horizontalThird = 206.0
|
||||
verticalSecond = 91.0
|
||||
verticalThird = 182.0
|
||||
verticalFourth = 273.0
|
||||
size = CGSize(width: 281.0, height: 345.0)
|
||||
offset = 294.0
|
||||
case .iPhoneXSMax:
|
||||
buttonSize = 85.0
|
||||
horizontalSecond = 115.0
|
||||
horizontalThird = 230.0
|
||||
verticalSecond = 100.0
|
||||
verticalThird = 200.0
|
||||
verticalFourth = 300.0
|
||||
size = CGSize(width: 315.0, height: 385.0)
|
||||
offset = 240.0
|
||||
case .iPad, .iPadPro10Inch, .iPadPro11Inch, .iPadPro, .iPadPro3rdGen:
|
||||
buttonSize = 81.0
|
||||
horizontalSecond = 106.0
|
||||
horizontalThird = 212.0
|
||||
verticalSecond = 101.0
|
||||
verticalThird = 202.0
|
||||
verticalFourth = 303.0
|
||||
size = CGSize(width: 293.0, height: 384.0)
|
||||
offset = 0.0
|
||||
}
|
||||
} else {
|
||||
buttonSize = 75.0
|
||||
horizontalSecond = 95.0
|
||||
horizontalThird = 190.0
|
||||
verticalSecond = 88.0
|
||||
verticalThird = 176.0
|
||||
verticalFourth = 264.0
|
||||
size = CGSize(width: 265.0, height: 339.0)
|
||||
offset = 0.0
|
||||
}
|
||||
|
||||
let origin = CGPoint(x: floor((layout.size.width - size.width) / 2.0), y: offset)
|
||||
|
||||
if let subnodes = self.subnodes {
|
||||
for i in 0 ..< subnodes.count {
|
||||
var origin = origin
|
||||
|
||||
@ -209,11 +209,6 @@ private func passcodeOptionsControllerEntries(presentationData: PresentationData
|
||||
entries.append(.touchId(presentationData.theme, presentationData.strings.PasscodeSettings_UnlockWithFaceId, passcodeOptionsData.presentationSettings.enableBiometrics))
|
||||
}
|
||||
}
|
||||
var simplePasscode = false
|
||||
if case .numericalPassword = passcodeOptionsData.accessChallenge {
|
||||
simplePasscode = true
|
||||
}
|
||||
entries.append(.simplePasscode(presentationData.theme, presentationData.strings.PasscodeSettings_SimplePasscode, simplePasscode))
|
||||
}
|
||||
|
||||
return entries
|
||||
|
||||
@ -54,8 +54,6 @@ enum PresentationResourceKey: Int32 {
|
||||
|
||||
case itemListCloseIconImage
|
||||
|
||||
case chatListLockTopLockedImage
|
||||
case chatListLockBottomLockedImage
|
||||
case chatListLockTopUnlockedImage
|
||||
case chatListLockBottomUnlockedImage
|
||||
case chatListPending
|
||||
|
||||
@ -99,30 +99,6 @@ struct PresentationResourcesChatList {
|
||||
})
|
||||
}
|
||||
|
||||
static func lockTopLockedImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatListLockTopLockedImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 7.0, height: 6.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(theme.rootController.navigationBar.accentTextColor.cgColor)
|
||||
context.setStrokeColor(theme.rootController.navigationBar.accentTextColor.cgColor)
|
||||
context.setLineWidth(1.5)
|
||||
context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.75, y: 0.75, width: 5.5, height: 12.0), cornerRadius: 2.5).cgPath)
|
||||
context.strokePath()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
static func lockBottomLockedImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatListLockBottomLockedImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 10.0, height: 7.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(theme.rootController.navigationBar.accentTextColor.cgColor)
|
||||
context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: 10.0, height: 7.0), cornerRadius: 1.33).cgPath)
|
||||
context.fillPath()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
static func lockTopUnlockedImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatListLockTopUnlockedImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 7.0, height: 6.0), rotatedContext: { size, context in
|
||||
@ -141,17 +117,15 @@ struct PresentationResourcesChatList {
|
||||
|
||||
static func lockBottomUnlockedImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatListLockBottomUnlockedImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 10.0, height: 7.0), rotatedContext: { size, context in
|
||||
return generateImage(CGSize(width: 10.0, height: 8.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(theme.rootController.navigationBar.primaryTextColor.cgColor)
|
||||
context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: 10.0, height: 7.0), cornerRadius: 1.33).cgPath)
|
||||
context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: 10.0, height: 8.0), cornerRadius: 1.5).cgPath)
|
||||
context.fillPath()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
static func recentStatusOnlineIcon(_ theme: PresentationTheme, state: RecentStatusOnlineIconState) -> UIImage? {
|
||||
let key: PresentationResourceKey
|
||||
switch state {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user