mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-30 03:44:18 +00:00
Bugfixes
This commit is contained in:
parent
5da7197c55
commit
bb9b706c94
24
Makefile
24
Makefile
@ -168,6 +168,28 @@ package_arm64:
|
|||||||
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
||||||
sh package_app.sh iphoneos-arm64 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
sh package_app.sh iphoneos-arm64 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
||||||
|
|
||||||
|
package_debug_arm64:
|
||||||
|
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
||||||
|
PACKAGE_CODE_SIGN_IDENTITY="${DEVELOPMENT_CODE_SIGN_IDENTITY}" \
|
||||||
|
PACKAGE_PROVISIONING_PROFILE_APP="${DEVELOPMENT_PROVISIONING_PROFILE_APP}" \
|
||||||
|
PACKAGE_ENTITLEMENTS_APP="${ENTITLEMENTS_APP}" \
|
||||||
|
PACKAGE_PROVISIONING_PROFILE_EXTENSION_Share="${DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_SHARE}" \
|
||||||
|
PACKAGE_ENTITLEMENTS_EXTENSION_Share="${ENTITLEMENTS_EXTENSION_SHARE}" \
|
||||||
|
PACKAGE_PROVISIONING_PROFILE_EXTENSION_Widget="${DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_WIDGET}" \
|
||||||
|
PACKAGE_ENTITLEMENTS_EXTENSION_Widget="${ENTITLEMENTS_EXTENSION_WIDGET}" \
|
||||||
|
PACKAGE_PROVISIONING_PROFILE_EXTENSION_NotificationService="${DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_NOTIFICATIONSERVICE}" \
|
||||||
|
PACKAGE_ENTITLEMENTS_EXTENSION_NotificationService="${ENTITLEMENTS_EXTENSION_NOTIFICATIONSERVICE}" \
|
||||||
|
PACKAGE_PROVISIONING_PROFILE_EXTENSION_NotificationContent="${DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_NOTIFICATIONCONTENT}" \
|
||||||
|
PACKAGE_ENTITLEMENTS_EXTENSION_NotificationContent="${ENTITLEMENTS_EXTENSION_NOTIFICATIONCONTENT}" \
|
||||||
|
PACKAGE_PROVISIONING_PROFILE_EXTENSION_Intents="${DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_INTENTS}" \
|
||||||
|
PACKAGE_ENTITLEMENTS_EXTENSION_Intents="${ENTITLEMENTS_EXTENSION_INTENTS}" \
|
||||||
|
PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DEVELOPMENT_PROVISIONING_PROFILE_WATCH_APP}" \
|
||||||
|
PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \
|
||||||
|
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
||||||
|
ENABLE_GET_TASK_ALLOW=1 \
|
||||||
|
CODESIGNING_PROFILES_VARIANT="development" \
|
||||||
|
sh package_app.sh iphoneos-arm64 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
||||||
|
|
||||||
package:
|
package:
|
||||||
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
||||||
PACKAGE_CODE_SIGN_IDENTITY="${DISTRIBUTION_CODE_SIGN_IDENTITY}" \
|
PACKAGE_CODE_SIGN_IDENTITY="${DISTRIBUTION_CODE_SIGN_IDENTITY}" \
|
||||||
@ -192,7 +214,7 @@ app: build package
|
|||||||
|
|
||||||
app_arm64: build_arm64 package_arm64
|
app_arm64: build_arm64 package_arm64
|
||||||
|
|
||||||
app_debug_arm64: build_debug_arm64 package_arm64
|
app_debug_arm64: build_debug_arm64 package_debug_arm64
|
||||||
|
|
||||||
build_buckdebug: check_env
|
build_buckdebug: check_env
|
||||||
BUCK_DEBUG_MODE=1 $(BUCK) build \
|
BUCK_DEBUG_MODE=1 $(BUCK) build \
|
||||||
|
|||||||
@ -301,6 +301,11 @@
|
|||||||
<string>remote-notification</string>
|
<string>remote-notification</string>
|
||||||
<string>voip</string>
|
<string>voip</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>UIDeviceFamily</key>
|
||||||
|
<array>
|
||||||
|
<integer>1</integer>
|
||||||
|
<integer>2</integer>
|
||||||
|
</array>
|
||||||
<key>UIFileSharingEnabled</key>
|
<key>UIFileSharingEnabled</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
@ -356,10 +361,5 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>UIDeviceFamily</key>
|
|
||||||
<array>
|
|
||||||
<integer>1</integer>
|
|
||||||
<integer>2</integer>
|
|
||||||
</array>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@ -44,6 +44,8 @@
|
|||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@ -65,6 +67,8 @@
|
|||||||
ReferencedContainer = "container:Project.xcodeproj">
|
ReferencedContainer = "container:Project.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@ -44,6 +44,8 @@
|
|||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@ -65,6 +67,8 @@
|
|||||||
ReferencedContainer = "container:Project.xcodeproj">
|
ReferencedContainer = "container:Project.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@ -44,6 +44,8 @@
|
|||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@ -65,6 +67,8 @@
|
|||||||
ReferencedContainer = "container:Project.xcodeproj">
|
ReferencedContainer = "container:Project.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@ -44,6 +44,8 @@
|
|||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@ -65,6 +67,8 @@
|
|||||||
ReferencedContainer = "container:Project.xcodeproj">
|
ReferencedContainer = "container:Project.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@ -44,6 +44,8 @@
|
|||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@ -65,6 +67,8 @@
|
|||||||
ReferencedContainer = "container:Project.xcodeproj">
|
ReferencedContainer = "container:Project.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@ -2563,6 +2563,8 @@
|
|||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@ -2572,6 +2574,8 @@
|
|||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
|
stopOnEveryThreadSanitizerIssue = "YES"
|
||||||
|
stopOnEveryMainThreadCheckerIssue = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
<BuildableProductRunnable
|
<BuildableProductRunnable
|
||||||
@ -2584,6 +2588,8 @@
|
|||||||
ReferencedContainer = "container:Project.xcodeproj">
|
ReferencedContainer = "container:Project.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@ -184,6 +184,12 @@ for ITEM in $APP_ITEMS_WITH_PROVISIONING_PROFILE; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ "$ENABLE_GET_TASK_ALLOW" == "1" ]; then
|
||||||
|
KEY="com.apple.security.get-task-allow"
|
||||||
|
PLUTIL_KEY=$(echo "$KEY" | sed 's/\./\\\./g')
|
||||||
|
plutil -insert "$PLUTIL_KEY" -xml "<false/>" "$PROFILE_ENTITLEMENTS_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
ENTITLEMENTS_VAR=PACKAGE_ENTITLEMENTS_$ITEM
|
ENTITLEMENTS_VAR=PACKAGE_ENTITLEMENTS_$ITEM
|
||||||
if [ ! -z "${!ENTITLEMENTS_VAR}" ]; then
|
if [ ! -z "${!ENTITLEMENTS_VAR}" ]; then
|
||||||
if [ ! -f "${!ENTITLEMENTS_VAR}" ]; then
|
if [ ! -f "${!ENTITLEMENTS_VAR}" ]; then
|
||||||
|
|||||||
@ -24,6 +24,6 @@
|
|||||||
|
|
||||||
+ (void)getHardwareEncryptionAvailableWithBaseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^)(NSData * _Nullable))completion;
|
+ (void)getHardwareEncryptionAvailableWithBaseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^)(NSData * _Nullable))completion;
|
||||||
+ (void)encryptApplicationSecret:(NSData * _Nonnull)secret baseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^)(NSData * _Nullable, NSData * _Nullable))completion;
|
+ (void)encryptApplicationSecret:(NSData * _Nonnull)secret baseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^)(NSData * _Nullable, NSData * _Nullable))completion;
|
||||||
+ (void)decryptApplicationSecret:(NSData * _Nonnull)secret publicKey:(NSData * _Nonnull)publicKey baseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^)(NSData * _Nullable))completion;
|
+ (void)decryptApplicationSecret:(NSData * _Nonnull)secret publicKey:(NSData * _Nonnull)publicKey baseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^)(NSData * _Nullable, bool))completion;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@ -694,28 +694,29 @@ API_AVAILABLE(ios(10))
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)decryptApplicationSecret:(NSData * _Nonnull)secret publicKey:(NSData * _Nonnull)publicKey baseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^)(NSData * _Nullable))completion {
|
+ (void)decryptApplicationSecret:(NSData * _Nonnull)secret publicKey:(NSData * _Nonnull)publicKey baseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^)(NSData * _Nullable, bool))completion {
|
||||||
dispatch_async([self encryptionQueue], ^{
|
dispatch_async([self encryptionQueue], ^{
|
||||||
LocalPrivateKey *privateKey = [self getApplicationSecretKey:baseAppBundleId isCheckKey:false];
|
LocalPrivateKey *privateKey = [self getApplicationSecretKey:baseAppBundleId isCheckKey:false];
|
||||||
if (privateKey == nil) {
|
if (privateKey == nil) {
|
||||||
completion(nil);
|
completion(nil, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (privateKey == nil) {
|
if (privateKey == nil) {
|
||||||
completion(nil);
|
completion(nil, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSData *currentPublicKey = [privateKey getPublicKey];
|
NSData *currentPublicKey = [privateKey getPublicKey];
|
||||||
if (currentPublicKey == nil) {
|
if (currentPublicKey == nil) {
|
||||||
completion(nil);
|
completion(nil, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (![publicKey isEqualToData:currentPublicKey]) {
|
if (![publicKey isEqualToData:currentPublicKey]) {
|
||||||
completion(nil);
|
completion(nil, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSData *result = [privateKey decrypt:secret cancelled:nil];
|
bool cancelled = false;
|
||||||
completion(result);
|
NSData *result = [privateKey decrypt:secret cancelled:&cancelled];
|
||||||
|
completion(result, cancelled);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,8 @@ public final class ContextGesture: UIGestureRecognizer, UIGestureRecognizerDeleg
|
|||||||
override public func reset() {
|
override public func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
|
self.endPressedAppearance()
|
||||||
|
|
||||||
self.currentProgress = 0.0
|
self.currentProgress = 0.0
|
||||||
self.delayTimer?.invalidate()
|
self.delayTimer?.invalidate()
|
||||||
self.delayTimer = nil
|
self.delayTimer = nil
|
||||||
@ -152,9 +154,8 @@ public final class ContextGesture: UIGestureRecognizer, UIGestureRecognizerDeleg
|
|||||||
|
|
||||||
if let touch = touches.first {
|
if let touch = touches.first {
|
||||||
if !self.currentProgress.isZero, self.isValidated {
|
if !self.currentProgress.isZero, self.isValidated {
|
||||||
if #available(iOS 9.0, *) {
|
self.currentProgress = 0.0
|
||||||
self.activationProgress?(0.0, .ended(self.currentProgress))
|
self.activationProgress?(0.0, .ended(self.currentProgress))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.externalEnded?((self.view, touch.location(in: self.view)))
|
self.externalEnded?((self.view, touch.location(in: self.view)))
|
||||||
@ -170,9 +171,8 @@ public final class ContextGesture: UIGestureRecognizer, UIGestureRecognizerDeleg
|
|||||||
super.touchesCancelled(touches, with: event)
|
super.touchesCancelled(touches, with: event)
|
||||||
|
|
||||||
if let touch = touches.first, !self.currentProgress.isZero, self.isValidated {
|
if let touch = touches.first, !self.currentProgress.isZero, self.isValidated {
|
||||||
if #available(iOS 9.0, *) {
|
self.currentProgress = 0.0
|
||||||
self.activationProgress?(0.0, .ended(self.currentProgress))
|
self.activationProgress?(0.0, .ended(self.currentProgress))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.delayTimer?.invalidate()
|
self.delayTimer?.invalidate()
|
||||||
@ -183,6 +183,7 @@ public final class ContextGesture: UIGestureRecognizer, UIGestureRecognizerDeleg
|
|||||||
|
|
||||||
public func cancel() {
|
public func cancel() {
|
||||||
if !self.currentProgress.isZero, self.isValidated {
|
if !self.currentProgress.isZero, self.isValidated {
|
||||||
|
self.currentProgress = 0.0
|
||||||
self.activationProgress?(0.0, .ended(self.currentProgress))
|
self.activationProgress?(0.0, .ended(self.currentProgress))
|
||||||
|
|
||||||
self.delayTimer?.invalidate()
|
self.delayTimer?.invalidate()
|
||||||
|
|||||||
@ -95,10 +95,8 @@ final class GlobalOverlayPresentationContext {
|
|||||||
}
|
}
|
||||||
return keyboardWindow
|
return keyboardWindow
|
||||||
} else {
|
} else {
|
||||||
if underStatusBar, let view = self.parentView {
|
if let view = self.parentView {
|
||||||
return view
|
return view
|
||||||
} else {
|
|
||||||
return statusBarHost.statusBarWindow
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3313,6 +3313,10 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
|||||||
indicatorFrame.origin.y = self.visibleSize.height - (self.scrollIndicatorInsets.bottom + indicatorBottomInset) - indicatorFrame.height
|
indicatorFrame.origin.y = self.visibleSize.height - (self.scrollIndicatorInsets.bottom + indicatorBottomInset) - indicatorFrame.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if indicatorFrame.origin.y.isNaN {
|
||||||
|
indicatorFrame.origin.y = indicatorTopInset
|
||||||
|
}
|
||||||
|
|
||||||
if indicatorHeight >= visibleHeightWithoutIndicatorInsets {
|
if indicatorHeight >= visibleHeightWithoutIndicatorInsets {
|
||||||
verticalScrollIndicator.isHidden = true
|
verticalScrollIndicator.isHidden = true
|
||||||
verticalScrollIndicator.frame = indicatorFrame
|
verticalScrollIndicator.frame = indicatorFrame
|
||||||
|
|||||||
@ -76,13 +76,22 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
private(set) var controllers: [ViewController] = []
|
private(set) var controllers: [ViewController] = []
|
||||||
private var state: State = State(layout: nil, canBeClosed: nil, top: nil, transition: nil, pending: nil)
|
private var state: State = State(layout: nil, canBeClosed: nil, top: nil, transition: nil, pending: nil)
|
||||||
|
|
||||||
|
private var ignoreInputHeight: Bool = false
|
||||||
|
|
||||||
private(set) var isReady: Bool = false
|
private(set) var isReady: Bool = false
|
||||||
var isReadyUpdated: (() -> Void)?
|
var isReadyUpdated: (() -> Void)?
|
||||||
var controllerRemoved: (ViewController) -> Void
|
var controllerRemoved: (ViewController) -> Void
|
||||||
var keyboardViewManager: KeyboardViewManager? {
|
var keyboardViewManager: KeyboardViewManager? {
|
||||||
didSet {
|
didSet {
|
||||||
if self.keyboardViewManager !== oldValue {
|
}
|
||||||
|
}
|
||||||
|
var canHaveKeyboardFocus: Bool = false {
|
||||||
|
didSet {
|
||||||
|
if self.canHaveKeyboardFocus != oldValue {
|
||||||
|
if !self.canHaveKeyboardFocus {
|
||||||
|
self.view.endEditing(true)
|
||||||
|
self.performUpdate(transition: .animated(duration: 0.5, curve: .spring))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,6 +156,7 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
guard self.state.transition == nil else {
|
guard self.state.transition == nil else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let beginGesture = self.controllers.count > 1
|
let beginGesture = self.controllers.count > 1
|
||||||
|
|
||||||
if beginGesture {
|
if beginGesture {
|
||||||
@ -163,7 +173,7 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
topController.viewWillDisappear(true)
|
topController.viewWillDisappear(true)
|
||||||
let topNode = topController.displayNode
|
let topNode = topController.displayNode
|
||||||
bottomController.containerLayoutUpdated(layout, transition: .immediate)
|
bottomController.containerLayoutUpdated(layout.withUpdatedInputHeight(nil), transition: .immediate)
|
||||||
bottomController.viewWillAppear(true)
|
bottomController.viewWillAppear(true)
|
||||||
let bottomNode = bottomController.displayNode
|
let bottomNode = bottomController.displayNode
|
||||||
|
|
||||||
@ -195,11 +205,16 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
let topController = top.value
|
let topController = top.value
|
||||||
let bottomController = transition.previous.value
|
let bottomController = transition.previous.value
|
||||||
|
|
||||||
|
if viewTreeContainsFirstResponder(view: top.value.view) {
|
||||||
|
strongSelf.ignoreInputHeight = true
|
||||||
|
}
|
||||||
strongSelf.keyboardViewManager?.dismissEditingWithoutAnimation(view: topController.view)
|
strongSelf.keyboardViewManager?.dismissEditingWithoutAnimation(view: topController.view)
|
||||||
|
|
||||||
strongSelf.state.transition = nil
|
strongSelf.state.transition = nil
|
||||||
|
|
||||||
strongSelf.controllerRemoved(top.value)
|
strongSelf.controllerRemoved(top.value)
|
||||||
|
strongSelf.ignoreInputHeight = false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
navigationTransitionCoordinator.animateCancel({ [weak self] in
|
navigationTransitionCoordinator.animateCancel({ [weak self] in
|
||||||
@ -383,12 +398,16 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func makeChild(layout: ContainerViewLayout, value: ViewController) -> Child {
|
private func makeChild(layout: ContainerViewLayout, value: ViewController) -> Child {
|
||||||
value.containerLayoutUpdated(layout, transition: .immediate)
|
let updatedLayout = layout.withUpdatedInputHeight(nil)
|
||||||
return Child(value: value, layout: layout)
|
value.containerLayoutUpdated(updatedLayout, transition: .immediate)
|
||||||
|
return Child(value: value, layout: updatedLayout)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func applyLayout(layout: ContainerViewLayout, to child: Child, isMaster: Bool, transition: ContainedViewLayoutTransition) {
|
private func applyLayout(layout: ContainerViewLayout, to child: Child, isMaster: Bool, transition: ContainedViewLayoutTransition) {
|
||||||
var childFrame = CGRect(origin: CGPoint(), size: layout.size)
|
var childFrame = CGRect(origin: CGPoint(), size: layout.size)
|
||||||
|
|
||||||
|
var updatedLayout = layout
|
||||||
|
|
||||||
var shouldSyncKeyboard = false
|
var shouldSyncKeyboard = false
|
||||||
if let transition = self.state.transition {
|
if let transition = self.state.transition {
|
||||||
childFrame.origin.x = child.value.displayNode.frame.origin.x
|
childFrame.origin.x = child.value.displayNode.frame.origin.x
|
||||||
@ -400,10 +419,21 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
case .push:
|
case .push:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if updatedLayout.inputHeight != nil {
|
||||||
|
if !self.canHaveKeyboardFocus {
|
||||||
|
updatedLayout = updatedLayout.withUpdatedInputHeight(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if isMaster {
|
if isMaster {
|
||||||
shouldSyncKeyboard = true
|
shouldSyncKeyboard = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if updatedLayout.inputHeight != nil {
|
||||||
|
if !self.canHaveKeyboardFocus || self.ignoreInputHeight {
|
||||||
|
updatedLayout = updatedLayout.withUpdatedInputHeight(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if child.value.displayNode.frame != childFrame {
|
if child.value.displayNode.frame != childFrame {
|
||||||
transition.updateFrame(node: child.value.displayNode, frame: childFrame)
|
transition.updateFrame(node: child.value.displayNode, frame: childFrame)
|
||||||
@ -411,9 +441,9 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
if shouldSyncKeyboard && isMaster {
|
if shouldSyncKeyboard && isMaster {
|
||||||
self.syncKeyboard(leftEdge: childFrame.minX, transition: transition)
|
self.syncKeyboard(leftEdge: childFrame.minX, transition: transition)
|
||||||
}
|
}
|
||||||
if child.layout != layout {
|
if child.layout != updatedLayout {
|
||||||
child.layout = layout
|
child.layout = updatedLayout
|
||||||
child.value.containerLayoutUpdated(layout, transition: transition)
|
child.value.containerLayoutUpdated(updatedLayout, transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,13 +460,13 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
private func pendingChildIsReady(_ child: PendingChild) {
|
private func pendingChildIsReady(_ child: PendingChild) {
|
||||||
if let pending = self.state.pending, pending === child {
|
if let pending = self.state.pending, pending === child {
|
||||||
pending.isReady = true
|
pending.isReady = true
|
||||||
self.performUpdate()
|
self.performUpdate(transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func performUpdate() {
|
private func performUpdate(transition: ContainedViewLayoutTransition) {
|
||||||
if let layout = self.state.layout, let canBeClosed = self.state.canBeClosed {
|
if let layout = self.state.layout, let canBeClosed = self.state.canBeClosed {
|
||||||
self.update(layout: layout, canBeClosed: canBeClosed, controllers: self.controllers, transition: .immediate)
|
self.update(layout: layout, canBeClosed: canBeClosed, controllers: self.controllers, transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -118,12 +118,18 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
return self.view as! NavigationControllerView
|
return self.view as! NavigationControllerView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var inCallNavigate: (() -> Void)?
|
||||||
private var inCallStatusBar: StatusBar?
|
private var inCallStatusBar: StatusBar?
|
||||||
|
private var globalScrollToTopNode: ScrollToTopNode?
|
||||||
private var rootContainer: RootContainer?
|
private var rootContainer: RootContainer?
|
||||||
private var rootModalFrame: NavigationModalFrame?
|
private var rootModalFrame: NavigationModalFrame?
|
||||||
private var modalContainers: [NavigationModalContainer] = []
|
private var modalContainers: [NavigationModalContainer] = []
|
||||||
|
private var overlayContainers: [NavigationOverlayContainer] = []
|
||||||
private var validLayout: ContainerViewLayout?
|
private var validLayout: ContainerViewLayout?
|
||||||
private var validStatusBarStyle: NavigationStatusBarStyle?
|
private var validStatusBarStyle: NavigationStatusBarStyle?
|
||||||
|
private var validStatusBarHidden: Bool = false
|
||||||
|
|
||||||
|
private var currentStatusBarExternalHidden: Bool = false
|
||||||
|
|
||||||
private var scheduledLayoutTransitionRequestId: Int = 0
|
private var scheduledLayoutTransitionRequestId: Int = 0
|
||||||
private var scheduledLayoutTransitionRequest: (Int, ContainedViewLayoutTransition)?
|
private var scheduledLayoutTransitionRequest: (Int, ContainedViewLayoutTransition)?
|
||||||
@ -151,7 +157,10 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
return self._displayNode!
|
return self._displayNode!
|
||||||
}
|
}
|
||||||
|
|
||||||
var statusBarHost: StatusBarHost?
|
var statusBarHost: StatusBarHost? {
|
||||||
|
didSet {
|
||||||
|
}
|
||||||
|
}
|
||||||
var keyboardViewManager: KeyboardViewManager?
|
var keyboardViewManager: KeyboardViewManager?
|
||||||
|
|
||||||
public func updateMasterDetailsBlackout(_ blackout: MasterDetailLayoutBlackout?, transition: ContainedViewLayoutTransition) {
|
public func updateMasterDetailsBlackout(_ blackout: MasterDetailLayoutBlackout?, transition: ContainedViewLayoutTransition) {
|
||||||
@ -199,6 +208,9 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
for modalContainer in self.modalContainers {
|
for modalContainer in self.modalContainers {
|
||||||
supportedOrientations = supportedOrientations.intersection(modalContainer.container.combinedSupportedOrientations(currentOrientationToLock: currentOrientationToLock))
|
supportedOrientations = supportedOrientations.intersection(modalContainer.container.combinedSupportedOrientations(currentOrientationToLock: currentOrientationToLock))
|
||||||
}
|
}
|
||||||
|
for overlayContrainer in self.overlayContainers {
|
||||||
|
supportedOrientations = supportedOrientations.intersection(overlayContrainer.controller.combinedSupportedOrientations(currentOrientationToLock: currentOrientationToLock))
|
||||||
|
}
|
||||||
return supportedOrientations
|
return supportedOrientations
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,18 +226,10 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.isViewLoaded {
|
if self.isViewLoaded {
|
||||||
if statusBarStyleUpdated {
|
|
||||||
self.validStatusBarStyle = self.theme.statusBar
|
|
||||||
let normalStatusBarStyle: UIStatusBarStyle
|
|
||||||
switch self.theme.statusBar {
|
|
||||||
case .black:
|
|
||||||
normalStatusBarStyle = .default
|
|
||||||
case .white:
|
|
||||||
normalStatusBarStyle = .lightContent
|
|
||||||
}
|
|
||||||
//self.statusBarHost?.setStatusBarStyle(normalStatusBarStyle, animated: false)
|
|
||||||
}
|
|
||||||
self.controllerView.backgroundColor = theme.emptyAreaColor
|
self.controllerView.backgroundColor = theme.emptyAreaColor
|
||||||
|
if let layout = self.validLayout {
|
||||||
|
self.containerLayoutUpdated(layout, transition: .immediate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,16 +243,33 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
self.validLayout = layout
|
self.validLayout = layout
|
||||||
self.updateContainers(layout: layout, transition: transition)
|
self.updateContainers(layout: layout, transition: transition)
|
||||||
|
|
||||||
self.inCallStatusBar?.frame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: max(40.0, layout.safeInsets.top)))
|
|
||||||
self.inCallStatusBar?.updateState(statusBar: nil, withSafeInsets: false, inCallText: "In Call Text", animated: false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateContainers(layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
private weak var currentTopVisibleOverlayContainerStatusBar: NavigationOverlayContainer? = nil
|
||||||
|
|
||||||
|
private func updateContainers(layout rawLayout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||||
|
var layout = rawLayout
|
||||||
|
|
||||||
|
if let globalScrollToTopNode = self.globalScrollToTopNode {
|
||||||
|
globalScrollToTopNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -1.0), size: CGSize(width: layout.size.width, height: 1.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
if let inCallStatusBar = self.inCallStatusBar {
|
||||||
|
let inCallStatusBarFrame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: max(40.0, layout.safeInsets.top)))
|
||||||
|
if inCallStatusBar.frame.isEmpty {
|
||||||
|
inCallStatusBar.frame = inCallStatusBarFrame
|
||||||
|
} else {
|
||||||
|
transition.updateFrame(node: inCallStatusBar, frame: inCallStatusBarFrame)
|
||||||
|
}
|
||||||
|
layout.statusBarHeight = inCallStatusBarFrame.height
|
||||||
|
self.inCallStatusBar?.frame = inCallStatusBarFrame
|
||||||
|
}
|
||||||
|
|
||||||
let navigationLayout = makeNavigationLayout(mode: self.mode, layout: layout, controllers: self._viewControllers)
|
let navigationLayout = makeNavigationLayout(mode: self.mode, layout: layout, controllers: self._viewControllers)
|
||||||
|
|
||||||
var transition = transition
|
var transition = transition
|
||||||
var statusBarStyle: StatusBarStyle = .Ignore
|
var statusBarStyle: StatusBarStyle = .Ignore
|
||||||
|
var statusBarHidden = false
|
||||||
var animateStatusBarStyleTransition = transition.isAnimated
|
var animateStatusBarStyleTransition = transition.isAnimated
|
||||||
|
|
||||||
var modalContainers: [NavigationModalContainer] = []
|
var modalContainers: [NavigationModalContainer] = []
|
||||||
@ -311,6 +332,56 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
self.modalContainers = modalContainers
|
self.modalContainers = modalContainers
|
||||||
|
|
||||||
|
var previousOverlayContainer: NavigationOverlayContainer?
|
||||||
|
var topVisibleOverlayContainerWithStatusBar: NavigationOverlayContainer?
|
||||||
|
for i in (0 ..< self.overlayContainers.count).reversed() {
|
||||||
|
let overlayContainer = self.overlayContainers[i]
|
||||||
|
|
||||||
|
let containerTransition: ContainedViewLayoutTransition
|
||||||
|
if overlayContainer.supernode == nil {
|
||||||
|
containerTransition = .immediate
|
||||||
|
} else {
|
||||||
|
containerTransition = transition
|
||||||
|
}
|
||||||
|
|
||||||
|
containerTransition.updateFrame(node: overlayContainer, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||||
|
overlayContainer.update(layout: layout, transition: containerTransition)
|
||||||
|
|
||||||
|
if overlayContainer.supernode == nil && overlayContainer.isReady {
|
||||||
|
if let previousOverlayContainer = previousOverlayContainer {
|
||||||
|
self.displayNode.insertSubnode(overlayContainer, belowSubnode: previousOverlayContainer)
|
||||||
|
} else if let globalScrollToTopNode = self.globalScrollToTopNode {
|
||||||
|
self.displayNode.insertSubnode(overlayContainer, belowSubnode: globalScrollToTopNode)
|
||||||
|
} else {
|
||||||
|
self.displayNode.addSubnode(overlayContainer)
|
||||||
|
}
|
||||||
|
overlayContainer.transitionIn()
|
||||||
|
}
|
||||||
|
|
||||||
|
if overlayContainer.supernode != nil {
|
||||||
|
previousOverlayContainer = overlayContainer
|
||||||
|
let controllerStatusBarStyle = overlayContainer.controller.statusBar.statusBarStyle
|
||||||
|
switch controllerStatusBarStyle {
|
||||||
|
case .Black, .White, .Hide:
|
||||||
|
if topVisibleOverlayContainerWithStatusBar == nil {
|
||||||
|
topVisibleOverlayContainerWithStatusBar = overlayContainer
|
||||||
|
}
|
||||||
|
if case .Hide = controllerStatusBarStyle {
|
||||||
|
statusBarHidden = true
|
||||||
|
} else {
|
||||||
|
statusBarHidden = overlayContainer.controller.statusBar.alpha.isZero
|
||||||
|
}
|
||||||
|
case .Ignore:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.currentTopVisibleOverlayContainerStatusBar !== topVisibleOverlayContainerWithStatusBar {
|
||||||
|
self.currentTopVisibleOverlayContainerStatusBar = topVisibleOverlayContainerWithStatusBar
|
||||||
|
animateStatusBarStyleTransition = true
|
||||||
|
}
|
||||||
|
|
||||||
var previousModalContainer: NavigationModalContainer?
|
var previousModalContainer: NavigationModalContainer?
|
||||||
var visibleModalCount = 0
|
var visibleModalCount = 0
|
||||||
var topModalDismissProgress: CGFloat = 0.0
|
var topModalDismissProgress: CGFloat = 0.0
|
||||||
@ -342,6 +413,10 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
self.displayNode.insertSubnode(modalContainer, belowSubnode: previousModalContainer)
|
self.displayNode.insertSubnode(modalContainer, belowSubnode: previousModalContainer)
|
||||||
} else if let inCallStatusBar = self.inCallStatusBar {
|
} else if let inCallStatusBar = self.inCallStatusBar {
|
||||||
self.displayNode.insertSubnode(modalContainer, belowSubnode: inCallStatusBar)
|
self.displayNode.insertSubnode(modalContainer, belowSubnode: inCallStatusBar)
|
||||||
|
} else if let previousOverlayContainer = previousOverlayContainer {
|
||||||
|
self.displayNode.insertSubnode(modalContainer, belowSubnode: previousOverlayContainer)
|
||||||
|
} else if let globalScrollToTopNode = self.globalScrollToTopNode {
|
||||||
|
self.displayNode.insertSubnode(modalContainer, belowSubnode: globalScrollToTopNode)
|
||||||
} else {
|
} else {
|
||||||
self.displayNode.addSubnode(modalContainer)
|
self.displayNode.addSubnode(modalContainer)
|
||||||
}
|
}
|
||||||
@ -354,11 +429,14 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
topModalDismissProgress = modalContainer.dismissProgress
|
topModalDismissProgress = modalContainer.dismissProgress
|
||||||
if case .compact = layout.metrics.widthClass {
|
if case .compact = layout.metrics.widthClass {
|
||||||
modalContainer.keyboardViewManager = self.keyboardViewManager
|
modalContainer.keyboardViewManager = self.keyboardViewManager
|
||||||
|
modalContainer.canHaveKeyboardFocus = true
|
||||||
} else {
|
} else {
|
||||||
modalContainer.keyboardViewManager = nil
|
modalContainer.keyboardViewManager = nil
|
||||||
|
modalContainer.canHaveKeyboardFocus = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
modalContainer.keyboardViewManager = nil
|
modalContainer.keyboardViewManager = nil
|
||||||
|
modalContainer.canHaveKeyboardFocus = false
|
||||||
}
|
}
|
||||||
previousModalContainer = modalContainer
|
previousModalContainer = modalContainer
|
||||||
}
|
}
|
||||||
@ -371,8 +449,10 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
case let .flat(flatContainer):
|
case let .flat(flatContainer):
|
||||||
if previousModalContainer == nil {
|
if previousModalContainer == nil {
|
||||||
flatContainer.keyboardViewManager = self.keyboardViewManager
|
flatContainer.keyboardViewManager = self.keyboardViewManager
|
||||||
|
flatContainer.canHaveKeyboardFocus = true
|
||||||
} else {
|
} else {
|
||||||
flatContainer.keyboardViewManager = nil
|
flatContainer.keyboardViewManager = nil
|
||||||
|
flatContainer.canHaveKeyboardFocus = false
|
||||||
}
|
}
|
||||||
transition.updateFrame(node: flatContainer, frame: CGRect(origin: CGPoint(), size: layout.size))
|
transition.updateFrame(node: flatContainer, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||||
flatContainer.update(layout: layout, canBeClosed: false, controllers: controllers, transition: transition)
|
flatContainer.update(layout: layout, canBeClosed: false, controllers: controllers, transition: transition)
|
||||||
@ -386,6 +466,13 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
strongSelf.updateContainers(layout: layout, transition: transition)
|
strongSelf.updateContainers(layout: layout, transition: transition)
|
||||||
}
|
}
|
||||||
|
if previousModalContainer == nil {
|
||||||
|
flatContainer.keyboardViewManager = self.keyboardViewManager
|
||||||
|
flatContainer.canHaveKeyboardFocus = true
|
||||||
|
} else {
|
||||||
|
flatContainer.keyboardViewManager = nil
|
||||||
|
flatContainer.canHaveKeyboardFocus = false
|
||||||
|
}
|
||||||
self.displayNode.insertSubnode(flatContainer, at: 0)
|
self.displayNode.insertSubnode(flatContainer, at: 0)
|
||||||
self.rootContainer = .flat(flatContainer)
|
self.rootContainer = .flat(flatContainer)
|
||||||
flatContainer.frame = CGRect(origin: CGPoint(), size: layout.size)
|
flatContainer.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||||
@ -402,6 +489,13 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
strongSelf.updateContainers(layout: layout, transition: transition)
|
strongSelf.updateContainers(layout: layout, transition: transition)
|
||||||
}
|
}
|
||||||
|
if previousModalContainer == nil {
|
||||||
|
flatContainer.keyboardViewManager = self.keyboardViewManager
|
||||||
|
flatContainer.canHaveKeyboardFocus = true
|
||||||
|
} else {
|
||||||
|
flatContainer.keyboardViewManager = nil
|
||||||
|
flatContainer.canHaveKeyboardFocus = false
|
||||||
|
}
|
||||||
self.displayNode.insertSubnode(flatContainer, at: 0)
|
self.displayNode.insertSubnode(flatContainer, at: 0)
|
||||||
self.rootContainer = .flat(flatContainer)
|
self.rootContainer = .flat(flatContainer)
|
||||||
flatContainer.frame = CGRect(origin: CGPoint(), size: layout.size)
|
flatContainer.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||||
@ -413,23 +507,42 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
case let .flat(flatContainer):
|
case let .flat(flatContainer):
|
||||||
let splitContainer = NavigationSplitContainer(theme: self.theme, controllerRemoved: { [weak self] controller in
|
let splitContainer = NavigationSplitContainer(theme: self.theme, controllerRemoved: { [weak self] controller in
|
||||||
self?.controllerRemoved(controller)
|
self?.controllerRemoved(controller)
|
||||||
|
}, scrollToTop: { [weak self] subject in
|
||||||
|
self?.scrollToTop(subject)
|
||||||
})
|
})
|
||||||
self.displayNode.insertSubnode(splitContainer, at: 0)
|
self.displayNode.insertSubnode(splitContainer, at: 0)
|
||||||
self.rootContainer = .split(splitContainer)
|
self.rootContainer = .split(splitContainer)
|
||||||
|
if previousModalContainer == nil {
|
||||||
|
splitContainer.canHaveKeyboardFocus = true
|
||||||
|
} else {
|
||||||
|
splitContainer.canHaveKeyboardFocus = false
|
||||||
|
}
|
||||||
splitContainer.frame = CGRect(origin: CGPoint(), size: layout.size)
|
splitContainer.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||||
splitContainer.update(layout: layout, masterControllers: masterControllers, detailControllers: detailControllers, transition: .immediate)
|
splitContainer.update(layout: layout, masterControllers: masterControllers, detailControllers: detailControllers, transition: .immediate)
|
||||||
flatContainer.statusBarStyleUpdated = nil
|
flatContainer.statusBarStyleUpdated = nil
|
||||||
flatContainer.removeFromSupernode()
|
flatContainer.removeFromSupernode()
|
||||||
case let .split(splitContainer):
|
case let .split(splitContainer):
|
||||||
|
if previousModalContainer == nil {
|
||||||
|
splitContainer.canHaveKeyboardFocus = true
|
||||||
|
} else {
|
||||||
|
splitContainer.canHaveKeyboardFocus = false
|
||||||
|
}
|
||||||
transition.updateFrame(node: splitContainer, frame: CGRect(origin: CGPoint(), size: layout.size))
|
transition.updateFrame(node: splitContainer, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||||
splitContainer.update(layout: layout, masterControllers: masterControllers, detailControllers: detailControllers, transition: transition)
|
splitContainer.update(layout: layout, masterControllers: masterControllers, detailControllers: detailControllers, transition: transition)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let splitContainer = NavigationSplitContainer(theme: self.theme, controllerRemoved: { [weak self] controller in
|
let splitContainer = NavigationSplitContainer(theme: self.theme, controllerRemoved: { [weak self] controller in
|
||||||
self?.controllerRemoved(controller)
|
self?.controllerRemoved(controller)
|
||||||
|
}, scrollToTop: { [weak self] subject in
|
||||||
|
self?.scrollToTop(subject)
|
||||||
})
|
})
|
||||||
self.displayNode.insertSubnode(splitContainer, at: 0)
|
self.displayNode.insertSubnode(splitContainer, at: 0)
|
||||||
self.rootContainer = .split(splitContainer)
|
self.rootContainer = .split(splitContainer)
|
||||||
|
if previousModalContainer == nil {
|
||||||
|
splitContainer.canHaveKeyboardFocus = true
|
||||||
|
} else {
|
||||||
|
splitContainer.canHaveKeyboardFocus = false
|
||||||
|
}
|
||||||
splitContainer.frame = CGRect(origin: CGPoint(), size: layout.size)
|
splitContainer.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||||
splitContainer.update(layout: layout, masterControllers: masterControllers, detailControllers: detailControllers, transition: .immediate)
|
splitContainer.update(layout: layout, masterControllers: masterControllers, detailControllers: detailControllers, transition: .immediate)
|
||||||
}
|
}
|
||||||
@ -439,8 +552,9 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
switch rootContainer {
|
switch rootContainer {
|
||||||
case let .flat(container):
|
case let .flat(container):
|
||||||
statusBarStyle = container.statusBarStyle
|
statusBarStyle = container.statusBarStyle
|
||||||
|
self.globalScrollToTopNode?.isHidden = false
|
||||||
case .split:
|
case .split:
|
||||||
break
|
self.globalScrollToTopNode?.isHidden = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,6 +673,18 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.inCallStatusBar != nil {
|
||||||
|
statusBarStyle = .White
|
||||||
|
}
|
||||||
|
|
||||||
|
if let topVisibleOverlayContainerWithStatusBar = topVisibleOverlayContainerWithStatusBar {
|
||||||
|
statusBarStyle = topVisibleOverlayContainerWithStatusBar.controller.statusBar.statusBarStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.currentStatusBarExternalHidden {
|
||||||
|
statusBarHidden = true
|
||||||
|
}
|
||||||
|
|
||||||
let resolvedStatusBarStyle: NavigationStatusBarStyle
|
let resolvedStatusBarStyle: NavigationStatusBarStyle
|
||||||
switch statusBarStyle {
|
switch statusBarStyle {
|
||||||
case .Ignore, .Hide:
|
case .Ignore, .Hide:
|
||||||
@ -580,6 +706,11 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
self.statusBarHost?.setStatusBarStyle(normalStatusBarStyle, animated: animateStatusBarStyleTransition)
|
self.statusBarHost?.setStatusBarStyle(normalStatusBarStyle, animated: animateStatusBarStyleTransition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.validStatusBarHidden != statusBarHidden {
|
||||||
|
self.validStatusBarHidden = statusBarHidden
|
||||||
|
self.statusBarHost?.setStatusBarHidden(statusBarHidden, animated: animateStatusBarStyleTransition)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func controllerRemoved(_ controller: ViewController) {
|
private func controllerRemoved(_ controller: ViewController) {
|
||||||
@ -589,6 +720,28 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
public func updateModalTransition(_ value: CGFloat, transition: ContainedViewLayoutTransition) {
|
public func updateModalTransition(_ value: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func scrollToTop(_ subject: NavigationSplitContainerScrollToTop) {
|
||||||
|
if let _ = self.inCallStatusBar {
|
||||||
|
self.inCallNavigate?()
|
||||||
|
} else if let rootContainer = self.rootContainer {
|
||||||
|
if let modalContainer = self.modalContainers.last {
|
||||||
|
modalContainer.container.controllers.last?.scrollToTop?()
|
||||||
|
} else {
|
||||||
|
switch rootContainer {
|
||||||
|
case let .flat(container):
|
||||||
|
container.controllers.last?.scrollToTop?()
|
||||||
|
case let .split(container):
|
||||||
|
switch subject {
|
||||||
|
case .master:
|
||||||
|
container.masterControllers.last?.scrollToTop?()
|
||||||
|
case .detail:
|
||||||
|
container.detailControllers.last?.scrollToTop?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
|
public func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
|
||||||
/*for record in self._viewControllers {
|
/*for record in self._viewControllers {
|
||||||
if let controller = record.controller as? ContainableController {
|
if let controller = record.controller as? ContainableController {
|
||||||
@ -613,9 +766,11 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
self.navigationBar.removeFromSuperview()
|
self.navigationBar.removeFromSuperview()
|
||||||
|
|
||||||
/*let inCallStatusBar = StatusBar()
|
let globalScrollToTopNode = ScrollToTopNode(action: { [weak self] in
|
||||||
self.displayNode.addSubnode(inCallStatusBar)
|
self?.scrollToTop(.master)
|
||||||
self.inCallStatusBar = inCallStatusBar*/
|
})
|
||||||
|
self.displayNode.addSubnode(globalScrollToTopNode)
|
||||||
|
self.globalScrollToTopNode = globalScrollToTopNode
|
||||||
}
|
}
|
||||||
|
|
||||||
public func pushViewController(_ controller: ViewController) {
|
public func pushViewController(_ controller: ViewController) {
|
||||||
@ -750,6 +905,53 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func presentOverlay(controller: ViewController, inGlobal: Bool = false) {
|
||||||
|
let container = NavigationOverlayContainer(controller: controller, controllerRemoved: { [weak self] controller in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i in 0 ..< strongSelf.overlayContainers.count {
|
||||||
|
let overlayContainer = strongSelf.overlayContainers[i]
|
||||||
|
if overlayContainer.controller === controller {
|
||||||
|
overlayContainer.removeFromSupernode()
|
||||||
|
strongSelf.overlayContainers.remove(at: i)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let layout = strongSelf.validLayout {
|
||||||
|
strongSelf.updateContainers(layout: layout, transition: .immediate)
|
||||||
|
}
|
||||||
|
}, statusBarUpdated: { [weak self] transition in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let layout = strongSelf.validLayout {
|
||||||
|
strongSelf.updateContainers(layout: layout, transition: transition)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
self.overlayContainers.append(container)
|
||||||
|
container.isReadyUpdated = { [weak self, weak container] in
|
||||||
|
guard let strongSelf = self, let container = container else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let layout = strongSelf.validLayout {
|
||||||
|
strongSelf.updateContainers(layout: layout, transition: .immediate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let layout = self.validLayout {
|
||||||
|
self.updateContainers(layout: layout, transition: .immediate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateExternalStatusBarHidden(_ value: Bool, transition: ContainedViewLayoutTransition) {
|
||||||
|
if self.currentStatusBarExternalHidden != value {
|
||||||
|
self.currentStatusBarExternalHidden = value
|
||||||
|
if let layout = self.validLayout {
|
||||||
|
self.updateContainers(layout: layout, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override open func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
|
override open func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
|
||||||
preconditionFailure()
|
preconditionFailure()
|
||||||
}
|
}
|
||||||
@ -816,4 +1018,49 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
self.containerLayoutUpdated(validLayout, transition: transition)
|
self.containerLayoutUpdated(validLayout, transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func setForceInCallStatusBar(_ forceInCallStatusBarText: String?, transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)) {
|
||||||
|
if let forceInCallStatusBarText = forceInCallStatusBarText {
|
||||||
|
let inCallStatusBar: StatusBar
|
||||||
|
if let current = self.inCallStatusBar {
|
||||||
|
inCallStatusBar = current
|
||||||
|
} else {
|
||||||
|
inCallStatusBar = StatusBar()
|
||||||
|
inCallStatusBar.inCallNavigate = { [weak self] in
|
||||||
|
self?.scrollToTop(.master)
|
||||||
|
}
|
||||||
|
inCallStatusBar.alpha = 0.0
|
||||||
|
self.inCallStatusBar = inCallStatusBar
|
||||||
|
|
||||||
|
var bottomOverlayContainer: NavigationOverlayContainer?
|
||||||
|
for overlayContainer in self.overlayContainers {
|
||||||
|
if overlayContainer.supernode != nil {
|
||||||
|
bottomOverlayContainer = overlayContainer
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let bottomOverlayContainer = bottomOverlayContainer {
|
||||||
|
self.displayNode.insertSubnode(inCallStatusBar, belowSubnode: bottomOverlayContainer)
|
||||||
|
} else if let globalScrollToTopNode = self.globalScrollToTopNode {
|
||||||
|
self.displayNode.insertSubnode(inCallStatusBar, belowSubnode: globalScrollToTopNode)
|
||||||
|
} else {
|
||||||
|
self.displayNode.addSubnode(inCallStatusBar)
|
||||||
|
}
|
||||||
|
transition.updateAlpha(node: inCallStatusBar, alpha: 1.0)
|
||||||
|
}
|
||||||
|
if let layout = self.validLayout {
|
||||||
|
self.containerLayoutUpdated(layout, transition: transition)
|
||||||
|
inCallStatusBar.updateState(statusBar: nil, withSafeInsets: false, inCallText: forceInCallStatusBarText, animated: false)
|
||||||
|
}
|
||||||
|
} else if let inCallStatusBar = self.inCallStatusBar {
|
||||||
|
self.inCallStatusBar = nil
|
||||||
|
transition.updateAlpha(node: inCallStatusBar, alpha: 0.0, completion: { [weak inCallStatusBar] _ in
|
||||||
|
inCallStatusBar?.removeFromSupernode()
|
||||||
|
})
|
||||||
|
if let layout = self.validLayout {
|
||||||
|
self.containerLayoutUpdated(layout, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,12 @@ final class NavigationModalContainer: ASDisplayNode, UIScrollViewDelegate, UIGes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var canHaveKeyboardFocus: Bool = false {
|
||||||
|
didSet {
|
||||||
|
self.container.canHaveKeyboardFocus = self.canHaveKeyboardFocus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init(theme: NavigationControllerTheme, controllerRemoved: @escaping (ViewController) -> Void) {
|
init(theme: NavigationControllerTheme, controllerRemoved: @escaping (ViewController) -> Void) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
|
||||||
@ -195,6 +201,8 @@ final class NavigationModalContainer: ASDisplayNode, UIScrollViewDelegate, UIGes
|
|||||||
self.dismissProgress = dismissProgress
|
self.dismissProgress = dismissProgress
|
||||||
|
|
||||||
self.applyDismissProgress(transition: transition, completion: {})
|
self.applyDismissProgress(transition: transition, completion: {})
|
||||||
|
|
||||||
|
self.view.endEditing(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||||
|
|||||||
@ -0,0 +1,78 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import AsyncDisplayKit
|
||||||
|
import SwiftSignalKit
|
||||||
|
|
||||||
|
final class NavigationOverlayContainer: ASDisplayNode {
|
||||||
|
let controller: ViewController
|
||||||
|
|
||||||
|
private(set) var isReady: Bool = false
|
||||||
|
var isReadyUpdated: (() -> Void)?
|
||||||
|
private var isReadyDisposable: Disposable?
|
||||||
|
|
||||||
|
private var validLayout: ContainerViewLayout?
|
||||||
|
|
||||||
|
var keyboardViewManager: KeyboardViewManager? {
|
||||||
|
didSet {
|
||||||
|
if self.keyboardViewManager !== oldValue {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(controller: ViewController, controllerRemoved: @escaping (ViewController) -> Void, statusBarUpdated: @escaping (ContainedViewLayoutTransition) -> Void) {
|
||||||
|
self.controller = controller
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.controller.navigation_setDismiss({ [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
controllerRemoved(strongSelf.controller)
|
||||||
|
}, rootController: nil)
|
||||||
|
|
||||||
|
self.controller.statusBar.alphaUpdated = { transition in
|
||||||
|
statusBarUpdated(transition)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.isReadyDisposable = (self.controller.ready.get()
|
||||||
|
|> filter { $0 }
|
||||||
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] _ in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !strongSelf.isReady {
|
||||||
|
strongSelf.isReady = true
|
||||||
|
strongSelf.isReadyUpdated?()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.isReadyDisposable?.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func didLoad() {
|
||||||
|
super.didLoad()
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||||
|
let updateLayout = self.validLayout != layout
|
||||||
|
|
||||||
|
self.validLayout = layout
|
||||||
|
|
||||||
|
if updateLayout {
|
||||||
|
transition.updateFrame(node: self.controller.displayNode, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||||
|
self.controller.containerLayoutUpdated(layout, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func transitionIn() {
|
||||||
|
self.controller.viewWillAppear(false)
|
||||||
|
self.controller.setIgnoreAppearanceMethodInvocations(true)
|
||||||
|
self.addSubnode(self.controller.displayNode)
|
||||||
|
self.controller.setIgnoreAppearanceMethodInvocations(false)
|
||||||
|
self.controller.viewDidAppear(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,19 +3,42 @@ import UIKit
|
|||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
|
|
||||||
|
enum NavigationSplitContainerScrollToTop {
|
||||||
|
case master
|
||||||
|
case detail
|
||||||
|
}
|
||||||
|
|
||||||
final class NavigationSplitContainer: ASDisplayNode {
|
final class NavigationSplitContainer: ASDisplayNode {
|
||||||
private var theme: NavigationControllerTheme
|
private var theme: NavigationControllerTheme
|
||||||
|
|
||||||
|
private let masterScrollToTopView: ScrollToTopView
|
||||||
|
private let detailScrollToTopView: ScrollToTopView
|
||||||
private let masterContainer: NavigationContainer
|
private let masterContainer: NavigationContainer
|
||||||
private let detailContainer: NavigationContainer
|
private let detailContainer: NavigationContainer
|
||||||
private let separator: ASDisplayNode
|
private let separator: ASDisplayNode
|
||||||
|
|
||||||
private var masterControllers: [ViewController] = []
|
private(set) var masterControllers: [ViewController] = []
|
||||||
private var detailControllers: [ViewController] = []
|
private(set) var detailControllers: [ViewController] = []
|
||||||
|
|
||||||
init(theme: NavigationControllerTheme, controllerRemoved: @escaping (ViewController) -> Void) {
|
var canHaveKeyboardFocus: Bool = false {
|
||||||
|
didSet {
|
||||||
|
self.masterContainer.canHaveKeyboardFocus = self.canHaveKeyboardFocus
|
||||||
|
self.detailContainer.canHaveKeyboardFocus = self.canHaveKeyboardFocus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(theme: NavigationControllerTheme, controllerRemoved: @escaping (ViewController) -> Void, scrollToTop: @escaping (NavigationSplitContainerScrollToTop) -> Void) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
|
||||||
|
self.masterScrollToTopView = ScrollToTopView(frame: CGRect())
|
||||||
|
self.masterScrollToTopView.action = {
|
||||||
|
scrollToTop(.master)
|
||||||
|
}
|
||||||
|
self.detailScrollToTopView = ScrollToTopView(frame: CGRect())
|
||||||
|
self.detailScrollToTopView.action = {
|
||||||
|
scrollToTop(.detail)
|
||||||
|
}
|
||||||
|
|
||||||
self.masterContainer = NavigationContainer(controllerRemoved: controllerRemoved)
|
self.masterContainer = NavigationContainer(controllerRemoved: controllerRemoved)
|
||||||
self.masterContainer.clipsToBounds = true
|
self.masterContainer.clipsToBounds = true
|
||||||
|
|
||||||
@ -30,6 +53,8 @@ final class NavigationSplitContainer: ASDisplayNode {
|
|||||||
self.addSubnode(self.masterContainer)
|
self.addSubnode(self.masterContainer)
|
||||||
self.addSubnode(self.detailContainer)
|
self.addSubnode(self.detailContainer)
|
||||||
self.addSubnode(self.separator)
|
self.addSubnode(self.separator)
|
||||||
|
self.view.addSubview(self.masterScrollToTopView)
|
||||||
|
self.view.addSubview(self.detailScrollToTopView)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateTheme(theme: NavigationControllerTheme) {
|
func updateTheme(theme: NavigationControllerTheme) {
|
||||||
@ -40,6 +65,9 @@ final class NavigationSplitContainer: ASDisplayNode {
|
|||||||
let masterWidth = min(max(320.0, floor(layout.size.width / 3.0)), floor(layout.size.width / 2.0))
|
let masterWidth = min(max(320.0, floor(layout.size.width / 3.0)), floor(layout.size.width / 2.0))
|
||||||
let detailWidth = layout.size.width - masterWidth
|
let detailWidth = layout.size.width - masterWidth
|
||||||
|
|
||||||
|
self.masterScrollToTopView.frame = CGRect(origin: CGPoint(x: 0.0, y: -1.0), size: CGSize(width: masterWidth, height: 1.0))
|
||||||
|
self.detailScrollToTopView.frame = CGRect(origin: CGPoint(x: masterWidth, y: -1.0), size: CGSize(width: detailWidth, height: 1.0))
|
||||||
|
|
||||||
transition.updateFrame(node: self.masterContainer, frame: CGRect(origin: CGPoint(), size: CGSize(width: masterWidth, height: layout.size.height)))
|
transition.updateFrame(node: self.masterContainer, frame: CGRect(origin: CGPoint(), size: CGSize(width: masterWidth, height: layout.size.height)))
|
||||||
transition.updateFrame(node: self.detailContainer, frame: CGRect(origin: CGPoint(x: masterWidth, y: 0.0), size: CGSize(width: detailWidth, height: layout.size.height)))
|
transition.updateFrame(node: self.detailContainer, frame: CGRect(origin: CGPoint(x: masterWidth, y: 0.0), size: CGSize(width: detailWidth, height: layout.size.height)))
|
||||||
transition.updateFrame(node: self.separator, frame: CGRect(origin: CGPoint(x: masterWidth, y: 0.0), size: CGSize(width: UIScreenPixel, height: layout.size.height)))
|
transition.updateFrame(node: self.separator, frame: CGRect(origin: CGPoint(x: masterWidth, y: 0.0), size: CGSize(width: UIScreenPixel, height: layout.size.height)))
|
||||||
|
|||||||
@ -35,3 +35,15 @@ class ScrollToTopView: UIScrollView, UIScrollViewDelegate {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ScrollToTopNode: ASDisplayNode {
|
||||||
|
init(action: @escaping () -> Void) {
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.setViewBlock({
|
||||||
|
let view = ScrollToTopView(frame: CGRect())
|
||||||
|
view.action = action
|
||||||
|
return view
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -68,6 +68,7 @@ public final class StatusBar: ASDisplayNode {
|
|||||||
didSet {
|
didSet {
|
||||||
if self.statusBarStyle != oldValue {
|
if self.statusBarStyle != oldValue {
|
||||||
self.layer.invalidateUpTheTree()
|
self.layer.invalidateUpTheTree()
|
||||||
|
self.alphaUpdated?(.immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,6 +95,13 @@ public final class StatusBar: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var alphaUpdated: ((ContainedViewLayoutTransition) -> Void)?
|
||||||
|
|
||||||
|
public func updateAlpha(_ alpha: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
|
self.alpha = alpha
|
||||||
|
self.alphaUpdated?(transition)
|
||||||
|
}
|
||||||
|
|
||||||
public override init() {
|
public override init() {
|
||||||
self.inCallLabel = StatusBarLabelNode()
|
self.inCallLabel = StatusBarLabelNode()
|
||||||
self.inCallLabel.isUserInteractionEnabled = false
|
self.inCallLabel.isUserInteractionEnabled = false
|
||||||
|
|||||||
@ -12,5 +12,8 @@ public protocol StatusBarHost {
|
|||||||
|
|
||||||
var handleVolumeControl: Signal<Bool, NoError> { get }
|
var handleVolumeControl: Signal<Bool, NoError> { get }
|
||||||
|
|
||||||
|
var isApplicationInForeground: Bool { get }
|
||||||
|
|
||||||
func setStatusBarStyle(_ style: UIStatusBarStyle, animated: Bool)
|
func setStatusBarStyle(_ style: UIStatusBarStyle, animated: Bool)
|
||||||
|
func setStatusBarHidden(_ value: Bool, animated: Bool)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -127,6 +127,15 @@ open class TabBarController: ViewController {
|
|||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
|
||||||
super.init(navigationBarPresentationData: navigationBarPresentationData)
|
super.init(navigationBarPresentationData: navigationBarPresentationData)
|
||||||
|
|
||||||
|
self.scrollToTop = { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let controller = strongSelf.currentController {
|
||||||
|
controller.scrollToTop?()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(coder aDecoder: NSCoder) {
|
required public init(coder aDecoder: NSCoder) {
|
||||||
|
|||||||
@ -246,7 +246,7 @@ public enum ViewControllerNavigationPresentation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func updateScrollToTopView() {
|
private func updateScrollToTopView() {
|
||||||
if self.scrollToTop != nil {
|
/*if self.scrollToTop != nil {
|
||||||
if let displayNode = self._displayNode , self.scrollToTopView == nil {
|
if let displayNode = self._displayNode , self.scrollToTopView == nil {
|
||||||
let scrollToTopView = ScrollToTopView(frame: CGRect(x: 0.0, y: -1.0, width: displayNode.bounds.size.width, height: 1.0))
|
let scrollToTopView = ScrollToTopView(frame: CGRect(x: 0.0, y: -1.0, width: displayNode.bounds.size.width, height: 1.0))
|
||||||
scrollToTopView.action = { [weak self] in
|
scrollToTopView.action = { [weak self] in
|
||||||
@ -257,7 +257,7 @@ public enum ViewControllerNavigationPresentation {
|
|||||||
self.scrollToTopView = scrollToTopView
|
self.scrollToTopView = scrollToTopView
|
||||||
self.view.addSubview(scrollToTopView)
|
self.view.addSubview(scrollToTopView)
|
||||||
}
|
}
|
||||||
} else if let scrollToTopView = self.scrollToTopView {
|
} else*/ if let scrollToTopView = self.scrollToTopView {
|
||||||
scrollToTopView.removeFromSuperview()
|
scrollToTopView.removeFromSuperview()
|
||||||
self.scrollToTopView = nil
|
self.scrollToTopView = nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -280,7 +280,7 @@ public class Window1 {
|
|||||||
private var deviceMetrics: DeviceMetrics
|
private var deviceMetrics: DeviceMetrics
|
||||||
|
|
||||||
private let statusBarHost: StatusBarHost?
|
private let statusBarHost: StatusBarHost?
|
||||||
private let statusBarManager: StatusBarManager?
|
//private let statusBarManager: StatusBarManager?
|
||||||
private let keyboardManager: KeyboardManager?
|
private let keyboardManager: KeyboardManager?
|
||||||
private let keyboardViewManager: KeyboardViewManager?
|
private let keyboardViewManager: KeyboardViewManager?
|
||||||
private var statusBarChangeObserver: AnyObject?
|
private var statusBarChangeObserver: AnyObject?
|
||||||
@ -312,7 +312,7 @@ public class Window1 {
|
|||||||
public private(set) var forceInCallStatusBarText: String? = nil
|
public private(set) var forceInCallStatusBarText: String? = nil
|
||||||
public var inCallNavigate: (() -> Void)? {
|
public var inCallNavigate: (() -> Void)? {
|
||||||
didSet {
|
didSet {
|
||||||
self.statusBarManager?.inCallNavigate = self.inCallNavigate
|
//self.statusBarManager?.inCallNavigate = self.inCallNavigate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,21 +323,17 @@ public class Window1 {
|
|||||||
|
|
||||||
private var keyboardTypeChangeTimer: SwiftSignalKit.Timer?
|
private var keyboardTypeChangeTimer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
private let volumeControlStatusBar: VolumeControlStatusBar
|
//private let volumeControlStatusBar: VolumeControlStatusBar
|
||||||
private let volumeControlStatusBarNode: VolumeControlStatusBarNode
|
//private let volumeControlStatusBarNode: VolumeControlStatusBarNode
|
||||||
|
|
||||||
private var isInteractionBlocked = false
|
private var isInteractionBlocked = false
|
||||||
|
|
||||||
/*private var accessibilityElements: [Any]? {
|
|
||||||
return self.viewController?.view.accessibilityElements
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public init(hostView: WindowHostView, statusBarHost: StatusBarHost?) {
|
public init(hostView: WindowHostView, statusBarHost: StatusBarHost?) {
|
||||||
self.hostView = hostView
|
self.hostView = hostView
|
||||||
|
|
||||||
self.volumeControlStatusBar = VolumeControlStatusBar(frame: CGRect(origin: CGPoint(x: 0.0, y: -20.0), size: CGSize(width: 100.0, height: 20.0)), shouldBeVisible: statusBarHost?.handleVolumeControl ?? .single(false))
|
//self.volumeControlStatusBar = VolumeControlStatusBar(frame: CGRect(origin: CGPoint(x: 0.0, y: -20.0), size: CGSize(width: 100.0, height: 20.0)), shouldBeVisible: statusBarHost?.handleVolumeControl ?? .single(false))
|
||||||
self.volumeControlStatusBarNode = VolumeControlStatusBarNode()
|
//self.volumeControlStatusBarNode = VolumeControlStatusBarNode()
|
||||||
self.volumeControlStatusBarNode.isHidden = true
|
//self.volumeControlStatusBarNode.isHidden = true
|
||||||
|
|
||||||
let boundsSize = self.hostView.eventView.bounds.size
|
let boundsSize = self.hostView.eventView.bounds.size
|
||||||
self.deviceMetrics = DeviceMetrics(screenSize: UIScreen.main.bounds.size, statusBarHeight: statusBarHost?.statusBarFrame.height ?? defaultStatusBarHeight, onScreenNavigationHeight: self.hostView.onScreenNavigationHeight)
|
self.deviceMetrics = DeviceMetrics(screenSize: UIScreen.main.bounds.size, statusBarHeight: statusBarHost?.statusBarFrame.height ?? defaultStatusBarHeight, onScreenNavigationHeight: self.hostView.onScreenNavigationHeight)
|
||||||
@ -346,12 +342,12 @@ public class Window1 {
|
|||||||
let statusBarHeight: CGFloat
|
let statusBarHeight: CGFloat
|
||||||
if let statusBarHost = statusBarHost {
|
if let statusBarHost = statusBarHost {
|
||||||
statusBarHeight = statusBarHost.statusBarFrame.size.height
|
statusBarHeight = statusBarHost.statusBarFrame.size.height
|
||||||
self.statusBarManager = StatusBarManager(host: statusBarHost, volumeControlStatusBar: self.volumeControlStatusBar, volumeControlStatusBarNode: self.volumeControlStatusBarNode)
|
//self.statusBarManager = StatusBarManager(host: statusBarHost, volumeControlStatusBar: self.volumeControlStatusBar, volumeControlStatusBarNode: self.volumeControlStatusBarNode)
|
||||||
self.keyboardManager = KeyboardManager(host: statusBarHost)
|
self.keyboardManager = KeyboardManager(host: statusBarHost)
|
||||||
self.keyboardViewManager = KeyboardViewManager(host: statusBarHost)
|
self.keyboardViewManager = KeyboardViewManager(host: statusBarHost)
|
||||||
} else {
|
} else {
|
||||||
statusBarHeight = self.deviceMetrics.statusBarHeight
|
statusBarHeight = self.deviceMetrics.statusBarHeight
|
||||||
self.statusBarManager = nil
|
//self.statusBarManager = nil
|
||||||
self.keyboardManager = nil
|
self.keyboardManager = nil
|
||||||
self.keyboardViewManager = nil
|
self.keyboardViewManager = nil
|
||||||
}
|
}
|
||||||
@ -394,7 +390,7 @@ public class Window1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.hostView.layoutSubviews = { [weak self] in
|
self.hostView.layoutSubviews = { [weak self] in
|
||||||
self?.layoutSubviews()
|
self?.layoutSubviews(force: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.hostView.updateToInterfaceOrientation = { [weak self] orientation in
|
self.hostView.updateToInterfaceOrientation = { [weak self] orientation in
|
||||||
@ -433,7 +429,7 @@ public class Window1 {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
self.presentationContext.view = self.hostView.containerView
|
self.presentationContext.view = self.hostView.containerView
|
||||||
self.presentationContext.volumeControlStatusBarNodeView = self.volumeControlStatusBarNode.view
|
//self.presentationContext.volumeControlStatusBarNodeView = self.volumeControlStatusBarNode.view
|
||||||
self.presentationContext.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout, deviceMetrics: self.deviceMetrics), transition: .immediate)
|
self.presentationContext.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout, deviceMetrics: self.deviceMetrics), transition: .immediate)
|
||||||
self.overlayPresentationContext.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout, deviceMetrics: self.deviceMetrics), transition: .immediate)
|
self.overlayPresentationContext.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout, deviceMetrics: self.deviceMetrics), transition: .immediate)
|
||||||
|
|
||||||
@ -455,7 +451,7 @@ public class Window1 {
|
|||||||
keyboardHeight = max(0.0, keyboardHeight - 24.0)
|
keyboardHeight = max(0.0, keyboardHeight - 24.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
print("keyboardHeight: \(keyboardHeight)")
|
//print("rotation keyboardHeight: \(keyboardHeight)")
|
||||||
|
|
||||||
var duration: Double = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0
|
var duration: Double = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0
|
||||||
if duration > Double.ulpOfOne {
|
if duration > Double.ulpOfOne {
|
||||||
@ -483,12 +479,31 @@ public class Window1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var popoverDelta: CGFloat = 0.0
|
||||||
|
|
||||||
let screenHeight: CGFloat
|
let screenHeight: CGFloat
|
||||||
var inPopover = false
|
var inPopover = false
|
||||||
if keyboardFrame.width.isEqual(to: UIScreen.main.bounds.width) {
|
if keyboardFrame.width.isEqual(to: UIScreen.main.bounds.width) {
|
||||||
|
var portraitScreenSize = UIScreen.main.bounds.size
|
||||||
|
if portraitScreenSize.width > portraitScreenSize.height {
|
||||||
|
portraitScreenSize = CGSize(width: portraitScreenSize.height, height: portraitScreenSize.width)
|
||||||
|
}
|
||||||
|
var portraitLayoutSize = strongSelf.windowLayout.size
|
||||||
|
if portraitLayoutSize.width > portraitLayoutSize.height {
|
||||||
|
portraitLayoutSize = CGSize(width: portraitLayoutSize.height, height: portraitLayoutSize.width)
|
||||||
|
}
|
||||||
if abs(strongSelf.windowLayout.size.height - UIScreen.main.bounds.height) > 41.0 {
|
if abs(strongSelf.windowLayout.size.height - UIScreen.main.bounds.height) > 41.0 {
|
||||||
screenHeight = UIScreen.main.bounds.height
|
screenHeight = UIScreen.main.bounds.height
|
||||||
inPopover = true
|
if abs(portraitLayoutSize.height - portraitScreenSize.height) > 41.0 || abs(portraitLayoutSize.width - portraitScreenSize.width) > 41.0 {
|
||||||
|
popoverDelta = 48.0
|
||||||
|
inPopover = true
|
||||||
|
}
|
||||||
|
} else if abs(strongSelf.windowLayout.size.height - UIScreen.main.bounds.height) > 39.0 {
|
||||||
|
screenHeight = UIScreen.main.bounds.height
|
||||||
|
if abs(portraitLayoutSize.height - portraitScreenSize.height) > 39.0 || abs(portraitLayoutSize.width - portraitScreenSize.width) > 39.0 {
|
||||||
|
popoverDelta = 40.0
|
||||||
|
inPopover = true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
screenHeight = strongSelf.windowLayout.size.height
|
screenHeight = strongSelf.windowLayout.size.height
|
||||||
}
|
}
|
||||||
@ -503,14 +518,14 @@ public class Window1 {
|
|||||||
keyboardHeight = max(0.0, screenHeight - keyboardFrame.minY)
|
keyboardHeight = max(0.0, screenHeight - keyboardFrame.minY)
|
||||||
if inPopover {
|
if inPopover {
|
||||||
if strongSelf.windowLayout.onScreenNavigationHeight != nil {
|
if strongSelf.windowLayout.onScreenNavigationHeight != nil {
|
||||||
keyboardHeight = max(0.0, keyboardHeight - 24.0)
|
keyboardHeight = max(0.0, keyboardHeight - popoverDelta / 2.0)
|
||||||
} else {
|
} else {
|
||||||
keyboardHeight = max(0.0, keyboardHeight - 48.0)
|
keyboardHeight = max(0.0, keyboardHeight - popoverDelta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print("keyboardHeight: \(keyboardHeight)")
|
print("keyboardHeight: \(keyboardHeight) (raw: \(keyboardFrame))")
|
||||||
|
|
||||||
var duration: Double = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0
|
var duration: Double = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0
|
||||||
if duration > Double.ulpOfOne {
|
if duration > Double.ulpOfOne {
|
||||||
@ -586,8 +601,8 @@ public class Window1 {
|
|||||||
self.windowPanRecognizer = recognizer
|
self.windowPanRecognizer = recognizer
|
||||||
self.hostView.containerView.addGestureRecognizer(recognizer)
|
self.hostView.containerView.addGestureRecognizer(recognizer)
|
||||||
|
|
||||||
self.hostView.containerView.addSubview(self.volumeControlStatusBar)
|
//self.hostView.containerView.addSubview(self.volumeControlStatusBar)
|
||||||
self.hostView.containerView.addSubview(self.volumeControlStatusBarNode.view)
|
//self.hostView.containerView.addSubview(self.volumeControlStatusBarNode.view)
|
||||||
}
|
}
|
||||||
|
|
||||||
public required init(coder aDecoder: NSCoder) {
|
public required init(coder aDecoder: NSCoder) {
|
||||||
@ -613,7 +628,7 @@ public class Window1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func setupVolumeControlStatusBarGraphics(_ graphics: (UIImage, UIImage, UIImage)) {
|
public func setupVolumeControlStatusBarGraphics(_ graphics: (UIImage, UIImage, UIImage)) {
|
||||||
self.volumeControlStatusBarNode.graphics = graphics
|
//self.volumeControlStatusBarNode.graphics = graphics
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setForceInCallStatusBar(_ forceInCallStatusBarText: String?, transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)) {
|
public func setForceInCallStatusBar(_ forceInCallStatusBarText: String?, transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)) {
|
||||||
@ -701,6 +716,9 @@ public class Window1 {
|
|||||||
transition = .immediate
|
transition = .immediate
|
||||||
}
|
}
|
||||||
self.updateLayout { $0.update(size: value, metrics: layoutMetricsForScreenSize(value), safeInsets: self.deviceMetrics.safeInsets(inLandscape: value.width > value.height), forceInCallStatusBarText: self.forceInCallStatusBarText, transition: transition, overrideTransition: true) }
|
self.updateLayout { $0.update(size: value, metrics: layoutMetricsForScreenSize(value), safeInsets: self.deviceMetrics.safeInsets(inLandscape: value.width > value.height), forceInCallStatusBarText: self.forceInCallStatusBarText, transition: transition, overrideTransition: true) }
|
||||||
|
if let statusBarHost = self.statusBarHost, !statusBarHost.isApplicationInForeground {
|
||||||
|
self.layoutSubviews(force: true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var _rootController: ContainableController?
|
private var _rootController: ContainableController?
|
||||||
@ -718,6 +736,9 @@ public class Window1 {
|
|||||||
if let rootController = rootController as? NavigationController {
|
if let rootController = rootController as? NavigationController {
|
||||||
rootController.statusBarHost = self.statusBarHost
|
rootController.statusBarHost = self.statusBarHost
|
||||||
rootController.keyboardViewManager = self.keyboardViewManager
|
rootController.keyboardViewManager = self.keyboardViewManager
|
||||||
|
rootController.inCallNavigate = { [weak self] in
|
||||||
|
self?.inCallNavigate?()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !self.windowLayout.size.width.isZero && !self.windowLayout.size.height.isZero {
|
if !self.windowLayout.size.width.isZero && !self.windowLayout.size.height.isZero {
|
||||||
rootController.displayNode.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
rootController.displayNode.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
||||||
@ -738,6 +759,9 @@ public class Window1 {
|
|||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
for controller in self._topLevelOverlayControllers {
|
for controller in self._topLevelOverlayControllers {
|
||||||
|
if let controller = controller as? ViewController {
|
||||||
|
controller.statusBar.alphaUpdated = nil
|
||||||
|
}
|
||||||
controller.view.removeFromSuperview()
|
controller.view.removeFromSuperview()
|
||||||
}
|
}
|
||||||
self._topLevelOverlayControllers = value
|
self._topLevelOverlayControllers = value
|
||||||
@ -750,7 +774,25 @@ public class Window1 {
|
|||||||
if let coveringView = self.coveringView {
|
if let coveringView = self.coveringView {
|
||||||
self.hostView.containerView.insertSubview(controller.view, belowSubview: coveringView)
|
self.hostView.containerView.insertSubview(controller.view, belowSubview: coveringView)
|
||||||
} else {
|
} else {
|
||||||
self.hostView.containerView.insertSubview(controller.view, belowSubview: self.volumeControlStatusBarNode.view)
|
self.hostView.containerView.addSubview(controller.view)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let controller = controller as? ViewController {
|
||||||
|
controller.statusBar.alphaUpdated = { [weak self] transition in
|
||||||
|
guard let strongSelf = self, let navigationController = strongSelf._rootController as? NavigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var isStatusBarHidden: Bool = false
|
||||||
|
for controller in strongSelf._topLevelOverlayControllers {
|
||||||
|
if let controller = controller as? ViewController {
|
||||||
|
if case .Hide = controller.statusBar.statusBarStyle {
|
||||||
|
isStatusBarHidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
navigationController.updateExternalStatusBarHidden(isStatusBarHidden, transition: .animated(duration: 0.3, curve: .easeInOut))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,7 +813,7 @@ public class Window1 {
|
|||||||
coveringView.layer.removeAnimation(forKey: "opacity")
|
coveringView.layer.removeAnimation(forKey: "opacity")
|
||||||
coveringView.layer.allowsGroupOpacity = false
|
coveringView.layer.allowsGroupOpacity = false
|
||||||
coveringView.alpha = 1.0
|
coveringView.alpha = 1.0
|
||||||
self.hostView.containerView.insertSubview(coveringView, belowSubview: self.volumeControlStatusBarNode.view)
|
self.hostView.containerView.addSubview(coveringView)
|
||||||
if !self.windowLayout.size.width.isZero {
|
if !self.windowLayout.size.width.isZero {
|
||||||
coveringView.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
coveringView.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
||||||
coveringView.updateLayout(self.windowLayout.size)
|
coveringView.updateLayout(self.windowLayout.size)
|
||||||
@ -781,7 +823,7 @@ public class Window1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func layoutSubviews() {
|
private func layoutSubviews(force: Bool) {
|
||||||
var hasPreview = false
|
var hasPreview = false
|
||||||
var updatedHasPreview = false
|
var updatedHasPreview = false
|
||||||
for subview in self.hostView.eventView.subviews {
|
for subview in self.hostView.eventView.subviews {
|
||||||
@ -796,7 +838,7 @@ public class Window1 {
|
|||||||
updatedHasPreview = true
|
updatedHasPreview = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.tracingStatusBarsInvalidated || updatedHasPreview, let statusBarManager = statusBarManager, let keyboardManager = keyboardManager {
|
if self.tracingStatusBarsInvalidated || updatedHasPreview, let keyboardManager = keyboardManager {
|
||||||
self.tracingStatusBarsInvalidated = false
|
self.tracingStatusBarsInvalidated = false
|
||||||
|
|
||||||
/*if self.statusBarHidden {
|
/*if self.statusBarHidden {
|
||||||
@ -902,7 +944,9 @@ public class Window1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !UIWindow.isDeviceRotating() {
|
if force {
|
||||||
|
self.commitUpdatingLayout()
|
||||||
|
} else if !UIWindow.isDeviceRotating() {
|
||||||
if !self.hostView.isUpdatingOrientationLayout {
|
if !self.hostView.isUpdatingOrientationLayout {
|
||||||
self.commitUpdatingLayout()
|
self.commitUpdatingLayout()
|
||||||
} else {
|
} else {
|
||||||
@ -967,6 +1011,9 @@ public class Window1 {
|
|||||||
let boundsSize = updatingLayout.layout.size
|
let boundsSize = updatingLayout.layout.size
|
||||||
let isLandscape = boundsSize.width > boundsSize.height
|
let isLandscape = boundsSize.width > boundsSize.height
|
||||||
var statusBarHeight: CGFloat? = self.deviceMetrics.statusBarHeight(for: boundsSize)
|
var statusBarHeight: CGFloat? = self.deviceMetrics.statusBarHeight(for: boundsSize)
|
||||||
|
if let statusBarHeightValue = statusBarHeight, let statusBarHost = self.statusBarHost {
|
||||||
|
statusBarHeight = max(statusBarHeightValue, statusBarHost.statusBarFrame.size.height)
|
||||||
|
}
|
||||||
|
|
||||||
if self.deviceMetrics.type == .tablet, let onScreenNavigationHeight = self.hostView.onScreenNavigationHeight, onScreenNavigationHeight != self.deviceMetrics.onScreenNavigationHeight(inLandscape: false) {
|
if self.deviceMetrics.type == .tablet, let onScreenNavigationHeight = self.hostView.onScreenNavigationHeight, onScreenNavigationHeight != self.deviceMetrics.onScreenNavigationHeight(inLandscape: false) {
|
||||||
self.deviceMetrics = DeviceMetrics(screenSize: UIScreen.main.bounds.size, statusBarHeight: statusBarHeight ?? defaultStatusBarHeight, onScreenNavigationHeight: onScreenNavigationHeight)
|
self.deviceMetrics = DeviceMetrics(screenSize: UIScreen.main.bounds.size, statusBarHeight: statusBarHeight ?? defaultStatusBarHeight, onScreenNavigationHeight: onScreenNavigationHeight)
|
||||||
@ -1023,8 +1070,8 @@ public class Window1 {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.volumeControlStatusBarNode.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
//self.volumeControlStatusBarNode.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
||||||
self.volumeControlStatusBarNode.updateLayout(layout: childLayout, transition: updatingLayout.transition)
|
//self.volumeControlStatusBarNode.updateLayout(layout: childLayout, transition: updatingLayout.transition)
|
||||||
|
|
||||||
if let coveringView = self.coveringView {
|
if let coveringView = self.coveringView {
|
||||||
coveringView.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
coveringView.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
||||||
@ -1035,7 +1082,12 @@ public class Window1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func present(_ controller: ContainableController, on level: PresentationSurfaceLevel, blockInteraction: Bool = false, completion: @escaping () -> Void = {}) {
|
public func present(_ controller: ContainableController, on level: PresentationSurfaceLevel, blockInteraction: Bool = false, completion: @escaping () -> Void = {}) {
|
||||||
self.presentationContext.present(controller, on: level, blockInteraction: blockInteraction, completion: completion)
|
if let navigationController = self._rootController as? NavigationController, let controller = controller as? ViewController {
|
||||||
|
navigationController.presentOverlay(controller: controller, inGlobal: false)
|
||||||
|
} else {
|
||||||
|
assertionFailure()
|
||||||
|
}
|
||||||
|
//self.presentationContext.present(controller, on: level, blockInteraction: blockInteraction, completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func presentInGlobalOverlay(_ controller: ContainableController) {
|
public func presentInGlobalOverlay(_ controller: ContainableController) {
|
||||||
|
|||||||
@ -275,14 +275,14 @@ open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGesture
|
|||||||
UIView.animate(withDuration: 0.3, animations: {
|
UIView.animate(withDuration: 0.3, animations: {
|
||||||
let alpha: CGFloat = self.areControlsHidden ? 0.0 : 1.0
|
let alpha: CGFloat = self.areControlsHidden ? 0.0 : 1.0
|
||||||
self.navigationBar?.alpha = alpha
|
self.navigationBar?.alpha = alpha
|
||||||
self.statusBar?.alpha = alpha
|
self.statusBar?.updateAlpha(alpha, transition: .animated(duration: 0.3, curve: .easeInOut))
|
||||||
self.footerNode.alpha = alpha
|
self.footerNode.alpha = alpha
|
||||||
self.updateThumbnailContainerNodeAlpha(.immediate)
|
self.updateThumbnailContainerNodeAlpha(.immediate)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let alpha: CGFloat = self.areControlsHidden ? 0.0 : 1.0
|
let alpha: CGFloat = self.areControlsHidden ? 0.0 : 1.0
|
||||||
self.navigationBar?.alpha = alpha
|
self.navigationBar?.alpha = alpha
|
||||||
self.statusBar?.alpha = alpha
|
self.statusBar?.updateAlpha(alpha, transition: .immediate)
|
||||||
self.footerNode.alpha = alpha
|
self.footerNode.alpha = alpha
|
||||||
self.updateThumbnailContainerNodeAlpha(.immediate)
|
self.updateThumbnailContainerNodeAlpha(.immediate)
|
||||||
}
|
}
|
||||||
@ -374,7 +374,11 @@ open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGesture
|
|||||||
self.updateThumbnailContainerNodeAlpha(.immediate)
|
self.updateThumbnailContainerNodeAlpha(.immediate)
|
||||||
|
|
||||||
if !self.areControlsHidden {
|
if !self.areControlsHidden {
|
||||||
self.statusBar?.alpha = transition
|
if transition < 0.5 {
|
||||||
|
self.statusBar?.updateAlpha(0.0, transition: .animated(duration: 0.3, curve: .easeInOut))
|
||||||
|
} else {
|
||||||
|
self.statusBar?.updateAlpha(1.0, transition: .animated(duration: 0.3, curve: .easeInOut))
|
||||||
|
}
|
||||||
self.navigationBar?.alpha = transition
|
self.navigationBar?.alpha = transition
|
||||||
self.footerNode.alpha = transition
|
self.footerNode.alpha = transition
|
||||||
|
|
||||||
|
|||||||
@ -364,10 +364,10 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
|
|||||||
addedInsets = UIEdgeInsets(top: 0.0, left: inset, bottom: 0.0, right: inset)
|
addedInsets = UIEdgeInsets(top: 0.0, left: inset, bottom: 0.0, right: inset)
|
||||||
|
|
||||||
if self.leftOverlayNode.supernode == nil {
|
if self.leftOverlayNode.supernode == nil {
|
||||||
self.addSubnode(self.leftOverlayNode)
|
self.insertSubnode(self.leftOverlayNode, aboveSubnode: self.listNode)
|
||||||
}
|
}
|
||||||
if self.rightOverlayNode.supernode == nil {
|
if self.rightOverlayNode.supernode == nil {
|
||||||
self.addSubnode(self.rightOverlayNode)
|
self.insertSubnode(self.rightOverlayNode, aboveSubnode: self.listNode)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
insets.left += layout.safeInsets.left
|
insets.left += layout.safeInsets.left
|
||||||
|
|||||||
@ -93,13 +93,15 @@
|
|||||||
|
|
||||||
- (BOOL)prefersStatusBarHidden
|
- (BOOL)prefersStatusBarHidden
|
||||||
{
|
{
|
||||||
if (!TGIsPad() && iosMajorVersion() >= 11 && UIInterfaceOrientationIsLandscape([[LegacyComponentsGlobals provider] applicationStatusBarOrientation]))
|
return true;
|
||||||
|
|
||||||
|
/*if (!TGIsPad() && iosMajorVersion() >= 11 && UIInterfaceOrientationIsLandscape([[LegacyComponentsGlobals provider] applicationStatusBarOrientation]))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (self.childViewControllers.count > 0)
|
if (self.childViewControllers.count > 0)
|
||||||
return [self.childViewControllers.lastObject prefersStatusBarHidden];
|
return [self.childViewControllers.lastObject prefersStatusBarHidden];
|
||||||
|
|
||||||
return [super prefersStatusBarHidden];
|
return [super prefersStatusBarHidden];*/
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
|
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
|
||||||
@ -262,7 +264,7 @@
|
|||||||
{
|
{
|
||||||
[UIView animateWithDuration:0.2 animations:^
|
[UIView animateWithDuration:0.2 animations:^
|
||||||
{
|
{
|
||||||
[strongSelf->_context setApplicationStatusBarAlpha:1.0f];
|
//[strongSelf->_context setApplicationStatusBarAlpha:1.0f];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1155,7 +1157,7 @@ static CGFloat transformRotation(CGAffineTransform transform)
|
|||||||
{
|
{
|
||||||
[UIView animateWithDuration:0.2 animations:^
|
[UIView animateWithDuration:0.2 animations:^
|
||||||
{
|
{
|
||||||
[_context setApplicationStatusBarAlpha:1.0f];
|
//[_context setApplicationStatusBarAlpha:1.0f];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1228,7 +1230,7 @@ static CGFloat transformRotation(CGAffineTransform transform)
|
|||||||
|
|
||||||
if (self.adjustsStatusBarVisibility)
|
if (self.adjustsStatusBarVisibility)
|
||||||
{
|
{
|
||||||
[_context setApplicationStatusBarAlpha:1.0f];
|
//[_context setApplicationStatusBarAlpha:1.0f];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -247,7 +247,7 @@ public final class LegacyControllerContext: NSObject, LegacyComponentsContext {
|
|||||||
|
|
||||||
public func setApplicationStatusBarAlpha(_ alpha: CGFloat) {
|
public func setApplicationStatusBarAlpha(_ alpha: CGFloat) {
|
||||||
if let controller = self.controller {
|
if let controller = self.controller {
|
||||||
controller.statusBar.alpha = alpha
|
controller.statusBar.updateAlpha(alpha, transition: .immediate)
|
||||||
self.updateDeferScreenEdgeGestures()
|
self.updateDeferScreenEdgeGestures()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,8 @@ public extension Peer {
|
|||||||
}
|
}
|
||||||
} else if let lastName = user.lastName {
|
} else if let lastName = user.lastName {
|
||||||
return lastName
|
return lastName
|
||||||
|
} else if let phone = user.phone {
|
||||||
|
return "+\(phone)"
|
||||||
} else {
|
} else {
|
||||||
return strings.User_DeletedAccount
|
return strings.User_DeletedAccount
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@ -40,6 +42,17 @@
|
|||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "E66DC04E89A74F8D00000000"
|
||||||
|
BuildableName = "libSwiftSignalKit.dylib"
|
||||||
|
BlueprintName = "SwiftSignalKit#shared"
|
||||||
|
ReferencedContainer = "container:SwiftSignalKit.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@ -1102,9 +1102,13 @@ public func settingsController(context: AccountContext, accountManager: AccountM
|
|||||||
|> mapToSignal { context in
|
|> mapToSignal { context in
|
||||||
return context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
|
return context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
|
||||||
|> map { view -> Bool in
|
|> map { view -> Bool in
|
||||||
let appConfiguration = view.values[PreferencesKeys.appConfiguration] as? AppConfiguration ?? .defaultValue
|
if #available(iOSApplicationExtension 10.3, iOS 10.3, *) {
|
||||||
let configuration = WalletConfiguration.with(appConfiguration: appConfiguration)
|
let appConfiguration = view.values[PreferencesKeys.appConfiguration] as? AppConfiguration ?? .defaultValue
|
||||||
return configuration.config != nil
|
let configuration = WalletConfiguration.with(appConfiguration: appConfiguration)
|
||||||
|
return configuration.config != nil
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1375,7 +1379,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM
|
|||||||
(controller?.navigationController as? NavigationController)?.replaceAllButRootController(value, animated: true, animationOptions: [.removeOnMasterDetails])
|
(controller?.navigationController as? NavigationController)?.replaceAllButRootController(value, animated: true, animationOptions: [.removeOnMasterDetails])
|
||||||
}
|
}
|
||||||
presentControllerImpl = { [weak controller] value, arguments in
|
presentControllerImpl = { [weak controller] value, arguments in
|
||||||
controller?.present(value, in: .window(.root), with: arguments ?? ViewControllerPresentationArguments(presentationAnimation: .modalSheet), blockInteraction: true)
|
controller?.present(value, in: .window(.root), with: arguments, blockInteraction: true)
|
||||||
}
|
}
|
||||||
presentInGlobalOverlayImpl = { [weak controller] value, arguments in
|
presentInGlobalOverlayImpl = { [weak controller] value, arguments in
|
||||||
controller?.presentInGlobalOverlay(value, with: arguments)
|
controller?.presentInGlobalOverlay(value, with: arguments)
|
||||||
|
|||||||
@ -54,7 +54,7 @@ public extension TermsOfServiceControllerTheme {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TermsOfServiceController: ViewController {
|
public class TermsOfServiceController: ViewController, StandalonePresentableController {
|
||||||
private var controllerNode: TermsOfServiceControllerNode {
|
private var controllerNode: TermsOfServiceControllerNode {
|
||||||
return self.displayNode as! TermsOfServiceControllerNode
|
return self.displayNode as! TermsOfServiceControllerNode
|
||||||
}
|
}
|
||||||
|
|||||||
@ -271,6 +271,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
override func didLoad() {
|
override func didLoad() {
|
||||||
super.didLoad()
|
super.didLoad()
|
||||||
|
|
||||||
|
self.scrollNode.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
self.scrollNode.view.showsHorizontalScrollIndicator = false
|
self.scrollNode.view.showsHorizontalScrollIndicator = false
|
||||||
self.scrollNode.view.isPagingEnabled = true
|
self.scrollNode.view.isPagingEnabled = true
|
||||||
self.scrollNode.view.delegate = self
|
self.scrollNode.view.delegate = self
|
||||||
|
|||||||
@ -129,7 +129,7 @@ public extension Peer {
|
|||||||
var isDeleted: Bool {
|
var isDeleted: Bool {
|
||||||
switch self {
|
switch self {
|
||||||
case let user as TelegramUser:
|
case let user as TelegramUser:
|
||||||
return user.firstName == nil && user.lastName == nil
|
return user.firstName == nil && user.lastName == nil && user.phone == nil
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ public enum TonKeychainEncryptDataError {
|
|||||||
public enum TonKeychainDecryptDataError {
|
public enum TonKeychainDecryptDataError {
|
||||||
case generic
|
case generic
|
||||||
case publicKeyMismatch
|
case publicKeyMismatch
|
||||||
|
case cancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct TonKeychain {
|
public struct TonKeychain {
|
||||||
@ -332,8 +333,8 @@ public final class TonInstance {
|
|||||||
|
|
||||||
fileprivate func walletRestoreWords(walletInfo: WalletInfo, keychain: TonKeychain, serverSalt: Data) -> Signal<[String], WalletRestoreWordsError> {
|
fileprivate func walletRestoreWords(walletInfo: WalletInfo, keychain: TonKeychain, serverSalt: Data) -> Signal<[String], WalletRestoreWordsError> {
|
||||||
return keychain.decrypt(walletInfo.encryptedSecret)
|
return keychain.decrypt(walletInfo.encryptedSecret)
|
||||||
|> mapError { _ -> WalletRestoreWordsError in
|
|> mapError { error -> WalletRestoreWordsError in
|
||||||
return .secretDecryptionFailed
|
return .secretDecryptionFailed(error)
|
||||||
}
|
}
|
||||||
|> mapToSignal { decryptedSecret -> Signal<[String], WalletRestoreWordsError> in
|
|> mapToSignal { decryptedSecret -> Signal<[String], WalletRestoreWordsError> in
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
@ -365,8 +366,8 @@ public final class TonInstance {
|
|||||||
|
|
||||||
fileprivate func deleteLocalWalletData(walletInfo: WalletInfo, keychain: TonKeychain, serverSalt: Data) -> Signal<Never, DeleteLocalWalletDataError> {
|
fileprivate func deleteLocalWalletData(walletInfo: WalletInfo, keychain: TonKeychain, serverSalt: Data) -> Signal<Never, DeleteLocalWalletDataError> {
|
||||||
return keychain.decrypt(walletInfo.encryptedSecret)
|
return keychain.decrypt(walletInfo.encryptedSecret)
|
||||||
|> mapError { _ -> DeleteLocalWalletDataError in
|
|> mapError { error -> DeleteLocalWalletDataError in
|
||||||
return .secretDecryptionFailed
|
return .secretDecryptionFailed(error)
|
||||||
}
|
}
|
||||||
|> mapToSignal { decryptedSecret -> Signal<Never, DeleteLocalWalletDataError> in
|
|> mapToSignal { decryptedSecret -> Signal<Never, DeleteLocalWalletDataError> in
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
@ -581,7 +582,7 @@ public func importWallet(postbox: Postbox, network: Network, tonInstance: TonIns
|
|||||||
|
|
||||||
public enum DeleteLocalWalletDataError {
|
public enum DeleteLocalWalletDataError {
|
||||||
case generic
|
case generic
|
||||||
case secretDecryptionFailed
|
case secretDecryptionFailed(TonKeychainDecryptDataError)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func deleteLocalWalletData(postbox: Postbox, network: Network, tonInstance: TonInstance, keychain: TonKeychain, walletInfo: WalletInfo) -> Signal<Never, DeleteLocalWalletDataError> {
|
public func deleteLocalWalletData(postbox: Postbox, network: Network, tonInstance: TonInstance, keychain: TonKeychain, walletInfo: WalletInfo) -> Signal<Never, DeleteLocalWalletDataError> {
|
||||||
@ -612,7 +613,7 @@ public func deleteLocalWalletData(postbox: Postbox, network: Network, tonInstanc
|
|||||||
|
|
||||||
public enum WalletRestoreWordsError {
|
public enum WalletRestoreWordsError {
|
||||||
case generic
|
case generic
|
||||||
case secretDecryptionFailed
|
case secretDecryptionFailed(TonKeychainDecryptDataError)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func walletRestoreWords(network: Network, walletInfo: WalletInfo, tonInstance: TonInstance, keychain: TonKeychain) -> Signal<[String], WalletRestoreWordsError> {
|
public func walletRestoreWords(network: Network, walletInfo: WalletInfo, tonInstance: TonInstance, keychain: TonKeychain) -> Signal<[String], WalletRestoreWordsError> {
|
||||||
|
|||||||
@ -56,6 +56,15 @@ private let keyboardWindowClass: AnyClass? = {
|
|||||||
private class ApplicationStatusBarHost: StatusBarHost {
|
private class ApplicationStatusBarHost: StatusBarHost {
|
||||||
private let application = UIApplication.shared
|
private let application = UIApplication.shared
|
||||||
|
|
||||||
|
var isApplicationInForeground: Bool {
|
||||||
|
switch self.application.applicationState {
|
||||||
|
case .background:
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var statusBarFrame: CGRect {
|
var statusBarFrame: CGRect {
|
||||||
return self.application.statusBarFrame
|
return self.application.statusBarFrame
|
||||||
}
|
}
|
||||||
@ -71,6 +80,10 @@ private class ApplicationStatusBarHost: StatusBarHost {
|
|||||||
self.application.setStatusBarStyle(style, animated: animated)
|
self.application.setStatusBarStyle(style, animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setStatusBarHidden(_ value: Bool, animated: Bool) {
|
||||||
|
self.application.setStatusBarHidden(value, with: animated ? .fade : .none)
|
||||||
|
}
|
||||||
|
|
||||||
var statusBarWindow: UIView? {
|
var statusBarWindow: UIView? {
|
||||||
return self.application.value(forKey: "statusBarWindow") as? UIView
|
return self.application.value(forKey: "statusBarWindow") as? UIView
|
||||||
}
|
}
|
||||||
@ -664,6 +677,7 @@ final class SharedApplicationContext {
|
|||||||
#if targetEnvironment(simulator)
|
#if targetEnvironment(simulator)
|
||||||
tonKeychain = TonKeychain(encryptionPublicKey: {
|
tonKeychain = TonKeychain(encryptionPublicKey: {
|
||||||
//return .single(nil)
|
//return .single(nil)
|
||||||
|
//return .single("1".data(using: .utf8)!)
|
||||||
return .single(Data())
|
return .single(Data())
|
||||||
}, encrypt: { data in
|
}, encrypt: { data in
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
@ -701,11 +715,17 @@ final class SharedApplicationContext {
|
|||||||
}
|
}
|
||||||
}, decrypt: { encryptedData in
|
}, decrypt: { encryptedData in
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
BuildConfig.decryptApplicationSecret(encryptedData.data, publicKey: encryptedData.publicKey, baseAppBundleId: baseAppBundleId, completion: { result in
|
BuildConfig.decryptApplicationSecret(encryptedData.data, publicKey: encryptedData.publicKey, baseAppBundleId: baseAppBundleId, completion: { result, cancelled in
|
||||||
if let result = result {
|
if let result = result {
|
||||||
subscriber.putNext(result)
|
subscriber.putNext(result)
|
||||||
} else {
|
} else {
|
||||||
subscriber.putError(.generic)
|
let error: TonKeychainDecryptDataError
|
||||||
|
if cancelled {
|
||||||
|
error = .cancelled
|
||||||
|
} else {
|
||||||
|
error = .generic
|
||||||
|
}
|
||||||
|
subscriber.putError(error)
|
||||||
}
|
}
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
})
|
})
|
||||||
@ -1259,9 +1279,12 @@ final class SharedApplicationContext {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if UIApplication.shared.isStatusBarHidden {
|
||||||
|
UIApplication.shared.setStatusBarHidden(false, with: .none)
|
||||||
|
}
|
||||||
NotificationCenter.default.addObserver(forName: UIWindow.didBecomeHiddenNotification, object: nil, queue: nil, using: { notification in
|
NotificationCenter.default.addObserver(forName: UIWindow.didBecomeHiddenNotification, object: nil, queue: nil, using: { notification in
|
||||||
if UIApplication.shared.isStatusBarHidden {
|
if UIApplication.shared.isStatusBarHidden {
|
||||||
UIApplication.shared.setStatusBarHidden(false, with: .none)
|
//UIApplication.shared.setStatusBarHidden(false, with: .none)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -456,6 +456,7 @@ final class AuthorizedApplicationContext {
|
|||||||
}, expandAction: { expandData in
|
}, expandAction: { expandData in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let chatController = ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(firstMessage.id.peerId), mode: .overlay)
|
let chatController = ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(firstMessage.id.peerId), mode: .overlay)
|
||||||
|
//chatController.navigation_setNavigationController(strongSelf.rootController)
|
||||||
(strongSelf.rootController.viewControllers.last as? ViewController)?.present(chatController, in: .window(.root), with: ChatControllerOverlayPresentationData(expandData: expandData()))
|
(strongSelf.rootController.viewControllers.last as? ViewController)?.present(chatController, in: .window(.root), with: ChatControllerOverlayPresentationData(expandData: expandData()))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|||||||
@ -2312,7 +2312,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
private func themeAndStringsUpdated() {
|
private func themeAndStringsUpdated() {
|
||||||
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
|
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
|
||||||
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
|
switch self.presentationInterfaceState.mode {
|
||||||
|
case .standard:
|
||||||
|
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
|
||||||
|
self.deferScreenEdgeGestures = []
|
||||||
|
case .overlay:
|
||||||
|
self.statusBar.statusBarStyle = .Hide
|
||||||
|
self.deferScreenEdgeGestures = [.top]
|
||||||
|
case .inline:
|
||||||
|
self.statusBar.statusBarStyle = .Ignore
|
||||||
|
}
|
||||||
self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData))
|
self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData))
|
||||||
self.chatTitleView?.updateThemeAndStrings(theme: self.presentationData.theme, strings: self.presentationData.strings)
|
self.chatTitleView?.updateThemeAndStrings(theme: self.presentationData.theme, strings: self.presentationData.strings)
|
||||||
self.updateChatPresentationInterfaceState(animated: false, interactive: false, { state in
|
self.updateChatPresentationInterfaceState(animated: false, interactive: false, { state in
|
||||||
@ -2589,22 +2598,19 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
self.chatDisplayNode.historyNode.contentPositionChanged = { [weak self] offset in
|
self.chatDisplayNode.historyNode.contentPositionChanged = { [weak self] offset in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let offsetAlpha: CGFloat
|
let offsetAlpha: CGFloat
|
||||||
if case let .standard(previewing) = strongSelf.presentationInterfaceState.mode, previewing {
|
switch offset {
|
||||||
offsetAlpha = 0.0
|
case let .known(offset):
|
||||||
} else {
|
if offset < 40.0 {
|
||||||
switch offset {
|
|
||||||
case let .known(offset):
|
|
||||||
if offset < 40.0 {
|
|
||||||
offsetAlpha = 0.0
|
|
||||||
} else {
|
|
||||||
offsetAlpha = 1.0
|
|
||||||
}
|
|
||||||
case .unknown:
|
|
||||||
offsetAlpha = 1.0
|
|
||||||
case .none:
|
|
||||||
offsetAlpha = 0.0
|
offsetAlpha = 0.0
|
||||||
}
|
} else {
|
||||||
|
offsetAlpha = 1.0
|
||||||
|
}
|
||||||
|
case .unknown:
|
||||||
|
offsetAlpha = 1.0
|
||||||
|
case .none:
|
||||||
|
offsetAlpha = 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.chatDisplayNode.navigateButtons.displayDownButton = !offsetAlpha.isZero
|
strongSelf.chatDisplayNode.navigateButtons.displayDownButton = !offsetAlpha.isZero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1903,6 +1903,9 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
switch self.chatPresentationInterfaceState.mode {
|
switch self.chatPresentationInterfaceState.mode {
|
||||||
case .standard(previewing: true):
|
case .standard(previewing: true):
|
||||||
|
if let result = self.navigateButtons.hitTest(self.view.convert(point, to: self.navigateButtons.view), with: event) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
if self.bounds.contains(point) {
|
if self.bounds.contains(point) {
|
||||||
return self.historyNode.view
|
return self.historyNode.view
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,8 @@ public final class NotificationContainerController: ViewController {
|
|||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
private var presentationDataDisposable: Disposable?
|
private var presentationDataDisposable: Disposable?
|
||||||
|
|
||||||
|
private var validLayout: ContainerViewLayout?
|
||||||
|
|
||||||
public init(context: AccountContext) {
|
public init(context: AccountContext) {
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
@ -61,7 +63,15 @@ public final class NotificationContainerController: ViewController {
|
|||||||
|
|
||||||
self.controllerNode.displayingItemsUpdated = { [weak self] value in
|
self.controllerNode.displayingItemsUpdated = { [weak self] value in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.statusBar.statusBarStyle = value ? .Hide : .Ignore
|
var statusBarHidden = false
|
||||||
|
if value, let layout = strongSelf.validLayout {
|
||||||
|
if let statusBarHeight = layout.statusBarHeight, statusBarHeight > 20.0 {
|
||||||
|
statusBarHidden = false
|
||||||
|
} else {
|
||||||
|
statusBarHidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strongSelf.statusBar.statusBarStyle = statusBarHidden ? .Hide : .Ignore
|
||||||
if value {
|
if value {
|
||||||
strongSelf.deferScreenEdgeGestures = [.top]
|
strongSelf.deferScreenEdgeGestures = [.top]
|
||||||
} else {
|
} else {
|
||||||
@ -72,6 +82,8 @@ public final class NotificationContainerController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||||
|
self.validLayout = layout
|
||||||
|
|
||||||
super.containerLayoutUpdated(layout, transition: transition)
|
super.containerLayoutUpdated(layout, transition: transition)
|
||||||
|
|
||||||
self.controllerNode.containerLayoutUpdated(layout, transition: transition)
|
self.controllerNode.containerLayoutUpdated(layout, transition: transition)
|
||||||
|
|||||||
@ -68,29 +68,19 @@ final class NotificationContainerControllerNode: ASDisplayNode {
|
|||||||
if let (item, topItemNode) = self.topItemAndNode {
|
if let (item, topItemNode) = self.topItemAndNode {
|
||||||
if item.groupingKey == key {
|
if item.groupingKey == key {
|
||||||
self.topItemAndNode = nil
|
self.topItemAndNode = nil
|
||||||
|
self.displayingItemsUpdated?(false)
|
||||||
topItemNode.animateOut(completion: { [weak self, weak topItemNode] in
|
topItemNode.animateOut(completion: { [weak self, weak topItemNode] in
|
||||||
topItemNode?.removeFromSupernode()
|
topItemNode?.removeFromSupernode()
|
||||||
|
|
||||||
if let strongSelf = self, strongSelf.topItemAndNode == nil {
|
|
||||||
strongSelf.displayingItemsUpdated?(false)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func enqueue(_ item: NotificationItem) {
|
func enqueue(_ item: NotificationItem) {
|
||||||
var updatedDisplayingItems = false
|
|
||||||
if let (_, topItemNode) = self.topItemAndNode {
|
if let (_, topItemNode) = self.topItemAndNode {
|
||||||
topItemNode.animateOut(completion: { [weak self, weak topItemNode] in
|
topItemNode.animateOut(completion: { [weak self, weak topItemNode] in
|
||||||
topItemNode?.removeFromSupernode()
|
topItemNode?.removeFromSupernode()
|
||||||
|
|
||||||
if let strongSelf = self, strongSelf.topItemAndNode == nil {
|
|
||||||
strongSelf.displayingItemsUpdated?(false)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
updatedDisplayingItems = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var useCompactLayout = false
|
var useCompactLayout = false
|
||||||
@ -138,9 +128,7 @@ final class NotificationContainerControllerNode: ASDisplayNode {
|
|||||||
containerNode.animateIn()
|
containerNode.animateIn()
|
||||||
}
|
}
|
||||||
|
|
||||||
if updatedDisplayingItems {
|
self.displayingItemsUpdated?(true)
|
||||||
self.displayingItemsUpdated?(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.resetTimeoutTimer()
|
self.resetTimeoutTimer()
|
||||||
}
|
}
|
||||||
@ -172,12 +160,9 @@ final class NotificationContainerControllerNode: ASDisplayNode {
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
if let (_, topItemNode) = strongSelf.topItemAndNode {
|
if let (_, topItemNode) = strongSelf.topItemAndNode {
|
||||||
strongSelf.topItemAndNode = nil
|
strongSelf.topItemAndNode = nil
|
||||||
|
strongSelf.displayingItemsUpdated?(false)
|
||||||
topItemNode.animateOut(completion: { [weak topItemNode] in
|
topItemNode.animateOut(completion: { [weak topItemNode] in
|
||||||
topItemNode?.removeFromSupernode()
|
topItemNode?.removeFromSupernode()
|
||||||
|
|
||||||
if let strongSelf = self, strongSelf.topItemAndNode == nil {
|
|
||||||
strongSelf.displayingItemsUpdated?(false)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -842,10 +842,13 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
} else {
|
} else {
|
||||||
text = presentationData.strings.Call_StatusBar("").0
|
text = presentationData.strings.Call_StatusBar("").0
|
||||||
}
|
}
|
||||||
|
if let navigationController = self.mainWindow?.viewController as? NavigationController {
|
||||||
self.mainWindow?.setForceInCallStatusBar(text)
|
navigationController.setForceInCallStatusBar(text)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.mainWindow?.setForceInCallStatusBar(nil)
|
if let navigationController = self.mainWindow?.viewController as? NavigationController {
|
||||||
|
navigationController.setForceInCallStatusBar(nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -94,16 +94,20 @@ public final class WalletSplashScreen: ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
strongSelf.sendGrams(walletInfo: walletInfo, decryptedSecret: decryptedSecret, address: address, amount: amount, textMessage: textMessage, forceIfDestinationNotInitialized: false, randomId: randomId, serverSalt: serverSalt)
|
strongSelf.sendGrams(walletInfo: walletInfo, decryptedSecret: decryptedSecret, address: address, amount: amount, textMessage: textMessage, forceIfDestinationNotInitialized: false, randomId: randomId, serverSalt: serverSalt)
|
||||||
}, error: { [weak self] _ in
|
}, error: { [weak self] error in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let text = strongSelf.presentationData.strings.Wallet_Send_ErrorDecryptionFailed
|
if case .cancelled = error {
|
||||||
let controller = textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
|
strongSelf.dismiss()
|
||||||
self?.dismiss()
|
} else {
|
||||||
})])
|
let text = strongSelf.presentationData.strings.Wallet_Send_ErrorDecryptionFailed
|
||||||
strongSelf.present(controller, in: .window(.root))
|
let controller = textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
|
||||||
strongSelf.dismiss()
|
self?.dismiss()
|
||||||
|
})])
|
||||||
|
strongSelf.present(controller, in: .window(.root))
|
||||||
|
strongSelf.dismiss()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
case .sent:
|
case .sent:
|
||||||
self.navigationItem.setLeftBarButton(UIBarButtonItem(customDisplayNode: ASDisplayNode())!, animated: false)
|
self.navigationItem.setLeftBarButton(UIBarButtonItem(customDisplayNode: ASDisplayNode())!, animated: false)
|
||||||
@ -235,15 +239,18 @@ public final class WalletSplashScreen: ViewController {
|
|||||||
strongSelf.mode = .created(walletInfo, wordList)
|
strongSelf.mode = .created(walletInfo, wordList)
|
||||||
controller.dismiss()
|
controller.dismiss()
|
||||||
strongSelf.push(WalletWordDisplayScreen(context: strongSelf.context, tonContext: strongSelf.tonContext, walletInfo: walletInfo, wordList: wordList, mode: .check, walletCreatedPreloadState: strongSelf.walletCreatedPreloadState))
|
strongSelf.push(WalletWordDisplayScreen(context: strongSelf.context, tonContext: strongSelf.tonContext, walletInfo: walletInfo, wordList: wordList, mode: .check, walletCreatedPreloadState: strongSelf.walletCreatedPreloadState))
|
||||||
}, error: { _ in
|
}, error: { error in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
controller.dismiss()
|
controller.dismiss()
|
||||||
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: strongSelf.presentationData.strings.Wallet_Created_ExportErrorTitle, text: strongSelf.presentationData.strings.Wallet_Created_ExportErrorText, actions: [
|
if case let .secretDecryptionFailed(.cancelled) = error {
|
||||||
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
|
} else {
|
||||||
})
|
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: strongSelf.presentationData.strings.Wallet_Created_ExportErrorTitle, text: strongSelf.presentationData.strings.Wallet_Created_ExportErrorText, actions: [
|
||||||
], actionLayout: .vertical), in: .window(.root))
|
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
|
||||||
|
})
|
||||||
|
], actionLayout: .vertical), in: .window(.root))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case let .success(walletInfo):
|
case let .success(walletInfo):
|
||||||
@ -720,16 +727,7 @@ private final class WalletSplashScreenNode: ViewControllerTracingNode {
|
|||||||
let secondaryActionSize = self.secondaryActionTitleNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: layout.size.height))
|
let secondaryActionSize = self.secondaryActionTitleNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: layout.size.height))
|
||||||
|
|
||||||
let contentHeight = iconSize.height + iconSpacing + titleSize.height + titleSpacing + textSize.height
|
let contentHeight = iconSize.height + iconSpacing + titleSize.height + titleSpacing + textSize.height
|
||||||
let contentVerticalOrigin = floor((layout.size.height - contentHeight - iconSize.height / 2.0) / 2.0)
|
var contentVerticalOrigin = floor((layout.size.height - contentHeight - iconSize.height / 2.0) / 2.0)
|
||||||
|
|
||||||
let iconFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: contentVerticalOrigin), size: iconSize).offsetBy(dx: iconOffset.x, dy: iconOffset.y)
|
|
||||||
transition.updateFrameAdditive(node: self.iconNode, frame: iconFrame)
|
|
||||||
self.animationNode.updateLayout(size: iconFrame.size)
|
|
||||||
transition.updateFrameAdditive(node: self.animationNode, frame: iconFrame)
|
|
||||||
let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: iconFrame.maxY + iconSpacing), size: titleSize)
|
|
||||||
transition.updateFrameAdditive(node: self.titleNode, frame: titleFrame)
|
|
||||||
let textFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - textSize.width) / 2.0), y: titleFrame.maxY + titleSpacing), size: textSize)
|
|
||||||
transition.updateFrameAdditive(node: self.textNode, frame: textFrame)
|
|
||||||
|
|
||||||
let minimalBottomInset: CGFloat = 60.0
|
let minimalBottomInset: CGFloat = 60.0
|
||||||
let bottomInset = layout.intrinsicInsets.bottom + max(minimalBottomInset, termsSize.height + termsSpacing * 2.0)
|
let bottomInset = layout.intrinsicInsets.bottom + max(minimalBottomInset, termsSize.height + termsSpacing * 2.0)
|
||||||
@ -740,12 +738,27 @@ private final class WalletSplashScreenNode: ViewControllerTracingNode {
|
|||||||
transition.updateFrame(node: self.buttonNode, frame: buttonFrame)
|
transition.updateFrame(node: self.buttonNode, frame: buttonFrame)
|
||||||
self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition)
|
self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition)
|
||||||
|
|
||||||
|
var maxContentVerticalOrigin = buttonFrame.minY - 12.0 - contentHeight
|
||||||
|
|
||||||
if !secondaryActionSize.width.isZero {
|
if !secondaryActionSize.width.isZero {
|
||||||
let secondaryActionFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - secondaryActionSize.width) / 2.0), y: buttonFrame.minY - 20.0 - secondaryActionSize.height), size: secondaryActionSize)
|
let secondaryActionFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - secondaryActionSize.width) / 2.0), y: buttonFrame.minY - 20.0 - secondaryActionSize.height), size: secondaryActionSize)
|
||||||
transition.updateFrameAdditive(node: self.secondaryActionTitleNode, frame: secondaryActionFrame)
|
transition.updateFrameAdditive(node: self.secondaryActionTitleNode, frame: secondaryActionFrame)
|
||||||
transition.updateFrame(node: self.secondaryActionButtonNode, frame: secondaryActionFrame.insetBy(dx: -10.0, dy: -10.0))
|
transition.updateFrame(node: self.secondaryActionButtonNode, frame: secondaryActionFrame.insetBy(dx: -10.0, dy: -10.0))
|
||||||
|
|
||||||
|
maxContentVerticalOrigin = secondaryActionFrame.minY - 12.0 - contentHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentVerticalOrigin = min(contentVerticalOrigin, maxContentVerticalOrigin)
|
||||||
|
|
||||||
|
let iconFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: contentVerticalOrigin), size: iconSize).offsetBy(dx: iconOffset.x, dy: iconOffset.y)
|
||||||
|
transition.updateFrameAdditive(node: self.iconNode, frame: iconFrame)
|
||||||
|
self.animationNode.updateLayout(size: iconFrame.size)
|
||||||
|
transition.updateFrameAdditive(node: self.animationNode, frame: iconFrame)
|
||||||
|
let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: iconFrame.maxY + iconSpacing), size: titleSize)
|
||||||
|
transition.updateFrameAdditive(node: self.titleNode, frame: titleFrame)
|
||||||
|
let textFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - textSize.width) / 2.0), y: titleFrame.maxY + titleSpacing), size: textSize)
|
||||||
|
transition.updateFrameAdditive(node: self.textNode, frame: textFrame)
|
||||||
|
|
||||||
let termsFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - termsSize.width) / 2.0), y: buttonFrame.maxY + floor((layout.size.height - layout.intrinsicInsets.bottom - buttonFrame.maxY - termsSize.height) / 2.0)), size: termsSize)
|
let termsFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - termsSize.width) / 2.0), y: buttonFrame.maxY + floor((layout.size.height - layout.intrinsicInsets.bottom - buttonFrame.maxY - termsSize.height) / 2.0)), size: termsSize)
|
||||||
transition.updateFrameAdditive(node: self.termsNode, frame: termsFrame)
|
transition.updateFrameAdditive(node: self.termsNode, frame: termsFrame)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user