mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various UI fixes
This commit is contained in:
parent
c1030b193d
commit
845f8fa8ee
@ -6,7 +6,7 @@ public protocol KeyShortcutResponder {
|
||||
|
||||
public class KeyShortcutsController: UIResponder {
|
||||
private var effectiveShortcuts: [KeyShortcut]?
|
||||
private var viewControllerEnumerator: ((ContainableController) -> Bool) -> Void
|
||||
private var viewControllerEnumerator: (@escaping (ContainableController) -> Bool) -> Void
|
||||
|
||||
public static var isAvailable: Bool {
|
||||
if #available(iOSApplicationExtension 8.0, iOS 8.0, *), UIDevice.current.userInterfaceIdiom == .pad {
|
||||
@ -16,7 +16,7 @@ public class KeyShortcutsController: UIResponder {
|
||||
}
|
||||
}
|
||||
|
||||
public init(enumerator: @escaping ((ContainableController) -> Bool) -> Void) {
|
||||
public init(enumerator: @escaping (@escaping (ContainableController) -> Bool) -> Void) {
|
||||
self.viewControllerEnumerator = enumerator
|
||||
super.init()
|
||||
}
|
||||
|
@ -1168,11 +1168,15 @@ public class Window1 {
|
||||
}
|
||||
|
||||
public func forEachViewController(_ f: (ContainableController) -> Bool) {
|
||||
if let navigationController = self._rootController as? NavigationController, let controller = navigationController.topOverlayController {
|
||||
!f(controller)
|
||||
}
|
||||
for (controller, _) in self.presentationContext.controllers {
|
||||
if !f(controller) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for controller in self.topLevelOverlayControllers {
|
||||
if !f(controller) {
|
||||
break
|
||||
|
@ -110,14 +110,11 @@ private func allOpenInOptions(context: AccountContext, item: OpenInItem) -> [Ope
|
||||
}
|
||||
return .none
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "yandex", application: .other(title: "Yandex", identifier: 483693909, scheme: "yandexbrowser-open-url", store: nil), action: {
|
||||
if let escapedUrl = url.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) {
|
||||
return .openUrl(url: "yandexbrowser-open-url://\(escapedUrl)")
|
||||
}
|
||||
return .none
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "duckDuckGo", application: .other(title: "DuckDuckGo", identifier: 663592361, scheme: "ddgQuickLink", store: nil), action: {
|
||||
return .openUrl(url: "ddgQuickLink://\(url)")
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "edge", application: .other(title: "Microsoft Edge", identifier: 1288723196, scheme: "microsoft-edge-http", store: nil), action: {
|
||||
if let url = URL(string: url), var components = URLComponents(url: url, resolvingAgainstBaseURL: true) {
|
||||
components.scheme = components.scheme == "https" ? "microsoft-edge-https" : "microsoft-edge-http"
|
||||
@ -127,9 +124,12 @@ private func allOpenInOptions(context: AccountContext, item: OpenInItem) -> [Ope
|
||||
}
|
||||
return .none
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "duckDuckGo", application: .other(title: "DuckDuckGo", identifier: 663592361, scheme: "ddgQuickLink", store: nil), action: {
|
||||
return .openUrl(url: "ddgQuickLink://\(url)")
|
||||
|
||||
options.append(OpenInOption(identifier: "yandex", application: .other(title: "Yandex Browser", identifier: 483693909, scheme: "yandexbrowser-open-url", store: nil), action: {
|
||||
if let escapedUrl = url.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) {
|
||||
return .openUrl(url: "yandexbrowser-open-url://\(escapedUrl)")
|
||||
}
|
||||
return .none
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "brave", application: .other(title: "Brave", identifier: 1052879175, scheme: "brave", store: nil), action: {
|
||||
@ -139,28 +139,27 @@ private func allOpenInOptions(context: AccountContext, item: OpenInItem) -> [Ope
|
||||
return .none
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "alook", application: .other(title: "Alook Browser", identifier: 1261944766, scheme: "alook", store: nil), action: {
|
||||
return .openUrl(url: "alook://\(url)")
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "dolphin", application: .other(title: "Dolphin", identifier: 452204407, scheme: "dolphin", store: nil), action: {
|
||||
options.append(OpenInOption(identifier: "dolphin", application: .other(title: "Dolphin", identifier: 1440710469, scheme: "dolphin", store: "us"), action: {
|
||||
return .openUrl(url: "dolphin://\(url)")
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "onion", application: .other(title: "Onion Browser", identifier: 519296448, scheme: "onionhttp", store: nil), action: {
|
||||
if let url = URL(string: url), var components = URLComponents(url: url, resolvingAgainstBaseURL: true) {
|
||||
components.scheme = components.scheme == "https" ? "onionhttps" : "onionhttp"
|
||||
if let url = components.string {
|
||||
return .openUrl(url: url)
|
||||
}
|
||||
if let url = URL(string: url), var components = URLComponents(url: url, resolvingAgainstBaseURL: true) {
|
||||
components.scheme = components.scheme == "https" ? "onionhttps" : "onionhttp"
|
||||
if let url = components.string {
|
||||
return .openUrl(url: url)
|
||||
}
|
||||
return .none
|
||||
}))
|
||||
}
|
||||
return .none
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "ucbrowser", application: .other(title: "UC Browser", identifier: 1048518592, scheme: "ucbrowser", store: nil), action: {
|
||||
return .openUrl(url: "ucbrowser://\(url)")
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(identifier: "alook", application: .other(title: "Alook Browser", identifier: 1261944766, scheme: "alook", store: nil), action: {
|
||||
return .openUrl(url: "alook://\(url)")
|
||||
}))
|
||||
case let .location(location, withDirections):
|
||||
let lat = location.latitude
|
||||
let lon = location.longitude
|
||||
|
@ -2991,9 +2991,8 @@ public func openInAppIcon(postbox: Postbox, appIcon: OpenInAppIcon) -> Signal<(T
|
||||
}
|
||||
|
||||
if let sourceImage = sourceImage, let cgImage = sourceImage.cgImage {
|
||||
let imageSize = sourceImage.size.aspectFilled(arguments.drawingRect.size)
|
||||
context.withFlippedContext { c in
|
||||
c.draw(cgImage, in: CGRect(origin: CGPoint(x: floor((arguments.drawingRect.size.width - imageSize.width) / 2.0), y: floor((arguments.drawingRect.size.height - imageSize.height) / 2.0)), size: imageSize))
|
||||
c.draw(cgImage, in: CGRect(origin: CGPoint(), size: arguments.drawingRect.size))
|
||||
drawOpenInAppIconBorder(into: c, arguments: arguments)
|
||||
}
|
||||
} else {
|
||||
|
@ -21,6 +21,7 @@ import PasscodeUI
|
||||
import ImageBlur
|
||||
import WatchBridge
|
||||
import SettingsUI
|
||||
import AppLock
|
||||
|
||||
final class UnauthorizedApplicationContext {
|
||||
let sharedContext: SharedAccountContextImpl
|
||||
@ -74,7 +75,6 @@ final class AuthorizedApplicationContext {
|
||||
|
||||
private var inAppNotificationSettings: InAppNotificationSettings?
|
||||
|
||||
private var isLocked: Bool = true
|
||||
var passcodeController: PasscodeEntryController?
|
||||
|
||||
private var currentAppUpdateInfo: AppUpdateInfo?
|
||||
@ -128,194 +128,31 @@ final class AuthorizedApplicationContext {
|
||||
|
||||
if KeyShortcutsController.isAvailable {
|
||||
let keyShortcutsController = KeyShortcutsController { [weak self] f in
|
||||
if let strongSelf = self {
|
||||
if strongSelf.isLocked {
|
||||
return
|
||||
}
|
||||
if let tabController = strongSelf.rootController.rootTabController {
|
||||
let controller = tabController.controllers[tabController.selectedIndex]
|
||||
if !f(controller) {
|
||||
if let strongSelf = self, let appLockContext = strongSelf.context.sharedContext.appLockContext as? AppLockContextImpl {
|
||||
let _ = (appLockContext.isCurrentlyLocked
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { locked in
|
||||
guard !locked else {
|
||||
return
|
||||
}
|
||||
if let controller = strongSelf.rootController.topViewController as? ViewController {
|
||||
if !f(controller) {
|
||||
if let tabController = strongSelf.rootController.rootTabController {
|
||||
let selectedController = tabController.controllers[tabController.selectedIndex]
|
||||
if !f(selectedController) {
|
||||
return
|
||||
}
|
||||
if let controller = strongSelf.rootController.topViewController as? ViewController, controller !== selectedController {
|
||||
if !f(controller) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
strongSelf.mainWindow.forEachViewController(f)
|
||||
strongSelf.mainWindow.forEachViewController(f)
|
||||
})
|
||||
}
|
||||
}
|
||||
context.keyShortcutsController = keyShortcutsController
|
||||
}
|
||||
|
||||
/*let previousPasscodeState = Atomic<PasscodeState?>(value: nil)
|
||||
let passcodeStatusData = combineLatest(queue: Queue.mainQueue(), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationPasscodeSettings]), context.sharedContext.accountManager.accessChallengeData(), context.sharedContext.applicationBindings.applicationIsActive)
|
||||
let passcodeState = passcodeStatusData
|
||||
|> map { sharedData, accessChallengeDataView, isActive -> PasscodeState in
|
||||
let accessChallengeData = accessChallengeDataView.data
|
||||
let passcodeSettings = sharedData.entries[ApplicationSpecificSharedDataKeys.presentationPasscodeSettings] as? PresentationPasscodeSettings
|
||||
return PasscodeState(isActive: isActive, challengeData: accessChallengeData, autolockTimeout: passcodeSettings?.autolockTimeout, enableBiometrics: passcodeSettings?.enableBiometrics ?? false, biometricsDomainState: passcodeSettings?.biometricsDomainState)
|
||||
}
|
||||
self.passcodeStatusDisposable.set(passcodeState.start(next: { [weak self] updatedState in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let previousState = previousPasscodeState.swap(updatedState)
|
||||
|
||||
var updatedAutolockDeadline: Int32?
|
||||
if updatedState.isActive != previousState?.isActive, let autolockTimeout = updatedState.autolockTimeout {
|
||||
updatedAutolockDeadline = Int32(CFAbsoluteTimeGetCurrent()) + max(10, autolockTimeout)
|
||||
}
|
||||
|
||||
var effectiveAutolockDeadline = updatedState.challengeData.autolockDeadline
|
||||
if updatedState.isActive {
|
||||
} else if previousState != nil && previousState!.autolockTimeout != updatedState.autolockTimeout {
|
||||
effectiveAutolockDeadline = updatedAutolockDeadline
|
||||
}
|
||||
|
||||
if let previousState = previousState, previousState.isActive, !updatedState.isActive, effectiveAutolockDeadline != 0 {
|
||||
effectiveAutolockDeadline = updatedAutolockDeadline
|
||||
}
|
||||
|
||||
var isLocked = false
|
||||
if isAccessLocked(data: updatedState.challengeData.withUpdatedAutolockDeadline(effectiveAutolockDeadline), at: Int32(CFAbsoluteTimeGetCurrent())) {
|
||||
isLocked = true
|
||||
updatedAutolockDeadline = 0
|
||||
}
|
||||
|
||||
let isLockable: Bool
|
||||
switch updatedState.challengeData {
|
||||
case .none:
|
||||
isLockable = false
|
||||
default:
|
||||
isLockable = true
|
||||
}
|
||||
|
||||
if previousState?.isActive != updatedState.isActive || isLocked != strongSelf.isLocked {
|
||||
if updatedAutolockDeadline != previousState?.challengeData.autolockDeadline {
|
||||
let _ = (strongSelf.context.sharedContext.accountManager.transaction { transaction -> Void in
|
||||
let data = transaction.getAccessChallengeData().withUpdatedAutolockDeadline(updatedAutolockDeadline)
|
||||
transaction.setAccessChallengeData(data)
|
||||
}).start()
|
||||
}
|
||||
|
||||
strongSelf.isLocked = isLocked
|
||||
|
||||
if isLocked {
|
||||
if updatedState.isActive {
|
||||
if strongSelf.passcodeController == nil {
|
||||
let presentAnimated = previousState != nil && previousState!.isActive
|
||||
|
||||
let biometrics: PasscodeEntryControllerBiometricsMode
|
||||
if updatedState.enableBiometrics {
|
||||
biometrics = .enabled(updatedState.biometricsDomainState)
|
||||
} else {
|
||||
biometrics = .none
|
||||
}
|
||||
|
||||
let controller = PasscodeEntryController(context: strongSelf.context, challengeData: updatedState.challengeData, biometrics: biometrics, arguments: PasscodeEntryControllerPresentationArguments(animated: presentAnimated, lockIconInitialFrame: { [weak self] in
|
||||
if let strongSelf = self, let lockViewFrame = strongSelf.rootController.chatListController?.lockViewFrame {
|
||||
return lockViewFrame
|
||||
} else {
|
||||
return CGRect()
|
||||
}
|
||||
}))
|
||||
strongSelf.passcodeController = controller
|
||||
|
||||
strongSelf.unlockedStatePromise.set(.single(false))
|
||||
controller.presentationCompleted = {
|
||||
strongSelf.rootController.view.isHidden = true
|
||||
strongSelf.context.sharedContext.mediaManager.overlayMediaManager.controller?.view.isHidden = true
|
||||
strongSelf.notificationController.view.isHidden = true
|
||||
}
|
||||
strongSelf.mainWindow.present(controller, on: .passcode)
|
||||
|
||||
if !presentAnimated {
|
||||
controller.requestBiometrics()
|
||||
}
|
||||
} else if previousState?.isActive != updatedState.isActive, updatedState.isActive, let passcodeController = strongSelf.passcodeController {
|
||||
passcodeController.requestBiometrics()
|
||||
}
|
||||
strongSelf.updateCoveringViewSnaphot(false)
|
||||
strongSelf.mainWindow.coveringView = nil
|
||||
} else {
|
||||
strongSelf.unlockedStatePromise.set(.single(false))
|
||||
strongSelf.updateCoveringViewSnaphot(true)
|
||||
strongSelf.mainWindow.coveringView = strongSelf.passcodeController == nil ? strongSelf.lockedCoveringView : nil
|
||||
strongSelf.rootController.view.isHidden = true
|
||||
strongSelf.context.sharedContext.mediaManager.overlayMediaManager.controller?.view.isHidden = true
|
||||
strongSelf.notificationController.view.isHidden = true
|
||||
}
|
||||
} else {
|
||||
if !updatedState.isActive && isLockable {
|
||||
strongSelf.updateCoveringViewSnaphot(true)
|
||||
strongSelf.mainWindow.coveringView = strongSelf.passcodeController == nil ? strongSelf.lockedCoveringView : nil
|
||||
strongSelf.rootController.view.isHidden = true
|
||||
strongSelf.context.sharedContext.mediaManager.overlayMediaManager.controller?.view.isHidden = true
|
||||
strongSelf.notificationController.view.isHidden = true
|
||||
} else {
|
||||
strongSelf.updateCoveringViewSnaphot(false)
|
||||
strongSelf.mainWindow.coveringView = nil
|
||||
strongSelf.rootController.view.isHidden = false
|
||||
strongSelf.context.sharedContext.mediaManager.overlayMediaManager.controller?.view.isHidden = false
|
||||
strongSelf.notificationController.view.isHidden = false
|
||||
if strongSelf.rootController.rootTabController == nil {
|
||||
strongSelf.rootController.addRootControllers(showCallsTab: strongSelf.showCallsTab)
|
||||
if let (peerId, messageId, activateInput) = strongSelf.scheduledOperChatWithPeerId {
|
||||
strongSelf.scheduledOperChatWithPeerId = nil
|
||||
strongSelf.openChatWithPeerId(peerId: peerId, messageId: messageId, activateInput: activateInput)
|
||||
}
|
||||
|
||||
if let url = strongSelf.scheduledOpenExternalUrl {
|
||||
strongSelf.scheduledOpenExternalUrl = nil
|
||||
strongSelf.openUrl(url)
|
||||
}
|
||||
|
||||
if #available(iOS 10.0, *) {
|
||||
} else {
|
||||
DeviceAccess.authorizeAccess(to: .contacts, presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, present: { c, a in
|
||||
})
|
||||
}
|
||||
|
||||
if let passcodeController = strongSelf.passcodeController {
|
||||
if let chatListController = strongSelf.rootController.chatListController {
|
||||
let _ = chatListController.ready.get().start(next: { [weak passcodeController] _ in
|
||||
if let strongSelf = self, let passcodeController = passcodeController, strongSelf.passcodeController === passcodeController {
|
||||
strongSelf.passcodeController = nil
|
||||
strongSelf.rootController.chatListController?.displayNode.recursivelyEnsureDisplaySynchronously(true)
|
||||
passcodeController.dismiss()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
strongSelf.passcodeController = nil
|
||||
strongSelf.rootController.chatListController?.displayNode.recursivelyEnsureDisplaySynchronously(true)
|
||||
passcodeController.dismiss()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let passcodeController = strongSelf.passcodeController {
|
||||
strongSelf.passcodeController = nil
|
||||
passcodeController.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.unlockedStatePromise.set(.single(true))
|
||||
}
|
||||
}
|
||||
if let tabsController = strongSelf.rootController.viewControllers.first as? TabBarController, !tabsController.controllers.isEmpty, tabsController.selectedIndex >= 0 {
|
||||
let controller = tabsController.controllers[tabsController.selectedIndex]
|
||||
let combinedReady = combineLatest(tabsController.ready.get(), controller.ready.get())
|
||||
|> map { $0 && $1 }
|
||||
|> filter { $0 }
|
||||
|> take(1)
|
||||
strongSelf.isReady.set(combinedReady)
|
||||
} else {
|
||||
strongSelf.isReady.set(.single(true))
|
||||
}
|
||||
}))*/
|
||||
|
||||
if self.rootController.rootTabController == nil {
|
||||
self.rootController.addRootControllers(showCallsTab: self.showCallsTab)
|
||||
}
|
||||
@ -392,25 +229,32 @@ final class AuthorizedApplicationContext {
|
||||
inAppNotificationSettings = InAppNotificationSettings.defaultSettings
|
||||
}
|
||||
|
||||
if !strongSelf.isLocked {
|
||||
let isMuted = firstMessage.attributes.contains(where: { attribute in
|
||||
if let attribute = attribute as? NotificationInfoMessageAttribute {
|
||||
return attribute.flags.contains(.muted)
|
||||
} else {
|
||||
return false
|
||||
if let appLockContext = strongSelf.context.sharedContext.appLockContext as? AppLockContextImpl {
|
||||
let _ = (appLockContext.isCurrentlyLocked
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { locked in
|
||||
guard !locked else {
|
||||
return
|
||||
}
|
||||
let isMuted = firstMessage.attributes.contains(where: { attribute in
|
||||
if let attribute = attribute as? NotificationInfoMessageAttribute {
|
||||
return attribute.flags.contains(.muted)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
if !isMuted {
|
||||
if firstMessage.id.peerId == context.account.peerId, !firstMessage.flags.contains(.WasScheduled) {
|
||||
} else {
|
||||
if inAppNotificationSettings.playSounds {
|
||||
serviceSoundManager.playIncomingMessageSound()
|
||||
}
|
||||
if inAppNotificationSettings.vibrate {
|
||||
serviceSoundManager.playVibrationSound()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if !isMuted {
|
||||
if firstMessage.id.peerId == context.account.peerId, !firstMessage.flags.contains(.WasScheduled) {
|
||||
} else {
|
||||
if inAppNotificationSettings.playSounds {
|
||||
serviceSoundManager.playIncomingMessageSound()
|
||||
}
|
||||
if inAppNotificationSettings.vibrate {
|
||||
serviceSoundManager.playVibrationSound()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if chatIsVisible {
|
||||
|
@ -8072,7 +8072,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
guard case let .peer(peerId) = self.chatLocation, peerId.namespace == Namespaces.Peer.CloudUser && peerId != self.context.account.peerId else {
|
||||
return
|
||||
}
|
||||
if #available(iOSApplicationExtension 11.0, iOS 11.0, *) {
|
||||
if #available(iOSApplicationExtension 13.2, iOS 13.2, *) {
|
||||
let _ = (self.context.account.postbox.loadedPeerWithId(peerId)
|
||||
|> mapToSignal { peer -> Signal<(Peer, UIImage?), NoError> in
|
||||
let avatarImage = peerAvatarImage(account: self.context.account, peer: peer, authorOfMessage: nil, representation: peer.smallProfileImage, round: false) ?? .single(nil)
|
||||
|
Loading…
x
Reference in New Issue
Block a user