diff --git a/submodules/AsyncDisplayKit/BUILD b/submodules/AsyncDisplayKit/BUILD index 6d054283b8..c7b86e3485 100644 --- a/submodules/AsyncDisplayKit/BUILD +++ b/submodules/AsyncDisplayKit/BUILD @@ -14,6 +14,9 @@ objc_library( "Source/**/*.m", "Source/**/*.mm", ]) + private_headers, + copts = [ + "-Werror", + ], hdrs = public_headers, defines = [ "MINIMAL_ASDK", diff --git a/submodules/AsyncDisplayKit/Source/ASDisplayNode.mm b/submodules/AsyncDisplayKit/Source/ASDisplayNode.mm index f17f390aff..29fe8db76b 100644 --- a/submodules/AsyncDisplayKit/Source/ASDisplayNode.mm +++ b/submodules/AsyncDisplayKit/Source/ASDisplayNode.mm @@ -68,6 +68,9 @@ static ASDisplayNodeNonFatalErrorBlock _nonFatalErrorBlock = nil; @end +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincomplete-implementation" + @implementation ASDisplayNode @dynamic layoutElementType; @@ -386,9 +389,12 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c) - (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" if (!(self = [self init])) { return nil; } +#pragma clang diagnostic pop [self setViewBlock:viewBlock]; if (didLoadBlock != nil) { @@ -405,9 +411,12 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c) - (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)layerBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" if (!(self = [self init])) { return nil; } +#pragma clang diagnostic pop [self setLayerBlock:layerBlock]; if (didLoadBlock != nil) { @@ -3816,3 +3825,5 @@ static const char *ASDisplayNodeAssociatedNodeKey = "ASAssociatedNode"; } @end + +#pragma clang diagnostic pop diff --git a/submodules/AsyncDisplayKit/Source/ASEditableTextNode.mm b/submodules/AsyncDisplayKit/Source/ASEditableTextNode.mm index fdd08f0929..984e293e31 100644 --- a/submodules/AsyncDisplayKit/Source/ASEditableTextNode.mm +++ b/submodules/AsyncDisplayKit/Source/ASEditableTextNode.mm @@ -687,7 +687,10 @@ } - (bool)isCurrentlyEmoji { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" NSString *value = [[UITextInputMode currentInputMode] primaryLanguage]; +#pragma clang diagnostic pop if ([value isEqualToString:@"emoji"]) { return true; } else { diff --git a/submodules/AsyncDisplayKit/Source/PublicHeaders/AsyncDisplayKit/ASDisplayNode+Subclasses.h b/submodules/AsyncDisplayKit/Source/PublicHeaders/AsyncDisplayKit/ASDisplayNode+Subclasses.h index 5ea0b2e6fe..8165b73087 100644 --- a/submodules/AsyncDisplayKit/Source/PublicHeaders/AsyncDisplayKit/ASDisplayNode+Subclasses.h +++ b/submodules/AsyncDisplayKit/Source/PublicHeaders/AsyncDisplayKit/ASDisplayNode+Subclasses.h @@ -133,7 +133,6 @@ AS_CATEGORY_IMPLEMENTABLE * @note This method should not be called directly outside of ASDisplayNode; use -layoutThatFits: or -calculatedLayout instead. */ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize; -- (CGSize)calculateSizeThatFits:(CGSize)contrainedSize; /** * ASDisplayNode's implementation of -layoutThatFits:parentSize: calls this method to resolve the node's size diff --git a/submodules/AsyncDisplayKit/Source/_ASAsyncTransaction.mm b/submodules/AsyncDisplayKit/Source/_ASAsyncTransaction.mm index c147f5f263..f8e0d9ca04 100644 --- a/submodules/AsyncDisplayKit/Source/_ASAsyncTransaction.mm +++ b/submodules/AsyncDisplayKit/Source/_ASAsyncTransaction.mm @@ -16,10 +16,6 @@ #import #import -#ifndef __STRICT_ANSI__ - #warning "Texture must be compiled with std=c++11 to prevent layout issues. gnu++ is not supported. This is hopefully temporary." -#endif - AS_EXTERN NSRunLoopMode const UITrackingRunLoopMode; NSInteger const ASDefaultTransactionPriority = 0; diff --git a/submodules/AsyncDisplayKit/Source/_ASDisplayViewAccessiblity.mm b/submodules/AsyncDisplayKit/Source/_ASDisplayViewAccessiblity.mm index b24e8e9f58..6e0b33541b 100644 --- a/submodules/AsyncDisplayKit/Source/_ASDisplayViewAccessiblity.mm +++ b/submodules/AsyncDisplayKit/Source/_ASDisplayViewAccessiblity.mm @@ -294,9 +294,7 @@ static void CollectAccessibilityElementsForView(UIView *view, NSMutableArray *el if (viewNode == nil) { return @[]; } - if (true || _accessibilityElements == nil) { - _accessibilityElements = [viewNode accessibilityElements]; - } + _accessibilityElements = [viewNode accessibilityElements]; return _accessibilityElements; } diff --git a/submodules/AsyncDisplayKit/Source/_ASPendingState.mm b/submodules/AsyncDisplayKit/Source/_ASPendingState.mm index 5bf75e50d1..39426df1d2 100644 --- a/submodules/AsyncDisplayKit/Source/_ASPendingState.mm +++ b/submodules/AsyncDisplayKit/Source/_ASPendingState.mm @@ -588,8 +588,8 @@ static UIColor *defaultTintColor = nil; _flags.setSemanticContentAttribute = YES; } -- (void)setAccessibilityCustomActions:(NSArray *)accessibilityCustomActions { - self->accessibilityCustomActions = accessibilityCustomActions; +- (void)setAccessibilityCustomActions:(NSArray *)accessibilityCustomActions_ { + self->accessibilityCustomActions = accessibilityCustomActions_; _flags.setAccessibilityCustomActions = YES; } diff --git a/submodules/AudioBlob/Sources/BlobView.swift b/submodules/AudioBlob/Sources/BlobView.swift index 64ade477e5..9bae6d2c5b 100644 --- a/submodules/AudioBlob/Sources/BlobView.swift +++ b/submodules/AudioBlob/Sources/BlobView.swift @@ -43,6 +43,9 @@ public final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDeco private let maxLevel: CGFloat private var displayLinkAnimator: ConstantDisplayLinkAnimator? + + private let hierarchyTrackingNode: HierarchyTrackingNode + private var isCurrentlyInHierarchy = true private var audioLevel: CGFloat = 0 public var presentationAudioLevel: CGFloat = 0 @@ -93,8 +96,15 @@ public final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDeco scaleSpeed: 0.2, isCircle: false ) + + var updateInHierarchy: ((Bool) -> Void)? + self.hierarchyTrackingNode = HierarchyTrackingNode({ value in + updateInHierarchy?(value) + }) super.init(frame: frame) + + self.addSubnode(self.hierarchyTrackingNode) self.addSubnode(self.bigBlob) self.addSubnode(self.mediumBlob) @@ -109,6 +119,12 @@ public final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDeco strongSelf.mediumBlob.level = strongSelf.presentationAudioLevel strongSelf.bigBlob.level = strongSelf.presentationAudioLevel } + + updateInHierarchy = { [weak self] value in + if let strongSelf = self { + strongSelf.isCurrentlyInHierarchy = value + } + } } required init?(coder: NSCoder) { @@ -266,6 +282,9 @@ final class BlobNode: ASDisplayNode { ) } } + + private let hierarchyTrackingNode: HierarchyTrackingNode + private var isCurrentlyInHierarchy = true init( pointsCount: Int, @@ -290,12 +309,24 @@ final class BlobNode: ASDisplayNode { let angle = (CGFloat.pi * 2) / CGFloat(pointsCount) self.smoothness = ((4 / 3) * tan(angle / 4)) / sin(angle / 2) / 2 + + var updateInHierarchy: ((Bool) -> Void)? + self.hierarchyTrackingNode = HierarchyTrackingNode({ value in + updateInHierarchy?(value) + }) super.init() - + + self.addSubnode(self.hierarchyTrackingNode) self.layer.addSublayer(self.shapeLayer) self.shapeLayer.transform = CATransform3DMakeScale(minScale, minScale, 1) + + updateInHierarchy = { [weak self] value in + if let strongSelf = self { + strongSelf.isCurrentlyInHierarchy = value + } + } } required init?(coder: NSCoder) { @@ -305,7 +336,7 @@ final class BlobNode: ASDisplayNode { func setColor(_ color: UIColor, animated: Bool) { let previousColor = self.shapeLayer.fillColor self.shapeLayer.fillColor = color.cgColor - if animated, let previousColor = previousColor { + if animated, let previousColor = previousColor, self.isCurrentlyInHierarchy { self.shapeLayer.animate(from: previousColor, to: color.cgColor, keyPath: "fillColor", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.3) } } diff --git a/submodules/BuildConfig/BUILD b/submodules/BuildConfig/BUILD index d3f9c56360..10c5c92dbb 100644 --- a/submodules/BuildConfig/BUILD +++ b/submodules/BuildConfig/BUILD @@ -17,6 +17,7 @@ objc_library( "Sources/*.m", ]), copts = [ + "-Werror", "-DAPP_CONFIG_API_ID={}".format(telegram_api_id), "-DAPP_CONFIG_API_HASH=\\\"{}\\\"".format(telegram_api_hash), "-DAPP_CONFIG_APP_CENTER_ID=\\\"{}\\\"".format(telegram_app_center_id), diff --git a/submodules/BuildConfig/PublicHeaders/BuildConfig/BuildConfig.h b/submodules/BuildConfig/PublicHeaders/BuildConfig/BuildConfig.h index 562a63ce27..d735dd74bc 100644 --- a/submodules/BuildConfig/PublicHeaders/BuildConfig/BuildConfig.h +++ b/submodules/BuildConfig/PublicHeaders/BuildConfig/BuildConfig.h @@ -22,8 +22,8 @@ + (DeviceSpecificEncryptionParameters * _Nonnull)deviceSpecificEncryptionParameters:(NSString * _Nonnull)rootPath baseAppBundleId:(NSString * _Nonnull)baseAppBundleId; - (NSData * _Nullable)bundleDataWithAppToken:(NSData * _Nullable)appToken signatureDict:(NSDictionary * _Nullable)signatureDict; -+ (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)decryptApplicationSecret:(NSData * _Nonnull)secret publicKey:(NSData * _Nonnull)publicKey baseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^)(NSData * _Nullable, bool))completion; ++ (void)getHardwareEncryptionAvailableWithBaseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^ _Nonnull)(NSData * _Nullable))completion; ++ (void)encryptApplicationSecret:(NSData * _Nonnull)secret baseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^ _Nonnull)(NSData * _Nullable, NSData * _Nullable))completion; ++ (void)decryptApplicationSecret:(NSData * _Nonnull)secret publicKey:(NSData * _Nonnull)publicKey baseAppBundleId:(NSString * _Nonnull)baseAppBundleId completion:(void (^ _Nonnull)(NSData * _Nullable, bool))completion; @end diff --git a/submodules/BuildConfig/Sources/BuildConfig.m b/submodules/BuildConfig/Sources/BuildConfig.m index a4a4cffa9e..3dde1749ae 100644 --- a/submodules/BuildConfig/Sources/BuildConfig.m +++ b/submodules/BuildConfig/Sources/BuildConfig.m @@ -207,7 +207,7 @@ API_AVAILABLE(ios(10)) return bundleSeedID; } -+ (NSString * _Nonnull)applicationSecretTag:(bool)isCheckKey { ++ (NSData * _Nullable)applicationSecretTag:(bool)isCheckKey { if (isCheckKey) { return [[telegramApplicationSecretKey stringByAppendingString:@"_check"] dataUsingEncoding:NSUTF8StringEncoding]; } else { @@ -349,7 +349,7 @@ API_AVAILABLE(ios(10)) CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent(); NSString *filePath = [rootPath stringByAppendingPathComponent:@".tempkey"]; - NSString *encryptedPath = [rootPath stringByAppendingPathComponent:@".tempkeyEncrypted"]; + //NSString *encryptedPath = [rootPath stringByAppendingPathComponent:@".tempkeyEncrypted"]; NSData *currentData = [NSData dataWithContentsOfFile:filePath]; NSData *resultData = nil; diff --git a/submodules/BuildConfigExtra/BUILD b/submodules/BuildConfigExtra/BUILD index 7e3972e6a0..fb403a5b73 100644 --- a/submodules/BuildConfigExtra/BUILD +++ b/submodules/BuildConfigExtra/BUILD @@ -7,6 +7,9 @@ objc_library( "Sources/**/*.m", "Sources/**/*.h", ]), + copts = [ + "-Werror", + ], hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/BuildConfigExtra/PublicHeaders/BuildConfigExtra/BuildConfigExtra.h b/submodules/BuildConfigExtra/PublicHeaders/BuildConfigExtra/BuildConfigExtra.h index bd4c629fa0..576a2e45e6 100644 --- a/submodules/BuildConfigExtra/PublicHeaders/BuildConfigExtra/BuildConfigExtra.h +++ b/submodules/BuildConfigExtra/PublicHeaders/BuildConfigExtra/BuildConfigExtra.h @@ -2,8 +2,6 @@ @interface BuildConfigExtra : NSObject -- (instancetype _Nonnull)initWithBaseAppBundleId:(NSString * _Nonnull)baseAppBundleId; - + (NSDictionary * _Nonnull)signatureDict; @end diff --git a/submodules/CloudData/BUILD b/submodules/CloudData/BUILD index 83da0d43aa..874cb8a64f 100644 --- a/submodules/CloudData/BUILD +++ b/submodules/CloudData/BUILD @@ -11,7 +11,6 @@ swift_library( ], deps = [ "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", - "//submodules/Postbox:Postbox", "//submodules/MtProtoKit:MtProtoKit", "//submodules/EncryptionProvider:EncryptionProvider", ], diff --git a/submodules/ComponentFlow/Source/Base/Transition.swift b/submodules/ComponentFlow/Source/Base/Transition.swift index f0187f4d08..a69a7bf576 100644 --- a/submodules/ComponentFlow/Source/Base/Transition.swift +++ b/submodules/ComponentFlow/Source/Base/Transition.swift @@ -192,6 +192,28 @@ public struct Transition { } } + public func setSublayerTransform(view: UIView, transform: CATransform3D, completion: ((Bool) -> Void)? = nil) { + switch self.animation { + case .none: + view.layer.sublayerTransform = transform + completion?(true) + case let .curve(duration, curve): + let previousValue = view.layer.sublayerTransform + view.layer.sublayerTransform = transform + view.layer.animate( + from: NSValue(caTransform3D: previousValue), + to: NSValue(caTransform3D: transform), + keyPath: "transform", + duration: duration, + delay: 0.0, + curve: curve, + removeOnCompletion: true, + additive: false, + completion: completion + ) + } + } + public func animateScale(view: UIView, from fromValue: CGFloat, to toValue: CGFloat, additive: Bool = false, completion: ((Bool) -> Void)? = nil) { switch self.animation { case .none: diff --git a/submodules/ComposePollUI/Sources/CreatePollController.swift b/submodules/ComposePollUI/Sources/CreatePollController.swift index 3a8e3eb8a4..cc5c5a3652 100644 --- a/submodules/ComposePollUI/Sources/CreatePollController.swift +++ b/submodules/ComposePollUI/Sources/CreatePollController.swift @@ -2,7 +2,6 @@ import Foundation import UIKit import Display import SwiftSignalKit -import Postbox import TelegramCore import TelegramPresentationData import ItemListUI @@ -11,6 +10,7 @@ import AccountContext import AlertUI import PresentationDataUtils import TextFormat +import Postbox private struct OrderedLinkedListItemOrderingId: RawRepresentable, Hashable { var rawValue: Int @@ -423,7 +423,7 @@ private struct CreatePollControllerState: Equatable { var isEditingSolution: Bool = false } -private func createPollControllerEntries(presentationData: PresentationData, peer: Peer, state: CreatePollControllerState, limitsConfiguration: LimitsConfiguration, defaultIsQuiz: Bool?) -> [CreatePollEntry] { +private func createPollControllerEntries(presentationData: PresentationData, peer: EnginePeer, state: CreatePollControllerState, limitsConfiguration: EngineConfiguration.Limits, defaultIsQuiz: Bool?) -> [CreatePollEntry] { var entries: [CreatePollEntry] = [] var textLimitText = ItemListSectionHeaderAccessoryText(value: "", color: .generic) @@ -453,7 +453,7 @@ private func createPollControllerEntries(presentationData: PresentationData, pee } var canBePublic = true - if let channel = peer as? TelegramChannel, case .broadcast = channel.info { + if case let .channel(channel) = peer, case .broadcast = channel.info { canBePublic = false } @@ -483,7 +483,7 @@ private func createPollControllerEntries(presentationData: PresentationData, pee return entries } -public func createPollController(context: AccountContext, peer: Peer, isQuiz: Bool? = nil, completion: @escaping (EnqueueMessage) -> Void) -> ViewController { +public func createPollController(context: AccountContext, peer: EnginePeer, isQuiz: Bool? = nil, completion: @escaping (EnqueueMessage) -> Void) -> ViewController { var initialState = CreatePollControllerState() if let isQuiz = isQuiz { initialState.isQuiz = isQuiz @@ -742,12 +742,13 @@ public func createPollController(context: AccountContext, peer: Peer, isQuiz: Bo }) let previousOptionIds = Atomic<[Int]?>(value: nil) - - let limitsKey = PostboxViewKey.preferences(keys: Set([PreferencesKeys.limitsConfiguration])) - let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, context.account.postbox.combinedView(keys: [limitsKey])) - |> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in - let limitsConfiguration: LimitsConfiguration = (combinedView.views[limitsKey] as? PreferencesView)?.values[PreferencesKeys.limitsConfiguration] as? LimitsConfiguration ?? LimitsConfiguration.defaultValue - + + let signal = combineLatest(queue: .mainQueue(), + context.sharedContext.presentationData, + statePromise.get(), + context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.Limits()) + ) + |> map { presentationData, state, limitsConfiguration -> (ItemListControllerState, (ItemListNodeState, Any)) in var enabled = true if processPollText(state.text).isEmpty { enabled = false diff --git a/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift b/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift index 1bbb8a5347..6cc80b5d17 100644 --- a/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift +++ b/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift @@ -291,7 +291,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode { switch wallpaper { case let .slug(slug, _, colors, intensity, angle): previewWallpaperFileReference = .message(message: MessageReference(item.message), media: file) - previewWallpaper = .file(id: file.fileId.id, accessHash: 0, isCreator: false, isDefault: false, isPattern: true, isDark: false, slug: slug, file: file, settings: WallpaperSettings(blur: false, motion: false, colors: colors, intensity: intensity, rotation: angle)) + previewWallpaper = .file(TelegramWallpaper.File(id: file.fileId.id, accessHash: 0, isCreator: false, isDefault: false, isPattern: true, isDark: false, slug: slug, file: file, settings: WallpaperSettings(blur: false, motion: false, colors: colors, intensity: intensity, rotation: angle))) default: break } diff --git a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTContext.h b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTContext.h index 9f687b8774..415f4f974f 100644 --- a/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTContext.h +++ b/submodules/MtProtoKit/PublicHeaders/MtProtoKit/MTContext.h @@ -56,6 +56,8 @@ + (MTQueue * _Nonnull)contextQueue; ++ (void)performWithObjCTry:(dispatch_block_t _Nonnull)block; + - (instancetype _Nonnull)initWithSerialization:(id _Nonnull)serialization encryptionProvider:(id _Nonnull)encryptionProvider apiEnvironment:(MTApiEnvironment * _Nonnull)apiEnvironment isTestingEnvironment:(bool)isTestingEnvironment useTempAuthKeys:(bool)useTempAuthKeys; - (void)performBatchUpdates:(void (^ _Nonnull)())block; diff --git a/submodules/MtProtoKit/Sources/MTContext.m b/submodules/MtProtoKit/Sources/MTContext.m index 8216fe97b7..7810572886 100644 --- a/submodules/MtProtoKit/Sources/MTContext.m +++ b/submodules/MtProtoKit/Sources/MTContext.m @@ -283,6 +283,13 @@ static int32_t fixedTimeDifferenceValue = 0; return queue; } ++ (void)performWithObjCTry:(dispatch_block_t _Nonnull)block { + @try { + block(); + } @finally { + } +} + - (void)cleanup { NSDictionary *datacenterAuthActions = _datacenterAuthActions; diff --git a/submodules/PasscodeUI/Sources/PasscodeEntryControllerNode.swift b/submodules/PasscodeUI/Sources/PasscodeEntryControllerNode.swift index 93cfd75f59..3d99089a0a 100644 --- a/submodules/PasscodeUI/Sources/PasscodeEntryControllerNode.swift +++ b/submodules/PasscodeUI/Sources/PasscodeEntryControllerNode.swift @@ -228,14 +228,14 @@ final class PasscodeEntryControllerNode: ASDisplayNode { color4 = baseColor.withMultiplied(hue: 1.034, saturation: 0.583, brightness: 1.043) } self.background = CustomPasscodeBackground(size: size, colors: [color1, color2, color3, color4], inverted: false) - case let .gradient(_, colors, settings): - self.background = CustomPasscodeBackground(size: size, colors: colors.compactMap { UIColor(rgb: $0) }, inverted: (settings.intensity ?? 0) < 0) + case let .gradient(gradient): + self.background = CustomPasscodeBackground(size: size, colors: gradient.colors.compactMap { UIColor(rgb: $0) }, inverted: (gradient.settings.intensity ?? 0) < 0) case .image, .file: if let image = chatControllerBackgroundImage(theme: self.theme, wallpaper: self.wallpaper, mediaBox: self.accountManager.mediaBox, composed: false, knockoutMode: false) { self.background = ImageBasedPasscodeBackground(image: image, size: size) } else { - if case let .file(_, _, _, _, _, _, _, _, settings) = self.wallpaper, !settings.colors.isEmpty { - self.background = CustomPasscodeBackground(size: size, colors: settings.colors.compactMap { UIColor(rgb: $0) }, inverted: (settings.intensity ?? 0) < 0) + if case let .file(file) = self.wallpaper, !file.settings.colors.isEmpty { + self.background = CustomPasscodeBackground(size: size, colors: file.settings.colors.compactMap { UIColor(rgb: $0) }, inverted: (file.settings.intensity ?? 0) < 0) } else { self.background = GradientPasscodeBackground(size: size, backgroundColors: self.theme.passcode.backgroundColors.colors, buttonColor: self.theme.passcode.buttonColor) } diff --git a/submodules/SettingsUI/BUILD b/submodules/SettingsUI/BUILD index 5a22cf2187..90dbf66c2a 100644 --- a/submodules/SettingsUI/BUILD +++ b/submodules/SettingsUI/BUILD @@ -6,6 +6,9 @@ swift_library( srcs = glob([ "Sources/**/*.swift", ]), + copts = [ + "-warnings-as-errors", + ], deps = [ "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit", diff --git a/submodules/SettingsUI/Sources/ChangePhoneNumberCodeController.swift b/submodules/SettingsUI/Sources/ChangePhoneNumberCodeController.swift index da25b216a6..f196db5ebc 100644 --- a/submodules/SettingsUI/Sources/ChangePhoneNumberCodeController.swift +++ b/submodules/SettingsUI/Sources/ChangePhoneNumberCodeController.swift @@ -88,13 +88,13 @@ private enum ChangePhoneNumberCodeEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! ChangePhoneNumberCodeControllerArguments switch self { - case let .codeEntry(theme, strings, title, text): + case let .codeEntry(_, _, title, text): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: title, textColor: .black), text: text, placeholder: "", type: .number, spacing: 10.0, tag: ChangePhoneNumberCodeTag.input, sectionId: self.section, textUpdated: { updatedText in arguments.updateEntryText(updatedText) }, action: { arguments.next() }) - case let .codeInfo(theme, text): + case let .codeInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } @@ -172,7 +172,7 @@ private func timeoutSignal(codeData: ChangeAccountPhoneNumberData) -> Signal ListViewItem { let arguments = arguments as! AutodownloadMediaConnectionTypeControllerArguments switch self { - case let .master(theme, text, value): + case let .master(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleMaster(value) }) - case let .dataUsageHeader(theme, text): + case let .dataUsageHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .dataUsageItem(theme, strings, value, customPosition, enabled): return AutodownloadDataUsagePickerItem(theme: theme, strings: strings, value: value, customPosition: customPosition, enabled: enabled, sectionId: self.section, updated: { preset in arguments.changePreset(preset) }) - case let .typesHeader(theme, text): + case let .typesHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .photos(theme, text, value, enabled): + case let .photos(_, text, value, enabled): return ItemListDisclosureItem(presentationData: presentationData, title: text, enabled: enabled, label: value, labelStyle: .detailText, sectionId: self.section, style: .blocks, action: { arguments.customize(.photo) }) - case let .videos(theme, text, value, enabled): + case let .videos(_, text, value, enabled): return ItemListDisclosureItem(presentationData: presentationData, title: text, enabled: enabled, label: value, labelStyle: .detailText, sectionId: self.section, style: .blocks, action: { arguments.customize(.video) }) - case let .files(theme, text, value, enabled): + case let .files(_, text, value, enabled): return ItemListDisclosureItem(presentationData: presentationData, title: text, enabled: enabled, label: value, labelStyle: .detailText, sectionId: self.section, style: .blocks, action: { arguments.customize(.file) }) - case let .voiceMessagesInfo(theme, text): + case let .voiceMessagesInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } @@ -278,7 +278,6 @@ private func autodownloadMediaConnectionTypeControllerEntries(presentationData: func autodownloadMediaConnectionTypeController(context: AccountContext, connectionType: AutomaticDownloadConnectionType) -> ViewController { var pushControllerImpl: ((ViewController) -> Void)? - var presentControllerImpl: ((ViewController) -> Void)? let arguments = AutodownloadMediaConnectionTypeControllerArguments(toggleMaster: { value in let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in @@ -356,8 +355,5 @@ func autodownloadMediaConnectionTypeController(context: AccountContext, connecti (controller.navigationController as? NavigationController)?.pushViewController(c) } } - presentControllerImpl = { [weak controller] c in - controller?.present(c, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) - } return controller } diff --git a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift index d9432a7a70..fa1918458e 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift @@ -311,49 +311,49 @@ private enum DataAndStorageEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! DataAndStorageControllerArguments switch self { - case let .storageUsage(theme, text): + case let .storageUsage(_, text): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: { arguments.openStorageUsage() }) - case let .networkUsage(theme, text): + case let .networkUsage(_, text): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: { arguments.openNetworkUsage() }) - case let .automaticDownloadHeader(theme, text): + case let .automaticDownloadHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .automaticDownloadCellular(theme, text, value): + case let .automaticDownloadCellular(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, labelStyle: .detailText, sectionId: self.section, style: .blocks, action: { arguments.openAutomaticDownloadConnectionType(.cellular) }) - case let .automaticDownloadWifi(theme, text, value): + case let .automaticDownloadWifi(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, labelStyle: .detailText, sectionId: self.section, style: .blocks, action: { arguments.openAutomaticDownloadConnectionType(.wifi) }) - case let .automaticDownloadReset(theme, text, enabled): + case let .automaticDownloadReset(_, text, enabled): return ItemListActionItem(presentationData: presentationData, title: text, kind: enabled ? .generic : .disabled, alignment: .natural, sectionId: self.section, style: .blocks, action: { if enabled { arguments.resetAutomaticDownload() } }, tag: DataAndStorageEntryTag.automaticDownloadReset) - case let .autoplayHeader(theme, text): + case let .autoplayHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .autoplayGifs(theme, text, value): + case let .autoplayGifs(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleAutoplayGifs(value) }, tag: DataAndStorageEntryTag.autoplayGifs) - case let .autoplayVideos(theme, text, value): + case let .autoplayVideos(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleAutoplayVideos(value) }, tag: DataAndStorageEntryTag.autoplayVideos) - case let .voiceCallsHeader(theme, text): + case let .voiceCallsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .useLessVoiceData(theme, text, value): + case let .useLessVoiceData(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openVoiceUseLessData() }) - case let .otherHeader(theme, text): + case let .otherHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .shareSheet(theme, text): + case let .shareSheet(_, text): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: { arguments.openIntents() }) @@ -361,27 +361,27 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: { arguments.openWidgetSettings() }) - case let .saveIncomingPhotos(theme, text): + case let .saveIncomingPhotos(_, text): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: { arguments.openSaveIncomingPhotos() }) - case let .saveEditedPhotos(theme, text, value): + case let .saveEditedPhotos(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleSaveEditedPhotos(value) }, tag: DataAndStorageEntryTag.saveEditedPhotos) - case let .openLinksIn(theme, text, value): + case let .openLinksIn(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openBrowserSelection() }) - case let .downloadInBackground(theme, text, value): + case let .downloadInBackground(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleDownloadInBackground(value) }, tag: DataAndStorageEntryTag.downloadInBackground) - case let .downloadInBackgroundInfo(theme, text): + case let .downloadInBackgroundInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .connectionHeader(theme, text): + case let .connectionHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .connectionProxy(theme, text, value): + case let .connectionProxy(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openProxy() }) diff --git a/submodules/SettingsUI/Sources/Data and Storage/IntentsSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/IntentsSettingsController.swift index 249c510aea..755b4e3860 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/IntentsSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/IntentsSettingsController.swift @@ -184,47 +184,46 @@ private enum IntentsSettingsControllerEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! IntentsSettingsControllerArguments switch self { - case let .accountHeader(theme, text): + case let .accountHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .account(theme, peer, selected, _): + case let .account(_, peer, selected, _): return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(), nameDisplayOrder: .firstLast, context: arguments.context.sharedContext.makeTempAccountContext(account: arguments.context.account), peer: peer, height: .generic, aliasHandling: .standard, nameStyle: .plain, presence: nil, text: .none, label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: false), revealOptions: nil, switchValue: ItemListPeerItemSwitch(value: selected, style: .check), enabled: true, selectable: true, sectionId: self.section, action: { arguments.updateSettings { $0.withUpdatedAccount(peer.id) } }, setPeerIdWithRevealedOptions: { _, _ in}, removePeer: { _ in }) - return ItemListTextItem(presentationData: presentationData, text: .plain(""), sectionId: self.section) - case let .accountInfo(theme, text): + case let .accountInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .chatsHeader(theme, text): + case let .chatsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .contacts(theme, text, value): + case let .contacts(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.updateSettings { $0.withUpdatedContacts(value) } }) - case let .savedMessages(theme, text, value): + case let .savedMessages(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.updateSettings { $0.withUpdatedSavedMessages(value) } }) - case let .privateChats(theme, text, value): + case let .privateChats(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.updateSettings { $0.withUpdatedPrivateChats(value) } }) - case let .groups(theme, text, value): + case let .groups(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.updateSettings { $0.withUpdatedGroups(value) } }) - case let .chatsInfo(theme, text): + case let .chatsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .suggestHeader(theme, text): + case let .suggestHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .suggestAll(theme, text, value): + case let .suggestAll(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateSettings { $0.withUpdatedOnlyShared(false) } }) - case let .suggestOnlyShared(theme, text, value): + case let .suggestOnlyShared(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateSettings { $0.withUpdatedOnlyShared(true) } }) - case let .resetAll(theme, text): + case let .resetAll(_, text): return ItemListActionItem(presentationData: presentationData, title: text, kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.resetAll() }) @@ -263,16 +262,13 @@ private func intentsSettingsControllerEntries(context: AccountContext, presentat } public func intentsSettingsController(context: AccountContext) -> ViewController { - var pushControllerImpl: ((ViewController) -> Void)? var presentControllerImpl: ((ViewController) -> Void)? - - let updateDisposable = MetaDisposable() + let arguments = IntentsSettingsControllerArguments(context: context, updateSettings: { f in let _ = updateIntentsSettingsInteractively(accountManager: context.sharedContext.accountManager, f).start(next: { previous, updated in guard let previous = previous, let updated = updated else { return } - let accountPeerId = context.account.peerId if previous.contacts && !updated.contacts { deleteAllSendMessageIntents() } @@ -285,7 +281,7 @@ public func intentsSettingsController(context: AccountContext) -> ViewController if previous.groups && !updated.groups { deleteAllSendMessageIntents() } - if previous.account != updated.account, let previousAccount = previous.account { + if previous.account != updated.account, let _ = previous.account { deleteAllSendMessageIntents() } }) @@ -318,9 +314,6 @@ public func intentsSettingsController(context: AccountContext) -> ViewController } let controller = ItemListController(context: context, state: signal) - pushControllerImpl = { [weak controller] c in - (controller?.navigationController as? NavigationController)?.pushViewController(c) - } presentControllerImpl = { [weak controller] c in controller?.present(c, in: .window(.root)) } diff --git a/submodules/SettingsUI/Sources/Data and Storage/KeepMediaDurationPickerItem.swift b/submodules/SettingsUI/Sources/Data and Storage/KeepMediaDurationPickerItem.swift index 575a85d06c..871357d4b5 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/KeepMediaDurationPickerItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/KeepMediaDurationPickerItem.swift @@ -108,7 +108,7 @@ private final class KeepMediaDurationPickerItemNode: ListViewItemNode { self.maskNode = ASImageNode() var textNodes: [TextNode] = [] - for i in 0 ..< 4 { + for _ in 0 ..< 4 { let textNode = TextNode() textNode.isUserInteractionEnabled = false textNode.displaysAsynchronously = false diff --git a/submodules/SettingsUI/Sources/Data and Storage/MaximumCacheSizePickerItem.swift b/submodules/SettingsUI/Sources/Data and Storage/MaximumCacheSizePickerItem.swift index 1b7f603eb2..9c072c596d 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/MaximumCacheSizePickerItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/MaximumCacheSizePickerItem.swift @@ -123,7 +123,7 @@ private final class MaximumCacheSizePickerItemNode: ListViewItemNode { self.maskNode = ASImageNode() var textNodes: [TextNode] = [] - for i in 0 ..< 4 { + for _ in 0 ..< 4 { let textNode = TextNode() textNode.isUserInteractionEnabled = false textNode.displaysAsynchronously = false diff --git a/submodules/SettingsUI/Sources/Data and Storage/ProxyListSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/ProxyListSettingsController.swift index eb26e53988..014cdfdbad 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/ProxyListSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/ProxyListSettingsController.swift @@ -200,7 +200,7 @@ private enum ProxySettingsControllerEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! ProxySettingsControllerArguments switch self { - case let .enabled(theme, text, value, createsNew): + case let .enabled(_, text, value, createsNew): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: !createsNew, enabled: true, sectionId: self.section, style: .blocks, updated: { value in if createsNew { arguments.addNewServer() @@ -208,9 +208,9 @@ private enum ProxySettingsControllerEntry: ItemListNodeEntry { arguments.toggleEnabled(value) } }) - case let .serversHeader(theme, text): + case let .serversHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .addServer(theme, text, _): + case let .addServer(_, text, _): return ProxySettingsActionItem(presentationData: presentationData, title: text, icon: .add, sectionId: self.section, editing: false, action: { arguments.addNewServer() }) @@ -224,15 +224,15 @@ private enum ProxySettingsControllerEntry: ItemListNodeEntry { }, removeServer: { _ in arguments.removeServer(settings) }) - case let .shareProxyList(theme, text): + case let .shareProxyList(_, text): return ProxySettingsActionItem(presentationData: presentationData, title: text, sectionId: self.section, editing: false, action: { arguments.shareProxyList() }) - case let .useForCalls(theme, text, value): + case let .useForCalls(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleUseForCalls(value) }) - case let .useForCallsInfo(theme, text): + case let .useForCallsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } @@ -314,7 +314,6 @@ public func proxySettingsController(context: AccountContext, mode: ProxySettings } public func proxySettingsController(accountManager: AccountManager, context: AccountContext? = nil, postbox: Postbox, network: Network, mode: ProxySettingsControllerMode, presentationData: PresentationData, updatedPresentationData: Signal) -> ViewController { - var presentControllerImpl: ((ViewController, Any?) -> Void)? var pushControllerImpl: ((ViewController) -> Void)? var dismissImpl: (() -> Void)? let stateValue = Atomic(value: ProxySettingsControllerState()) @@ -439,9 +438,6 @@ public func proxySettingsController(accountManager: AccountManager, context: Acc let controller = ItemListController(presentationData: ItemListPresentationData(presentationData), updatedPresentationData: updatedPresentationData |> map(ItemListPresentationData.init(_:)), state: signal, tabBarItem: nil) controller.navigationPresentation = .modal - presentControllerImpl = { [weak controller] c, a in - controller?.present(c, in: .window(.root), with: a) - } pushControllerImpl = { [weak controller] c in (controller?.navigationController as? NavigationController)?.pushViewController(c) } diff --git a/submodules/SettingsUI/Sources/Data and Storage/ProxyServerActionSheetController.swift b/submodules/SettingsUI/Sources/Data and Storage/ProxyServerActionSheetController.swift index 2da448a17a..1b56234871 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/ProxyServerActionSheetController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/ProxyServerActionSheetController.swift @@ -376,7 +376,7 @@ private final class ProxyServerActionItemNode: ActionSheetItemNode { let proxyServerSettings = self.server let _ = (self.accountManager.transaction { transaction -> ProxySettings in var currentSettings: ProxySettings? - updateProxySettingsInteractively(transaction: transaction, { settings in + let _ = updateProxySettingsInteractively(transaction: transaction, { settings in currentSettings = settings var settings = settings if let index = settings.servers.firstIndex(of: proxyServerSettings) { diff --git a/submodules/SettingsUI/Sources/Data and Storage/ProxyServerSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/ProxyServerSettingsController.swift index 10257c7264..5ebc2a616f 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/ProxyServerSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/ProxyServerSettingsController.swift @@ -116,13 +116,13 @@ private enum ProxySettingsEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! proxyServerSettingsControllerArguments switch self { - case let .usePasteboardSettings(theme, title): + case let .usePasteboardSettings(_, title): return ItemListActionItem(presentationData: presentationData, title: title, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.usePasteboardSettings() }) - case let .usePasteboardInfo(theme, text): + case let .usePasteboardInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .modeSocks5(theme, text, value): + case let .modeSocks5(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateState { state in var state = state @@ -130,7 +130,7 @@ private enum ProxySettingsEntry: ItemListNodeEntry { return state } }) - case let .modeMtp(theme, text, value): + case let .modeMtp(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateState { state in var state = state @@ -138,9 +138,9 @@ private enum ProxySettingsEntry: ItemListNodeEntry { return state } }) - case let .connectionHeader(theme, text): + case let .connectionHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .connectionServer(theme, strings, placeholder, text): + case let .connectionServer(_, _, placeholder, text): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: text, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: false), sectionId: self.section, textUpdated: { value in arguments.updateState { current in var state = current @@ -148,7 +148,7 @@ private enum ProxySettingsEntry: ItemListNodeEntry { return state } }, action: {}) - case let .connectionPort(theme, strings, placeholder, text): + case let .connectionPort(_, _, placeholder, text): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: text, placeholder: placeholder, type: .number, sectionId: self.section, textUpdated: { value in arguments.updateState { current in var state = current @@ -156,9 +156,9 @@ private enum ProxySettingsEntry: ItemListNodeEntry { return state } }, action: {}) - case let .credentialsHeader(theme, text): + case let .credentialsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .credentialsUsername(theme, strings, placeholder, text): + case let .credentialsUsername(_, _, placeholder, text): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: text, placeholder: placeholder, sectionId: self.section, textUpdated: { value in arguments.updateState { current in var state = current @@ -166,7 +166,7 @@ private enum ProxySettingsEntry: ItemListNodeEntry { return state } }, action: {}) - case let .credentialsPassword(theme, strings, placeholder, text): + case let .credentialsPassword(_, _, placeholder, text): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: text, placeholder: placeholder, type: .password, sectionId: self.section, textUpdated: { value in arguments.updateState { current in var state = current @@ -174,7 +174,7 @@ private enum ProxySettingsEntry: ItemListNodeEntry { return state } }, action: {}) - case let .credentialsSecret(theme, strings, placeholder, text): + case let .credentialsSecret(_, _, placeholder, text): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: text, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: false), sectionId: self.section, textUpdated: { value in arguments.updateState { current in var state = current @@ -182,7 +182,7 @@ private enum ProxySettingsEntry: ItemListNodeEntry { return state } }, action: {}) - case let .share(theme, text, enabled): + case let .share(_, text, enabled): return ItemListActionItem(presentationData: presentationData, title: text, kind: enabled ? .generic : .disabled, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.share() }) diff --git a/submodules/SettingsUI/Sources/Data and Storage/SaveIncomingMediaController.swift b/submodules/SettingsUI/Sources/Data and Storage/SaveIncomingMediaController.swift index be37e859fd..b06e56bfb9 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/SaveIncomingMediaController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/SaveIncomingMediaController.swift @@ -62,21 +62,21 @@ private enum SaveIncomingMediaEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! SaveIncomingMediaControllerArguments switch self { - case let .header(theme, text): + case let .header(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .contacts(theme, text, value): + case let .contacts(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.toggle(.contact) }) - case let .otherPrivate(theme, text, value): + case let .otherPrivate(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.toggle(.otherPrivate) }) - case let .groups(theme, text, value): + case let .groups(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.toggle(.group) }) - case let .channels(theme, text, value): + case let .channels(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in arguments.toggle(.channel) }) diff --git a/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift b/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift index f3cdb336b6..b5d0018ab7 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift @@ -230,7 +230,7 @@ private enum StorageUsageEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! StorageUsageControllerArguments switch self { - case let .keepMediaHeader(theme, text): + case let .keepMediaHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .keepMedia(theme, strings, value): return KeepMediaDurationPickerItem(theme: theme, strings: strings, value: value, sectionId: self.section, updated: { updatedValue in diff --git a/submodules/SettingsUI/Sources/Data and Storage/VoiceCallDataSavingController.swift b/submodules/SettingsUI/Sources/Data and Storage/VoiceCallDataSavingController.swift index 9144bd3b83..fe684bb32e 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/VoiceCallDataSavingController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/VoiceCallDataSavingController.swift @@ -81,19 +81,19 @@ private enum VoiceCallDataSavingEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! VoiceCallDataSavingControllerArguments switch self { - case let .never(theme, text, value): + case let .never(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateSelection(.never) }) - case let .cellular(theme, text, value): + case let .cellular(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateSelection(.cellular) }) - case let .always(theme, text, value): + case let .always(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateSelection(.always) }) - case let .info(theme, text): + case let .info(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } diff --git a/submodules/SettingsUI/Sources/Data and Storage/WebBrowserItem.swift b/submodules/SettingsUI/Sources/Data and Storage/WebBrowserItem.swift index 4c07fd94de..62e0eb33a0 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/WebBrowserItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/WebBrowserItem.swift @@ -133,7 +133,7 @@ private final class WebBrowserItemNode: ListViewItemNode { let currentItem = self.item return { item, params, neighbors in - var leftInset: CGFloat = params.leftInset + 16.0 + 43.0 + let leftInset: CGFloat = params.leftInset + 16.0 + 43.0 let iconSize = CGSize(width: 29.0, height: 29.0) let arguments = TransformImageArguments(corners: ImageCorners(radius: 5.0), imageSize: iconSize, boundingSize: iconSize, intrinsicInsets: UIEdgeInsets(), emptyColor: item.presentationData.theme.list.mediaPlaceholderColor) diff --git a/submodules/SettingsUI/Sources/Data and Storage/WebBrowserSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/WebBrowserSettingsController.swift index 5b7a1d76c6..02ee92d985 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/WebBrowserSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/WebBrowserSettingsController.swift @@ -68,9 +68,9 @@ private enum WebBrowserSettingsControllerEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! WebBrowserSettingsControllerArguments switch self { - case let .browserHeader(theme, text): + case let .browserHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .browser(theme, title, application, identifier, selected, _): + case let .browser(_, title, application, identifier, selected, _): return WebBrowserItem(account: arguments.context.account, presentationData: presentationData, title: title, application: application, checked: selected, sectionId: self.section) { arguments.updateDefaultBrowser(identifier) } @@ -96,10 +96,6 @@ private func webBrowserSettingsControllerEntries(context: AccountContext, presen } public func webBrowserSettingsController(context: AccountContext) -> ViewController { - var pushControllerImpl: ((ViewController) -> Void)? - var presentControllerImpl: ((ViewController) -> Void)? - - let updateDisposable = MetaDisposable() let arguments = WebBrowserSettingsControllerArguments(context: context, updateDefaultBrowser: { identifier in let _ = updateWebBrowserSettingsInteractively(accountManager: context.sharedContext.accountManager, { $0.withUpdatedDefaultWebBrowser(identifier) }).start() }) @@ -116,11 +112,5 @@ public func webBrowserSettingsController(context: AccountContext) -> ViewControl } let controller = ItemListController(context: context, state: signal) - pushControllerImpl = { [weak controller] c in - (controller?.navigationController as? NavigationController)?.pushViewController(c) - } - presentControllerImpl = { [weak controller] c in - controller?.present(c, in: .window(.root)) - } return controller } diff --git a/submodules/SettingsUI/Sources/LogoutOptionsController.swift b/submodules/SettingsUI/Sources/LogoutOptionsController.swift index 737a864dda..6134bfd35c 100644 --- a/submodules/SettingsUI/Sources/LogoutOptionsController.swift +++ b/submodules/SettingsUI/Sources/LogoutOptionsController.swift @@ -75,33 +75,33 @@ private enum LogoutOptionsEntry: ItemListNodeEntry, Equatable { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! LogoutOptionsItemArguments switch self { - case let .alternativeHeader(theme, title): + case let .alternativeHeader(_, title): return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section) - case let .addAccount(theme, title, text): + case let .addAccount(_, title, text): return ItemListDisclosureItem(presentationData: presentationData, icon: PresentationResourcesSettings.addAccount, title: title, label: text, labelStyle: .multilineDetailText, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: { arguments.addAccount() }) - case let .setPasscode(theme, title, text): + case let .setPasscode(_, title, text): return ItemListDisclosureItem(presentationData: presentationData, icon: PresentationResourcesSettings.setPasscode, title: title, label: text, labelStyle: .multilineDetailText, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: { arguments.setPasscode() }) - case let .clearCache(theme, title, text): + case let .clearCache(_, title, text): return ItemListDisclosureItem(presentationData: presentationData, icon: PresentationResourcesSettings.clearCache, title: title, label: text, labelStyle: .multilineDetailText, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: { arguments.clearCache() }) - case let .changePhoneNumber(theme, title, text): + case let .changePhoneNumber(_, title, text): return ItemListDisclosureItem(presentationData: presentationData, icon: PresentationResourcesSettings.changePhoneNumber, title: title, label: text, labelStyle: .multilineDetailText, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: { arguments.changePhoneNumber() }) - case let .contactSupport(theme, title, text): + case let .contactSupport(_, title, text): return ItemListDisclosureItem(presentationData: presentationData, icon: PresentationResourcesSettings.support, title: title, label: text, labelStyle: .multilineDetailText, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: { arguments.contactSupport() }) - case let .logout(theme, title): + case let .logout(_, title): return ItemListActionItem(presentationData: presentationData, title: title, kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.logout() }) - case let .logoutInfo(theme, title): + case let .logoutInfo(_, title): return ItemListTextItem(presentationData: presentationData, text: .plain(title), sectionId: self.section) } } diff --git a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift index 2186263bdb..27e56d5f88 100644 --- a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift +++ b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift @@ -529,7 +529,7 @@ private enum NotificationExceptionEntry : ItemListNodeEntry { return ItemListPeerActionItem(presentationData: presentationData, icon: icon, title: strings.Notification_Exceptions_AddException, alwaysPlain: true, sectionId: self.section, editing: editing, action: { arguments.selectPeer() }) - case let .peer(_, peer, theme, strings, dateTimeFormat, nameDisplayOrder, value, _, revealed, editing, isSearching): + case let .peer(_, peer, _, _, dateTimeFormat, nameDisplayOrder, value, _, revealed, editing, isSearching): return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer, presence: nil, text: .text(value, .secondary), label: .none, editing: ItemListPeerItemEditing(editable: true, editing: editing, revealed: revealed), switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: { arguments.openPeer(peer) }, setPeerIdWithRevealedOptions: { peerId, fromPeerId in @@ -542,7 +542,7 @@ private enum NotificationExceptionEntry : ItemListNodeEntry { arguments.openPeer(peer) }, setPeerIdWithRevealedOptions: { _, _ in }) - case let .removeAll(theme, strings): + case let .removeAll(_, strings): return ItemListActionItem(presentationData: presentationData, title: strings.Notification_Exceptions_DeleteAll, kind: .destructive, alignment: .center, sectionId: self.section, style: .blocks, action: { arguments.removeAll() }) diff --git a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionSettingsController.swift b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionSettingsController.swift index 9e6c9ab6cb..9638dd5ef2 100644 --- a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionSettingsController.swift +++ b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionSettingsController.swift @@ -37,9 +37,9 @@ private enum NotificationPeerExceptionEntryId : Hashable { case soundClassicHeader case none case `default` - - var hashValue: Int { - return 0 + + func hash(into hasher: inout Hasher) { + hasher.combine(0) } } diff --git a/submodules/SettingsUI/Sources/Notifications/NotificationsAndSounds.swift b/submodules/SettingsUI/Sources/Notifications/NotificationsAndSounds.swift index c755e29656..27412b4a81 100644 --- a/submodules/SettingsUI/Sources/Notifications/NotificationsAndSounds.swift +++ b/submodules/SettingsUI/Sources/Notifications/NotificationsAndSounds.swift @@ -584,142 +584,142 @@ private enum NotificationsAndSoundsEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! NotificationsAndSoundsArguments switch self { - case let .accountsHeader(theme, text): + case let .accountsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .allAccounts(theme, text, value): + case let .allAccounts(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateNotificationsFromAllAccounts(updatedValue) }, tag: self.tag) - case let .accountsInfo(theme, text): + case let .accountsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .permissionInfo(theme, title, text, suppressed): + case let .permissionInfo(_, title, text, suppressed): return ItemListInfoItem(presentationData: presentationData, title: title, text: .plain(text), style: .blocks, sectionId: self.section, closeAction: suppressed ? nil : { arguments.suppressWarning() }) - case let .permissionEnable(theme, text): + case let .permissionEnable(_, text): return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.authorizeNotifications() }) - case let .messageHeader(theme, text): + case let .messageHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .messageAlerts(theme, text, value): + case let .messageAlerts(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateMessageAlerts(updatedValue) }, tag: self.tag) - case let .messagePreviews(theme, text, value): + case let .messagePreviews(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateMessagePreviews(updatedValue) }, tag: self.tag) - case let .messageSound(theme, text, value, sound): + case let .messageSound(_, text, value, sound): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { let controller = notificationSoundSelectionController(context: arguments.context, isModal: true, currentSound: sound, defaultSound: nil, completion: { [weak arguments] value in arguments?.updateMessageSound(value) }) arguments.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) }) - case let .userExceptions(theme, strings, text, value): + case let .userExceptions(_, strings, text, value): let label = value.settings.count > 0 ? strings.Notifications_Exceptions(Int32(value.settings.count)) : strings.Notification_Exceptions_Add return ItemListDisclosureItem(presentationData: presentationData, title: text, label: label, sectionId: self.section, style: .blocks, action: { let controller = NotificationExceptionsController(context: arguments.context, mode: value, updatedMode: arguments.updatedExceptionMode) arguments.pushController(controller) }) - case let .messageNotice(theme, text): + case let .messageNotice(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .groupHeader(theme, text): + case let .groupHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .groupAlerts(theme, text, value): + case let .groupAlerts(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateGroupAlerts(updatedValue) }, tag: self.tag) - case let .groupPreviews(theme, text, value): + case let .groupPreviews(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateGroupPreviews(updatedValue) }, tag: self.tag) - case let .groupSound(theme, text, value, sound): + case let .groupSound(_, text, value, sound): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { let controller = notificationSoundSelectionController(context: arguments.context, isModal: true, currentSound: sound, defaultSound: nil, completion: { [weak arguments] value in arguments?.updateGroupSound(value) }) arguments.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) }) - case let .groupExceptions(theme, strings, text, value): + case let .groupExceptions(_, strings, text, value): let label = value.settings.count > 0 ? strings.Notifications_Exceptions(Int32(value.settings.count)) : strings.Notification_Exceptions_Add return ItemListDisclosureItem(presentationData: presentationData, title: text, label: label, sectionId: self.section, style: .blocks, action: { let controller = NotificationExceptionsController(context: arguments.context, mode: value, updatedMode: arguments.updatedExceptionMode) arguments.pushController(controller) }) - case let .groupNotice(theme, text): + case let .groupNotice(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .channelHeader(theme, text): + case let .channelHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .channelAlerts(theme, text, value): + case let .channelAlerts(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateChannelAlerts(updatedValue) }, tag: self.tag) - case let .channelPreviews(theme, text, value): + case let .channelPreviews(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateChannelPreviews(updatedValue) }, tag: self.tag) - case let .channelSound(theme, text, value, sound): + case let .channelSound(_, text, value, sound): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { let controller = notificationSoundSelectionController(context: arguments.context, isModal: true, currentSound: sound, defaultSound: nil, completion: { [weak arguments] value in arguments?.updateChannelSound(value) }) arguments.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) }) - case let .channelExceptions(theme, strings, text, value): + case let .channelExceptions(_, strings, text, value): let label = value.settings.count > 0 ? strings.Notifications_Exceptions(Int32(value.settings.count)) : strings.Notification_Exceptions_Add return ItemListDisclosureItem(presentationData: presentationData, title: text, label: label, sectionId: self.section, style: .blocks, action: { let controller = NotificationExceptionsController(context: arguments.context, mode: value, updatedMode: arguments.updatedExceptionMode) arguments.pushController(controller) }) - case let .channelNotice(theme, text): + case let .channelNotice(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .inAppHeader(theme, text): + case let .inAppHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .inAppSounds(theme, text, value): + case let .inAppSounds(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateInAppSounds(updatedValue) }, tag: self.tag) - case let .inAppVibrate(theme, text, value): + case let .inAppVibrate(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateInAppVibration(updatedValue) }, tag: self.tag) - case let .inAppPreviews(theme, text, value): + case let .inAppPreviews(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateInAppPreviews(updatedValue) }, tag: self.tag) - case let .displayNamesOnLockscreen(theme, text, value): + case let .displayNamesOnLockscreen(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateDisplayNameOnLockscreen(updatedValue) }, tag: self.tag) - case let .displayNamesOnLockscreenInfo(theme, text): + case let .displayNamesOnLockscreenInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .markdown(text.replacingOccurrences(of: "]", with: "]()")), sectionId: self.section, linkAction: { _ in arguments.openAppSettings() }) - case let .badgeHeader(theme, text): + case let .badgeHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .includeChannels(theme, text, value): + case let .includeChannels(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateIncludeTag(.channels, updatedValue) }, tag: self.tag) - case let .unreadCountCategory(theme, text, value): + case let .unreadCountCategory(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateTotalUnreadCountCategory(updatedValue) }, tag: self.tag) - case let .unreadCountCategoryInfo(theme, text): + case let .unreadCountCategoryInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .joinedNotifications(theme, text, value): + case let .joinedNotifications(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateJoinedNotifications(updatedValue) }, tag: self.tag) - case let .joinedNotificationsInfo(theme, text): + case let .joinedNotificationsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .reset(theme, text): + case let .reset(_, text): return ItemListActionItem(presentationData: presentationData, title: text, kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.resetNotifications() }, tag: self.tag) - case let .resetNotice(theme, text): + case let .resetNotice(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } diff --git a/submodules/SettingsUI/Sources/Privacy and Security/BlockedPeersController.swift b/submodules/SettingsUI/Sources/Privacy and Security/BlockedPeersController.swift index dec04096e9..5f9322d222 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/BlockedPeersController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/BlockedPeersController.swift @@ -211,7 +211,6 @@ public func blockedPeersController(context: AccountContext, blockedPeersContext: } var pushControllerImpl: ((ViewController) -> Void)? - var presentControllerImpl: ((ViewController, Any?) -> Void)? let actionsDisposable = DisposableSet() @@ -312,11 +311,6 @@ public func blockedPeersController(context: AccountContext, blockedPeersContext: (controller.navigationController as? NavigationController)?.pushViewController(c) } } - presentControllerImpl = { [weak controller] c, a in - if let controller = controller { - controller.present(c, in: .window(.root), with: a) - } - } controller.visibleBottomContentOffsetChanged = { offset in if case let .known(value) = offset, value < 40.0 { blockedPeersContext.loadMore() diff --git a/submodules/SettingsUI/Sources/Privacy and Security/ConfirmPhoneNumberController.swift b/submodules/SettingsUI/Sources/Privacy and Security/ConfirmPhoneNumberController.swift index 9de89ca41a..1cc0b8723b 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/ConfirmPhoneNumberController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/ConfirmPhoneNumberController.swift @@ -87,13 +87,13 @@ private enum ConfirmPhoneNumberCodeEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! ConfirmPhoneNumberCodeControllerArguments switch self { - case let .codeEntry(theme, strings, title, text): + case let .codeEntry(_, _, title, text): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: title, textColor: .black), text: text, placeholder: "", type: .number, spacing: 10.0, tag: ConfirmPhoneNumberCodeTag.input, sectionId: self.section, textUpdated: { updatedText in arguments.updateEntryText(updatedText) }, action: { arguments.next() }) - case let .codeInfo(theme, strings, phoneNumber, nextOptionText): + case let .codeInfo(_, strings, phoneNumber, nextOptionText): let formattedNumber = formatPhoneNumber(phoneNumber) let stringAndRanges = strings.CancelResetAccount_TextSMS(formattedNumber) var result = "" @@ -157,7 +157,7 @@ private func timeoutSignal(codeData: CancelAccountResetData) -> Signal ListViewItem { let arguments = arguments as! CreatePasswordControllerArguments switch self { - case let .passwordHeader(theme, text): + case let .passwordHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .password(theme, strings, text, value): + case let .password(_, _, text, value): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: value, placeholder: text, type: .password, returnKeyType: .next, spacing: 0.0, tag: CreatePasswordEntryTag.password, sectionId: self.section, textUpdated: { updatedText in arguments.updateFieldText(.password, updatedText) }, action: { arguments.selectNextInputItem(CreatePasswordEntryTag.password) }) - case let .passwordConfirmation(theme, strings, text, value): + case let .passwordConfirmation(_, _, text, value): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: value, placeholder: text, type: .password, returnKeyType: .next, spacing: 0.0, tag: CreatePasswordEntryTag.passwordConfirmation, sectionId: self.section, textUpdated: { updatedText in arguments.updateFieldText(.passwordConfirmation, updatedText) }, action: { arguments.selectNextInputItem(CreatePasswordEntryTag.passwordConfirmation) }) - case let .passwordInfo(theme, text): + case let .passwordInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .hintHeader(theme, text): + case let .hintHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .hint(theme, strings, text, value, last): + case let .hint(_, _, text, value, last): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: value, placeholder: text, type: .regular(capitalization: true, autocorrection: false), returnKeyType: last ? .done : .next, spacing: 0.0, tag: CreatePasswordEntryTag.hint, sectionId: self.section, textUpdated: { updatedText in arguments.updateFieldText(.hint, updatedText) }, action: { @@ -148,21 +148,21 @@ private enum CreatePasswordEntry: ItemListNodeEntry, Equatable { arguments.selectNextInputItem(CreatePasswordEntryTag.hint) } }) - case let .hintInfo(theme, text): + case let .hintInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .emailHeader(theme, text): + case let .emailHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .email(theme, strings, text, value): + case let .email(_, _, text, value): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: value, placeholder: text, type: .email, returnKeyType: .done, spacing: 0.0, tag: CreatePasswordEntryTag.email, sectionId: self.section, textUpdated: { updatedText in arguments.updateFieldText(.email, updatedText) }, action: { arguments.save() }) - case let .emailInfo(theme, text): + case let .emailInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .emailConfirmation(theme, text): + case let .emailConfirmation(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .emailCancel(theme, text, enabled): + case let .emailCancel(_, text, enabled): return ItemListActionItem(presentationData: presentationData, title: text, kind: enabled ? .generic : .disabled, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.cancelEmailConfirmation() }) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/DataPrivacySettingsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/DataPrivacySettingsController.swift index 2c19e29e1e..755ce09724 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/DataPrivacySettingsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/DataPrivacySettingsController.swift @@ -211,45 +211,45 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! DataPrivacyControllerArguments switch self { - case let .contactsHeader(theme, text): + case let .contactsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .deleteContacts(theme, text, value): + case let .deleteContacts(_, text, value): return ItemListActionItem(presentationData: presentationData, title: text, kind: value ? .generic : .disabled, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.deleteContacts() }) - case let .syncContacts(theme, text, value): + case let .syncContacts(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateSyncContacts(updatedValue) }) - case let .syncContactsInfo(theme, text): + case let .syncContactsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .frequentContacts(theme, text, value): + case let .frequentContacts(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: !value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateSuggestFrequentContacts(updatedValue) }) - case let .frequentContactsInfo(theme, text): + case let .frequentContactsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .chatsHeader(theme, text): + case let .chatsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .deleteCloudDrafts(theme, text, value): + case let .deleteCloudDrafts(_, text, value): return ItemListActionItem(presentationData: presentationData, title: text, kind: value ? .generic : .disabled, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.deleteCloudDrafts() }) - case let .paymentHeader(theme, text): + case let .paymentHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .clearPaymentInfo(theme, text, enabled): + case let .clearPaymentInfo(_, text, enabled): return ItemListActionItem(presentationData: presentationData, title: text, kind: enabled ? .generic : .disabled, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.clearPaymentInfo() }) - case let .paymentInfo(theme, text): + case let .paymentInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .secretChatLinkPreviewsHeader(theme, text): + case let .secretChatLinkPreviewsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .secretChatLinkPreviews(theme, text, value): + case let .secretChatLinkPreviews(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in arguments.updateSecretChatLinkPreviews(updatedValue) }) - case let .secretChatLinkPreviewsInfo(theme, text): + case let .secretChatLinkPreviewsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } @@ -500,8 +500,6 @@ public func dataPrivacyController(context: AccountContext) -> ViewController { presentControllerImpl?(controller) }) - let previousState = Atomic(value: nil) - actionsDisposable.add(context.engine.peers.managedUpdatedRecentPeers().start()) let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.secretChatLinkPreviewsKey()), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]), context.account.postbox.preferencesView(keys: [PreferencesKeys.contactsSettings]), context.engine.peers.recentPeers()) @@ -528,7 +526,6 @@ public func dataPrivacyController(context: AccountContext) -> ViewController { let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.PrivateDataSettings_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false) - let previousStateValue = previousState.swap(state) let animateChanges = false let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: dataPrivacyControllerEntries(presentationData: presentationData, state: state, secretChatLinkPreviews: secretChatLinkPreviews, synchronizeDeviceContacts: synchronizeDeviceContacts, frequentContacts: suggestRecentPeers), style: .blocks, animateChanges: animateChanges) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/PasscodeOptionsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/PasscodeOptionsController.swift index 672935076e..0d0814e639 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/PasscodeOptionsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/PasscodeOptionsController.swift @@ -109,23 +109,23 @@ private enum PasscodeOptionsEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! PasscodeOptionsControllerArguments switch self { - case let .togglePasscode(theme, title, value): + case let .togglePasscode(_, title, value): return ItemListActionItem(presentationData: presentationData, title: title, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { if value { arguments.turnPasscodeOff() } }) - case let .changePasscode(theme, title): + case let .changePasscode(_, title): return ItemListActionItem(presentationData: presentationData, title: title, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.changePasscode() }) - case let .settingInfo(theme, text): + case let .settingInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .autoLock(theme, title, value): + case let .autoLock(_, title, value): return ItemListDisclosureItem(presentationData: presentationData, title: title, label: value, sectionId: self.section, style: .blocks, action: { arguments.changePasscodeTimeout() }) - case let .touchId(theme, title, value): + case let .touchId(_, title, value): return ItemListSwitchItem(presentationData: presentationData, title: title, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.changeTouchId(value) }) @@ -210,10 +210,6 @@ func passcodeOptionsController(context: AccountContext) -> ViewController { let initialState = PasscodeOptionsControllerState() let statePromise = ValuePromise(initialState, ignoreRepeated: true) - let stateValue = Atomic(value: initialState) - let updateState: ((PasscodeOptionsControllerState) -> PasscodeOptionsControllerState) -> Void = { f in - statePromise.set(stateValue.modify { f($0) }) - } var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments) -> Void)? var pushControllerImpl: ((ViewController) -> Void)? diff --git a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift index 28207189e0..7be99cbb75 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift @@ -284,47 +284,47 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! PrivacyAndSecurityControllerArguments switch self { - case let .privacyHeader(theme, text): + case let .privacyHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .blockedPeers(theme, text, value): + case let .blockedPeers(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: "Settings/MenuIcons/Blocked")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openBlockedUsers() }) - case let .phoneNumberPrivacy(theme, text, value): + case let .phoneNumberPrivacy(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openPhoneNumberPrivacy() }) - case let .lastSeenPrivacy(theme, text, value): + case let .lastSeenPrivacy(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openLastSeenPrivacy() }) - case let .profilePhotoPrivacy(theme, text, value): + case let .profilePhotoPrivacy(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openProfilePhotoPrivacy() }) - case let .forwardPrivacy(theme, text, value): + case let .forwardPrivacy(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openForwardPrivacy() }) - case let .groupPrivacy(theme, text, value): + case let .groupPrivacy(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openGroupsPrivacy() }) - case let .selectivePrivacyInfo(theme, text): + case let .selectivePrivacyInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .voiceCallPrivacy(theme, text, value): + case let .voiceCallPrivacy(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openVoiceCallPrivacy() }) - case let .passcode(theme, text, hasFaceId, value): + case let .passcode(_, text, hasFaceId, value): return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: hasFaceId ? "Settings/MenuIcons/FaceId" : "Settings/MenuIcons/TouchId")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openPasscode() }) - case let .twoStepVerification(theme, text, value, data): + case let .twoStepVerification(_, text, value, data): return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: "Settings/MenuIcons/TwoStepAuth")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openTwoStepVerification(data) }) - case let .activeSessions(theme, text, value): + case let .activeSessions(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: "Settings/MenuIcons/Websites")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openActiveSessions() }) @@ -336,19 +336,19 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry { }, tag: PrivacyAndSecurityEntryTag.autoArchive) case let .autoArchiveInfo(text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .accountHeader(theme, text): + case let .accountHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .accountTimeout(theme, text, value): + case let .accountTimeout(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.setupAccountAutoremove() }, tag: PrivacyAndSecurityEntryTag.accountTimeout) - case let .accountInfo(theme, text): + case let .accountInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .dataSettings(theme, text): + case let .dataSettings(_, text): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: { arguments.openDataSettings() }) - case let .dataSettingsInfo(theme, text): + case let .dataSettingsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } @@ -726,7 +726,6 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting } }) }, openTwoStepVerification: { data in - let intro = false if let data = data { switch data { case .set: @@ -737,28 +736,12 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting pushControllerImpl?(controller, true) return - } else { - } } } - if intro { - var nextImpl: (() -> Void)? - let introController = PrivacyIntroController(context: context, mode: .twoStepVerification, proceedAction: { - nextImpl?() - }) - nextImpl = { [weak introController] in - guard let introController = introController, let navigationController = introController.navigationController as? NavigationController else { - return - } - let controller = twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: intro, data: data.flatMap({ Signal.single(.access(configuration: $0)) }))) - navigationController.replaceController(introController, with: controller, animated: true) - } - pushControllerImpl?(introController, true) - } else { - let controller = twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: intro, data: data.flatMap({ Signal.single(.access(configuration: $0)) }))) - pushControllerImpl?(controller, true) - } + + let controller = twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: false, data: data.flatMap({ Signal.single(.access(configuration: $0)) }))) + pushControllerImpl?(controller, true) }, openActiveSessions: { pushControllerImpl?(recentSessionsController(context: context, activeSessionsContext: activeSessionsContext, webSessionsContext: webSessionsContext, websitesOnly: true), true) }, toggleArchiveAndMuteNonContacts: { archiveValue in diff --git a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsController.swift index b739dc8d07..b7671b73fe 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsController.swift @@ -267,7 +267,7 @@ private enum RecentSessionsEntry: ItemListNodeEntry { switch self { case let .currentSessionHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .currentSession(_, strings, dateTimeFormat, session): + case let .currentSession(_, _, dateTimeFormat, session): return ItemListRecentSessionItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, session: session, enabled: true, editable: false, editing: false, revealed: false, sectionId: self.section, setSessionIdWithRevealedOptions: { _, _ in }, removeSession: { _ in }) @@ -512,6 +512,7 @@ public func recentSessionsController(context: AccountContext, activeSessionsCont |> deliverOnMainQueue).start(next: { _ in dismissImpl?() }) + actionsDisposable.add(autoDismissDisposable) } let mode = ValuePromise(websitesOnly ? .websites : .sessions) @@ -593,12 +594,8 @@ public func recentSessionsController(context: AccountContext, activeSessionsCont removeSessionDisposable.set(((webSessionsContext.remove(hash: sessionId) |> mapToSignal { _ -> Signal in - return .complete() }) |> deliverOnMainQueue).start(error: { _ in - updateState { - return $0.withUpdatedRemovingSessionId(nil) - } }, completed: { updateState { return $0.withUpdatedRemovingSessionId(nil) @@ -621,9 +618,6 @@ public func recentSessionsController(context: AccountContext, activeSessionsCont terminateOtherSessionsDisposable.set((webSessionsContext.removeAll() |> deliverOnMainQueue).start(error: { _ in - updateState { - return $0.withUpdatedTerminatingOtherSessions(false) - } }, completed: { updateState { return $0.withUpdatedTerminatingOtherSessions(false) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift index 76a093fb66..d878a8953c 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift @@ -347,81 +347,81 @@ private enum SelectivePrivacySettingsEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! SelectivePrivacySettingsControllerArguments switch self { - case let .forwardsPreviewHeader(theme, text): + case let .forwardsPreviewHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, multiline: true, sectionId: self.section) case let .forwardsPreview(theme, wallpaper, fontSize, chatBubbleCorners, strings, dateTimeFormat, nameDisplayOrder, peerName, linkEnabled, tooltipText): return ForwardPrivacyChatPreviewItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, fontSize: fontSize, chatBubbleCorners: chatBubbleCorners, wallpaper: wallpaper, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, peerName: peerName, linkEnabled: linkEnabled, tooltipText: tooltipText) - case let .settingHeader(theme, text): + case let .settingHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, multiline: true, sectionId: self.section) - case let .everybody(theme, text, value): + case let .everybody(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateType(.everybody) }) - case let .contacts(theme, text, value): + case let .contacts(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateType(.contacts) }) - case let .nobody(theme, text, value): + case let .nobody(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateType(.nobody) }) - case let .settingInfo(theme, text): + case let .settingInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .exceptionsHeader(theme, text): + case let .exceptionsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .disableFor(theme, title, value): + case let .disableFor(_, title, value): return ItemListDisclosureItem(presentationData: presentationData, title: title, label: value, sectionId: self.section, style: .blocks, action: { arguments.openSelective(.main, false) }) - case let .enableFor(theme, title, value): + case let .enableFor(_, title, value): return ItemListDisclosureItem(presentationData: presentationData, title: title, label: value, sectionId: self.section, style: .blocks, action: { arguments.openSelective(.main, true) }) - case let .peersInfo(theme, text): + case let .peersInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .callsP2PHeader(theme, text): + case let .callsP2PHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .callsP2PAlways(theme, text, value): + case let .callsP2PAlways(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateCallP2PMode?(.everybody) }) - case let .callsP2PContacts(theme, text, value): + case let .callsP2PContacts(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateCallP2PMode?(.contacts) }) - case let .callsP2PNever(theme, text, value): + case let .callsP2PNever(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updateCallP2PMode?(.nobody) }) - case let .callsP2PInfo(theme, text): + case let .callsP2PInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .callsP2PDisableFor(theme, title, value): + case let .callsP2PDisableFor(_, title, value): return ItemListDisclosureItem(presentationData: presentationData, title: title, label: value, sectionId: self.section, style: .blocks, action: { arguments.openSelective(.callP2P, false) }) - case let .callsP2PEnableFor(theme, title, value): + case let .callsP2PEnableFor(_, title, value): return ItemListDisclosureItem(presentationData: presentationData, title: title, label: value, sectionId: self.section, style: .blocks, action: { arguments.openSelective(.callP2P, true) }) - case let .callsP2PPeersInfo(theme, text): + case let .callsP2PPeersInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .callsIntegrationEnabled(theme, text, value): + case let .callsIntegrationEnabled(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.updateCallIntegrationEnabled?(value) }) - case let .callsIntegrationInfo(theme, text): + case let .callsIntegrationInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .phoneDiscoveryHeader(theme, text): + case let .phoneDiscoveryHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .phoneDiscoveryEverybody(theme, text, value): + case let .phoneDiscoveryEverybody(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updatePhoneDiscovery?(true) }) - case let .phoneDiscoveryMyContacts(theme, text, value): + case let .phoneDiscoveryMyContacts(_, text, value): return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { arguments.updatePhoneDiscovery?(false) }) - case let .phoneDiscoveryInfo(theme, text): + case let .phoneDiscoveryInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } @@ -694,13 +694,11 @@ func selectivePrivacySettingsController(context: AccountContext, kind: Selective let updateState: ((SelectivePrivacySettingsControllerState) -> SelectivePrivacySettingsControllerState) -> Void = { f in statePromise.set(stateValue.modify { f($0) }) } - - var dismissImpl: (() -> Void)? + var pushControllerImpl: ((ViewController, Bool) -> Void)? var presentControllerImpl: ((ViewController, Any?) -> Void)? let actionsDisposable = DisposableSet() - let updateSettingsDisposable = MetaDisposable() let addPeerDisposable = MetaDisposable() actionsDisposable.add(addPeerDisposable) @@ -804,7 +802,7 @@ func selectivePrivacySettingsController(context: AccountContext, kind: Selective controller?.dismiss() updateState { state in - var state = state + let state = state if enable { switch target { case .main: @@ -1080,9 +1078,6 @@ func selectivePrivacySettingsController(context: AccountContext, kind: Selective presentControllerImpl = { [weak controller] c, a in controller?.present(c, in: .window(.root), with: a) } - dismissImpl = { [weak controller] in - let _ = (controller?.navigationController as? NavigationController)?.popViewController(animated: true) - } return controller } diff --git a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsPeersController.swift b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsPeersController.swift index 7fb0f87d32..a3a4c368d7 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsPeersController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsPeersController.swift @@ -37,32 +37,6 @@ private enum SelectivePrivacyPeersSection: Int32 { private enum SelectivePrivacyPeersEntryStableId: Hashable { case add case peer(PeerId) - - var hashValue: Int { - switch self { - case let .peer(peerId): - return peerId.hashValue - case .add: - return 1 - } - } - - static func ==(lhs: SelectivePrivacyPeersEntryStableId, rhs: SelectivePrivacyPeersEntryStableId) -> Bool { - switch lhs { - case let .peer(peerId): - if case .peer(peerId) = rhs { - return true - } else { - return false - } - case .add: - if case .add = rhs { - return true - } else { - return false - } - } - } } private enum SelectivePrivacyPeersEntry: ItemListNodeEntry { @@ -150,7 +124,7 @@ private enum SelectivePrivacyPeersEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! SelectivePrivacyPeersControllerArguments switch self { - case let .peerItem(_, theme, strings, dateTimeFormat, nameDisplayOrder, peer, editing, enabled): + case let .peerItem(_, _, strings, dateTimeFormat, nameDisplayOrder, peer, editing, enabled): var text: ItemListPeerItemText = .none if let group = peer.peer as? TelegramGroup { text = .text(strings.Conversation_StatusMembers(Int32(group.participantCount)), .secondary) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift index 117c00bcb9..aad0182437 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift @@ -129,7 +129,7 @@ private enum TwoStepVerificationUnlockSettingsEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! TwoStepVerificationUnlockSettingsControllerArguments switch self { - case let .passwordEntry(theme, strings, text, value): + case let .passwordEntry(theme, _, text, value): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: text, textColor: theme.list.itemPrimaryTextColor), text: value, placeholder: "", type: .password, spacing: 10.0, tag: TwoStepVerificationUnlockSettingsEntryTag.password, sectionId: self.section, textUpdated: { updatedText in arguments.updatePasswordText(updatedText) }, action: { @@ -377,8 +377,8 @@ public func twoStepVerificationUnlockSettingsController(context: AccountContext, switch data { case .access: dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.access(configuration: .notSet(pendingEmail: nil)))) - case let .manage(manage): - dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.manage(password: manage.password, emailSet: false, pendingEmail: nil, hasSecureValues: manage.hasSecureValues))) + case let .manage(password, _, _, hasSecureValues): + dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.manage(password: password, emailSet: false, pendingEmail: nil, hasSecureValues: hasSecureValues))) } updateState { state in @@ -406,8 +406,8 @@ public func twoStepVerificationUnlockSettingsController(context: AccountContext, dataPromise.set(.single(.access(configuration: nil)) |> then(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: pendingEmail.password)) })) } - case let .manage(manage): - dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.manage(password: manage.password, emailSet: true, pendingEmail: nil, hasSecureValues: manage.hasSecureValues))) + case let .manage(password, _, _, hasSecureValues): + dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.manage(password: password, emailSet: true, pendingEmail: nil, hasSecureValues: hasSecureValues))) } updateState { state in @@ -448,8 +448,8 @@ public func twoStepVerificationUnlockSettingsController(context: AccountContext, } |> map { configuration in var pendingEmail: TwoStepVerificationPendingEmail? - if case let .set(configuration) = configuration { - pendingEmail = configuration.pendingEmail + if case let .set(_, _, pendingEmailValue, _, _) = configuration { + pendingEmail = pendingEmailValue } return (settings, pendingEmail) } @@ -646,7 +646,7 @@ public func twoStepVerificationUnlockSettingsController(context: AccountContext, break } } - case let .manage(password, hasRecovery, pendingEmail, hasSecureValues): + case let .manage(password, hasRecovery, _, hasSecureValues): let controller = SetupTwoStepVerificationController(context: context, initialState: .updatePassword(current: password, hasRecoveryEmail: hasRecovery, hasSecureValues: hasSecureValues), stateUpdated: { update, shouldDismiss, controller in switch update { case .pendingPasswordReset: @@ -697,7 +697,7 @@ public func twoStepVerificationUnlockSettingsController(context: AccountContext, if disablePassword { setupDisposable.set((dataPromise.get() |> take(1) - |> mapError { _ -> UpdateTwoStepVerificationPasswordError in return .generic } + |> mapError { _ -> UpdateTwoStepVerificationPasswordError in } |> mapToSignal { data -> Signal in switch data { case .access: @@ -953,12 +953,12 @@ public func twoStepVerificationUnlockSettingsController(context: AccountContext, } else { emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme) } - case let .manage(manage): + case let .manage(_, _, pendingEmail, _): title = presentationData.strings.PrivacySettings_TwoStepAuth if state.checking { rightNavigationButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {}) } else { - if let _ = manage.pendingEmail { + if let _ = pendingEmail { rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Next), style: .bold, enabled: !state.emailCode.isEmpty, action: { checkEmailConfirmation() }) diff --git a/submodules/SettingsUI/Sources/Search/SettingsSearchItem.swift b/submodules/SettingsUI/Sources/Search/SettingsSearchItem.swift index a63dcee4ab..745c267742 100644 --- a/submodules/SettingsUI/Sources/Search/SettingsSearchItem.swift +++ b/submodules/SettingsUI/Sources/Search/SettingsSearchItem.swift @@ -240,24 +240,6 @@ private func preparedSettingsSearchContainerTransition(theme: PresentationTheme, private enum SettingsSearchRecentEntryStableId: Hashable { case recent(SettingsSearchableItemId) - - static func ==(lhs: SettingsSearchRecentEntryStableId, rhs: SettingsSearchRecentEntryStableId) -> Bool { - switch lhs { - case let .recent(id): - if case .recent(id) = rhs { - return true - } else { - return false - } - } - } - - var hashValue: Int { - switch self { - case let .recent(id): - return id.hashValue - } - } } private enum SettingsSearchRecentEntry: Comparable, Identifiable { diff --git a/submodules/SettingsUI/Sources/Search/SettingsSearchRecentQueries.swift b/submodules/SettingsUI/Sources/Search/SettingsSearchRecentQueries.swift index a13843c491..32317752fb 100644 --- a/submodules/SettingsUI/Sources/Search/SettingsSearchRecentQueries.swift +++ b/submodules/SettingsUI/Sources/Search/SettingsSearchRecentQueries.swift @@ -8,7 +8,12 @@ private struct SettingsSearchRecentQueryItemId { public let rawValue: MemoryBuffer var value: Int64 { - return self.rawValue.makeData().withUnsafeBytes { $0.pointee } as Int64 + return self.rawValue.makeData().withUnsafeBytes { buffer -> Int64 in + guard let bytes = buffer.baseAddress?.assumingMemoryBound(to: Int64.self) else { + return 0 + } + return bytes.pointee + } } init(_ rawValue: MemoryBuffer) { diff --git a/submodules/SettingsUI/Sources/SettingsController.swift b/submodules/SettingsUI/Sources/SettingsController.swift index 8338d432df..71484a7b62 100644 --- a/submodules/SettingsUI/Sources/SettingsController.swift +++ b/submodules/SettingsUI/Sources/SettingsController.swift @@ -6,7 +6,7 @@ import Postbox import TelegramCore import AccountContext -public protocol SettingsController: class { +public protocol SettingsController: AnyObject { func updateContext(context: AccountContext) } diff --git a/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift index 3818ec06c1..bd86306f87 100644 --- a/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift @@ -43,32 +43,6 @@ private enum ArchivedStickerPacksSection: Int32 { private enum ArchivedStickerPacksEntryId: Hashable { case index(Int32) case pack(ItemCollectionId) - - var hashValue: Int { - switch self { - case let .index(index): - return index.hashValue - case let .pack(id): - return id.hashValue - } - } - - static func ==(lhs: ArchivedStickerPacksEntryId, rhs: ArchivedStickerPacksEntryId) -> Bool { - switch lhs { - case let .index(index): - if case .index(index) = rhs { - return true - } else { - return false - } - case let .pack(id): - if case .pack(id) = rhs { - return true - } else { - return false - } - } - } } private enum ArchivedStickerPacksEntry: ItemListNodeEntry { @@ -157,9 +131,9 @@ private enum ArchivedStickerPacksEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! ArchivedStickerPacksControllerArguments switch self { - case let .info(theme, text): + case let .info(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .pack(_, theme, strings, info, topItem, count, animatedStickers, enabled, editing): + case let .pack(_, _, _, info, topItem, count, animatedStickers, enabled, editing): return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: .installation(installed: false), editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { arguments.openStickerPack(info) }, setPackIdWithRevealedOptions: { current, previous in diff --git a/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift index 6c57829354..3d17794f75 100644 --- a/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift @@ -31,24 +31,6 @@ private enum FeaturedStickerPacksSection: Int32 { private enum FeaturedStickerPacksEntryId: Hashable { case pack(ItemCollectionId) - - var hashValue: Int { - switch self { - case let .pack(id): - return id.hashValue - } - } - - static func ==(lhs: FeaturedStickerPacksEntryId, rhs: FeaturedStickerPacksEntryId) -> Bool { - switch lhs { - case let .pack(id): - if case .pack(id) = rhs { - return true - } else { - return false - } - } - } } private enum FeaturedStickerPacksEntry: ItemListNodeEntry { @@ -119,7 +101,7 @@ private enum FeaturedStickerPacksEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! FeaturedStickerPacksControllerArguments switch self { - case let .pack(_, theme, strings, info, unread, topItem, count, playAnimatedStickers, installed): + case let .pack(_, _, _, info, unread, topItem, count, playAnimatedStickers, installed): return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: unread, control: .installation(installed: installed), editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: { arguments.openStickerPack(info) }, setPackIdWithRevealedOptions: { _, _ in @@ -202,8 +184,7 @@ public func featuredStickerPacksController(context: AccountContext) -> ViewContr let featured = Promise<[FeaturedStickerPackItem]>() featured.set(context.account.viewTracker.featuredStickerPacks()) - - var previousPackCount: Int? + var initialUnreadPacks: [ItemCollectionId: Bool] = [:] let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, stickerPacks.get() |> deliverOnMainQueue, featured.get() |> deliverOnMainQueue, context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.stickerSettings]) |> deliverOnMainQueue) @@ -214,8 +195,6 @@ public func featuredStickerPacksController(context: AccountContext) -> ViewContr stickerSettings = value } - let packCount: Int? = featured.count - for item in featured { if initialUnreadPacks[item.info.id] == nil { initialUnreadPacks[item.info.id] = item.unread @@ -223,8 +202,6 @@ public func featuredStickerPacksController(context: AccountContext) -> ViewContr } let rightNavigationButton: ItemListNavigationButton? = nil - let previous = previousPackCount - previousPackCount = packCount let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.FeaturedStickerPacks_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) diff --git a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift index 2bf1143f04..bf40f089ae 100644 --- a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift @@ -65,32 +65,6 @@ public enum InstalledStickerPacksEntryTag: ItemListItemTag { private enum InstalledStickerPacksEntryId: Hashable { case index(Int32) case pack(ItemCollectionId) - - var hashValue: Int { - switch self { - case let .index(index): - return index.hashValue - case let .pack(id): - return id.hashValue - } - } - - static func ==(lhs: InstalledStickerPacksEntryId, rhs: InstalledStickerPacksEntryId) -> Bool { - switch lhs { - case let .index(index): - if case .index(index) = rhs { - return true - } else { - return false - } - case let .pack(id): - if case .pack(id) = rhs { - return true - } else { - return false - } - } - } } private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry { @@ -848,8 +822,8 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta var currentIds: [ItemCollectionId] = [] for entry in entries { switch entry { - case let .pack(pack): - currentIds.append(pack.3.id) + case let .pack(_, _, _, info, _, _, _, _, _, _): + currentIds.append(info.id) default: break } @@ -902,14 +876,14 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta var currentIds: [ItemCollectionId] = [] for entry in entries { switch entry { - case let .pack(pack): - currentIds.append(pack.3.id) + case let .pack(_, _, _, info, _, _, _, _, _, _): + currentIds.append(info.id) default: break } } let _ = (context.account.postbox.transaction { transaction -> Void in - var infos = transaction.getItemCollectionsInfos(namespace: namespaceForMode(mode)) + let infos = transaction.getItemCollectionsInfos(namespace: namespaceForMode(mode)) var packDict: [ItemCollectionId: Int] = [:] for i in 0 ..< infos.count { diff --git a/submodules/SettingsUI/Sources/Terms of Service/TermsOfServiceController.swift b/submodules/SettingsUI/Sources/Terms of Service/TermsOfServiceController.swift index 1fda1a5129..4e4db063d1 100644 --- a/submodules/SettingsUI/Sources/Terms of Service/TermsOfServiceController.swift +++ b/submodules/SettingsUI/Sources/Terms of Service/TermsOfServiceController.swift @@ -113,7 +113,6 @@ public class TermsOfServiceController: ViewController, StandalonePresentableCont text = strongSelf.presentationData.strings.PrivacyPolicy_DeclineMessage declineTitle = strongSelf.presentationData.strings.PrivacyPolicy_DeclineDeclineAndDelete } - let theme: PresentationTheme = strongSelf.presentationData.theme strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: strongSelf.presentationData.strings.PrivacyPolicy_Decline, text: text, actions: [TextAlertAction(type: .destructiveAction, title: declineTitle, action: { self?.decline() }), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { diff --git a/submodules/SettingsUI/Sources/Terms of Service/TermsOfServiceControllerNode.swift b/submodules/SettingsUI/Sources/Terms of Service/TermsOfServiceControllerNode.swift index fe3797b498..5e1058e9de 100644 --- a/submodules/SettingsUI/Sources/Terms of Service/TermsOfServiceControllerNode.swift +++ b/submodules/SettingsUI/Sources/Terms of Service/TermsOfServiceControllerNode.swift @@ -137,7 +137,6 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode { guard let strongSelf = self else { return } - let theme: PresentationTheme = strongSelf.presentationData.theme let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData) actionSheet.setItemGroups([ActionSheetItemGroup(items: [ ActionSheetTextItem(title: strongSelf.presentationData.strings.Login_TermsOfService_ProceedBot(mention).string), @@ -169,7 +168,6 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode { return } if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { - let theme: PresentationTheme = strongSelf.presentationData.theme let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData) actionSheet.setItemGroups([ActionSheetItemGroup(items: [ ActionSheetTextItem(title: url), diff --git a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift index 5fd07b038f..ceefe04ed2 100644 --- a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift +++ b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift @@ -227,7 +227,6 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView let peer4 = TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt32Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) let peer5 = TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt32Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil) let peer6 = TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt32Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) - let peer7 = TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt32Value(6)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_7_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) let timestamp = self.referenceTimestamp diff --git a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift index 2b6b8237eb..7d1c27992f 100644 --- a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift +++ b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift @@ -147,7 +147,7 @@ private enum EditThemeControllerEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! EditThemeControllerArguments switch self { - case let .title(theme, strings, title, text, _): + case let .title(_, _, title, text, _): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(), text: text, placeholder: title, type: .regular(capitalization: true, autocorrection: false), returnKeyType: .default, clearType: .onFocus, tag: EditThemeEntryTag.title, sectionId: self.section, textUpdated: { value in arguments.updateState { current in var state = current @@ -157,8 +157,8 @@ private enum EditThemeControllerEntry: ItemListNodeEntry { }, action: { }) - case let .slug(theme, strings, title, text, enabled): - return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: "t.me/addtheme/", textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: title, type: .username, clearType: .onFocus, enabled: enabled, tag: EditThemeEntryTag.slug, sectionId: self.section, textUpdated: { value in + case let .slug(_, _, title, text, enabled): + return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: "t.me/addtheme/", textColor: presentationData.theme.list.itemPrimaryTextColor), text: text, placeholder: title, type: .username, clearType: .onFocus, enabled: enabled, tag: EditThemeEntryTag.slug, sectionId: self.section, textUpdated: { value in arguments.updateState { current in var state = current state.slug = value @@ -167,21 +167,21 @@ private enum EditThemeControllerEntry: ItemListNodeEntry { }, action: { }) - case let .slugInfo(theme, text): + case let .slugInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section) - case let .chatPreviewHeader(theme, text): + case let .chatPreviewHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .chatPreview(theme, componentTheme, wallpaper, fontSize, chatBubbleCorners, strings, dateTimeFormat, nameDisplayOrder, items): return ThemeSettingsChatPreviewItem(context: arguments.context, theme: theme, componentTheme: componentTheme, strings: strings, sectionId: self.section, fontSize: fontSize, chatBubbleCorners: chatBubbleCorners, wallpaper: wallpaper, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, messageItems: items) - case let .changeColors(theme, text): + case let .changeColors(_, text): return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.openColors() }) - case let .uploadTheme(theme, text): + case let .uploadTheme(_, text): return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { arguments.openFile() }) - case let .uploadInfo(theme, text): + case let .uploadInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section) } } diff --git a/submodules/SettingsUI/Sources/Themes/GenerateGradientColors.swift b/submodules/SettingsUI/Sources/Themes/GenerateGradientColors.swift index edd2dce252..48d4c93dc9 100644 --- a/submodules/SettingsUI/Sources/Themes/GenerateGradientColors.swift +++ b/submodules/SettingsUI/Sources/Themes/GenerateGradientColors.swift @@ -325,12 +325,12 @@ func generateGradientColors(color: UIColor) -> (UIColor, UIColor) { } if let colors = nearest?.colors { - var colorHsb = color.hsb - var similarColorHsb = UIColor(rgb: colors.0).hsb - var complementingColorHsb = UIColor(rgb: colors.1).hsb + let colorHsb = color.hsb + let similarColorHsb = UIColor(rgb: colors.0).hsb + let complementingColorHsb = UIColor(rgb: colors.1).hsb - var correction = (similarColorHsb.0 > 0.0 ? colorHsb.0 / similarColorHsb.0 : 1.0, similarColorHsb.1 > 0.0 ? colorHsb.1 / similarColorHsb.1 : 1.0, similarColorHsb.2 > 0.0 ? colorHsb.2 / similarColorHsb.2 : 1.0) - var correctedComplementingColor = UIColor(hue: min(1.0, complementingColorHsb.0 * correction.0), saturation: min(1.0, complementingColorHsb.1 * correction.1), brightness: min(1.0, complementingColorHsb.2 * correction.2), alpha: 1.0) + let correction = (similarColorHsb.0 > 0.0 ? colorHsb.0 / similarColorHsb.0 : 1.0, similarColorHsb.1 > 0.0 ? colorHsb.1 / similarColorHsb.1 : 1.0, similarColorHsb.2 > 0.0 ? colorHsb.2 / similarColorHsb.2 : 1.0) + let correctedComplementingColor = UIColor(hue: min(1.0, complementingColorHsb.0 * correction.0), saturation: min(1.0, complementingColorHsb.1 * correction.1), brightness: min(1.0, complementingColorHsb.2 * correction.2), alpha: 1.0) return (color, correctedComplementingColor) } else { return (color, color) diff --git a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift index 641ede3a5c..6ed9876771 100644 --- a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift +++ b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift @@ -117,8 +117,8 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { var colors: [UInt32] = [] var intensity: CGFloat = 0.5 - if case let .gradient(_, value, _) = wallpaper { - colors = value + if case let .gradient(gradient) = wallpaper { + colors = gradient.colors } else if case let .file(file) = wallpaper { colors = file.settings.colors intensity = CGFloat(file.settings.intensity ?? 50) / 100.0 @@ -210,7 +210,6 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { let convertedFullRepresentations = [ImageRepresentationWithReference(representation: .init(dimensions: fullDimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))] let imageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> - var placeholder: UIImage? if wallpaper.isPattern { var patternIntensity: CGFloat = 0.5 if !file.settings.colors.isEmpty { @@ -220,7 +219,6 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { } if patternIntensity < 0.0 { - placeholder = blackColorImage self.imageNode.alpha = 1.0 self.arguments = PatternWallpaperArguments(colors: [.clear], rotation: nil, customPatternColor: UIColor(white: 0.0, alpha: 1.0 + patternIntensity)) } else { diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift index 34479b9e34..10bc360375 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift @@ -34,8 +34,6 @@ enum ThemeAccentColorControllerMode { return themeReference case let .edit(_, _, _, defaultThemeReference, _, _): return defaultThemeReference - default: - return nil } } } @@ -68,7 +66,7 @@ final class ThemeAccentColorController: ViewController { self.mode = mode self.presentationData = context.sharedContext.currentPresentationData.with { $0 } - var section: ThemeColorSection = .background + let section: ThemeColorSection = .background self.section = section self.segmentedTitleView = ThemeColorSegmentedTitleView(theme: self.presentationData.theme, strings: self.presentationData.strings, selectedSection: section) @@ -163,15 +161,12 @@ final class ThemeAccentColorController: ViewController { if let patternWallpaper = state.patternWallpaper { coloredWallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(colors: state.backgroundColors, intensity: state.patternIntensity, rotation: state.rotation)) } else if state.backgroundColors.count >= 2 { - coloredWallpaper = .gradient(nil, state.backgroundColors, WallpaperSettings(rotation: state.rotation)) + coloredWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: state.backgroundColors, settings: WallpaperSettings(rotation: state.rotation))) } else { coloredWallpaper = .color(state.backgroundColors[0]) } } - - let apply: Signal - let prepareWallpaper: Signal if let patternWallpaper = state.patternWallpaper, case let .file(file) = patternWallpaper, !state.backgroundColors.isEmpty { let resource = file.file.resource @@ -193,10 +188,9 @@ final class ThemeAccentColorController: ViewController { prepareWallpaper = .complete() } - if case let .edit(theme, initialWallpaper, generalThemeReference, themeReference, _, completion) = strongSelf.mode { + if case let .edit(theme, _, generalThemeReference, _, _, completion) = strongSelf.mode { let _ = (prepareWallpaper - |> deliverOnMainQueue).start(completed: { [weak self] in - let updatedTheme: PresentationTheme + |> deliverOnMainQueue).start(completed: { let updatedTheme: PresentationTheme var settings: TelegramThemeSettings? var hasSettings = false @@ -217,11 +211,6 @@ final class ThemeAccentColorController: ViewController { } if hasSettings, let baseTheme = baseTheme { - var messageColors: (Int32, Int32)? - if let colors = state.messagesColors { - messageColors = (Int32(bitPattern: colors.0.argb), Int32(bitPattern: colors.1?.argb ?? colors.0.argb)) - } - settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: state.accentColor, messageColors: state.messagesColors, wallpaper: coloredWallpaper) } @@ -390,9 +379,8 @@ final class ThemeAccentColorController: ViewController { var backgroundColors: [UInt32] = [] var patternWallpaper: TelegramWallpaper? var patternIntensity: Int32 = 50 - var motion = false let messageColors: (UIColor, UIColor?)? - var defaultMessagesColor: UIColor? + let defaultMessagesColor: UIColor? = nil var rotation: Int32 = 0 func extractWallpaperParameters(_ wallpaper: TelegramWallpaper?) { @@ -400,27 +388,19 @@ final class ThemeAccentColorController: ViewController { return } if case let .file(file) = wallpaper, wallpaper.isPattern { - var patternColor = UIColor(rgb: 0xd6e2ee, alpha: 0.4) - var bottomColor: UIColor? if !file.settings.colors.isEmpty { if let intensity = file.settings.intensity { patternIntensity = intensity } - patternColor = UIColor(rgb: file.settings.colors[0]) - if file.settings.colors.count >= 2 { - bottomColor = UIColor(rgb: file.settings.colors[1]) - } } patternWallpaper = wallpaper backgroundColors = file.settings.colors - motion = file.settings.motion rotation = file.settings.rotation ?? 0 } else if case let .color(color) = wallpaper { backgroundColors = [color] - } else if case let .gradient(_, colors, settings) = wallpaper { - backgroundColors = colors - motion = settings.motion - rotation = settings.rotation ?? 0 + } else if case let .gradient(gradient) = wallpaper { + backgroundColors = gradient.colors + rotation = gradient.settings.rotation ?? 0 } else { if let image = chatControllerBackgroundImage(theme: nil, wallpaper: wallpaper, mediaBox: strongSelf.context.sharedContext.accountManager.mediaBox, knockoutMode: false) { backgroundColors = [averageColor(from: image).rgb] @@ -559,8 +539,6 @@ final class ThemeAccentColorController: ViewController { } } } else { - let themeSpecificAccentColor = settings.themeSpecificAccentColors[themeReference.index] - let theme = makePresentationTheme(mediaBox: strongSelf.context.sharedContext.accountManager.mediaBox, themeReference: themeReference)! accentColor = theme.rootController.navigationBar.accentTextColor @@ -582,7 +560,7 @@ final class ThemeAccentColorController: ViewController { } } } - } else if case let .edit(theme, wallpaper, _, themeReference, _, _) = strongSelf.mode { + } else if case let .edit(theme, wallpaper, _, _, _, _) = strongSelf.mode { accentColor = theme.rootController.navigationBar.accentTextColor let wallpaper = wallpaper ?? theme.chat.defaultWallpaper diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index bd1850236f..2569a513a4 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -205,7 +205,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate switch self.wallpaper { case .image, .builtin: return true - case let .file(file): + case .file: return !self.wallpaper.isPattern default: return false @@ -457,7 +457,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate } convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) } else if backgroundColors.count >= 2 { - wallpaper = .gradient(nil, backgroundColors, WallpaperSettings(rotation: state.rotation)) + wallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: backgroundColors, settings: WallpaperSettings(rotation: state.rotation))) } else { wallpaper = .color(backgroundColors.first ?? 0xffffff) } @@ -467,7 +467,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate case .dayClassic: let topColor = accentColor.withMultiplied(hue: 1.010, saturation: 0.414, brightness: 0.957) let bottomColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.867, brightness: 0.965) - suggestedWallpaper = .gradient(nil, [topColor.rgb, bottomColor.rgb], WallpaperSettings()) + suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: [topColor.rgb, bottomColor.rgb], settings: WallpaperSettings())) backgroundColors = [topColor.rgb, bottomColor.rgb] case .nightAccent: let color = accentColor.withMultiplied(hue: 1.024, saturation: 0.573, brightness: 0.18) @@ -980,8 +980,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate } func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { - let isFirstLayout = self.validLayout == nil - let bounds = CGRect(origin: CGPoint(), size: layout.size) let chatListPreviewAvailable = self.state.section == .accent @@ -1022,8 +1020,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate transition.updateFrame(node: self.colorPanelNode, frame: colorPanelFrame) self.colorPanelNode.updateLayout(size: colorPanelFrame.size, transition: transition) - var patternPanelAlpha: CGFloat = self.state.displayPatternPanel ? 1.0 : 0.0 - var patternPanelFrame = colorPanelFrame + let patternPanelAlpha: CGFloat = self.state.displayPatternPanel ? 1.0 : 0.0 + let patternPanelFrame = colorPanelFrame transition.updateFrame(node: self.patternPanelNode, frame: patternPanelFrame) self.patternPanelNode.updateLayout(size: patternPanelFrame.size, transition: transition) self.patternPanelNode.isUserInteractionEnabled = self.state.displayPatternPanel diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightTimeSelectionActionSheet.swift b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightTimeSelectionActionSheet.swift index b71ed79464..b357293898 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightTimeSelectionActionSheet.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightTimeSelectionActionSheet.swift @@ -19,7 +19,6 @@ final class ThemeAutoNightTimeSelectionActionSheet: ActionSheetController { init(context: AccountContext, currentValue: Int32, emptyTitle: String? = nil, applyValue: @escaping (Int32?) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } - let theme = presentationData.theme let strings = presentationData.strings super.init(theme: ActionSheetControllerTheme(presentationData: presentationData)) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerNode.swift index e531bbb151..bb37b5bdfa 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerNode.swift @@ -142,7 +142,7 @@ final class ThemeColorsGridControllerNode: ASDisplayNode { self.controllerInteraction = interaction var wallpapers: [TelegramWallpaper] = [] - wallpapers.append(contentsOf: gradients.map { TelegramWallpaper.gradient(nil, $0, WallpaperSettings()) }) + wallpapers.append(contentsOf: gradients.map { TelegramWallpaper.gradient(TelegramWallpaper.Gradient(id: nil, colors: $0, settings: WallpaperSettings())) }) wallpapers.append(contentsOf: colors.map { TelegramWallpaper.color($0) }) let transition = context.sharedContext.presentationData |> map { presentationData -> (ThemeColorsGridEntryTransition, Bool) in diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift index 355a2be23d..b39af5c582 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift @@ -343,13 +343,13 @@ final class ThemeGridController: ViewController { for wallpaper in wallpapers { var item: String? switch wallpaper { - case let .file(_, _, _, _, isPattern, _, slug, _, settings): + case let .file(file): var options: [String] = [] - if isPattern { - if settings.colors.count >= 1 { - options.append("bg_color=\(UIColor(rgb: settings.colors[0]).hexString)") + if file.isPattern { + if file.settings.colors.count >= 1 { + options.append("bg_color=\(UIColor(rgb: file.settings.colors[0]).hexString)") } - if let intensity = settings.intensity { + if let intensity = file.settings.intensity { options.append("intensity=\(intensity)") } } @@ -358,7 +358,7 @@ final class ThemeGridController: ViewController { if !options.isEmpty { optionsString = "?\(options.joined(separator: "&"))" } - item = slug + optionsString + item = file.slug + optionsString case let .color(color): item = "\(UIColor(rgb: color).hexString)" default: diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift index 733c7b4174..762f26a144 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift @@ -60,10 +60,10 @@ struct ThemeGridControllerEntry: Comparable, Identifiable { return .builtin case let .color(color): return .color(color) - case let .gradient(_, colors, _): - return .gradient(colors) - case let .file(id, _, _, _, _, _, _, _, settings): - return .file(id, settings.colors, settings.intensity ?? 0) + case let .gradient(gradient): + return .gradient(gradient.colors) + case let .file(file): + return .file(file.id, file.settings.colors, file.settings.intensity ?? 0) case let .image(representations, _): if let largest = largestImageRepresentation(representations) { return .image(largest.resource.id.uniqueId) @@ -240,8 +240,6 @@ final class ThemeGridControllerNode: ASDisplayNode { self.currentState = ThemeGridControllerNodeState(editing: false, selectedIds: Set()) self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true) - let defaultWallpaper = presentationData.theme.chat.defaultWallpaper - let wallpapersPromise = Promise<[Wallpaper]>() self.wallpapersPromise = wallpapersPromise @@ -344,13 +342,7 @@ final class ThemeGridControllerNode: ASDisplayNode { |> map { wallpapers, deletedWallpaperIds, presentationData -> (ThemeGridEntryTransition, Bool) in var entries: [ThemeGridControllerEntry] = [] var index = 1 - - var isSelectedEditable = true - if case .builtin = presentationData.chatWallpaper { - isSelectedEditable = false - } else if presentationData.chatWallpaper.isBasicallyEqual(to: presentationData.theme.chat.defaultWallpaper) { - isSelectedEditable = false - } + entries.insert(ThemeGridControllerEntry(index: 0, wallpaper: presentationData.chatWallpaper, isEditable: false, isSelected: true), at: 0) var defaultWallpaper: TelegramWallpaper? diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridSearchContentNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridSearchContentNode.swift index 17c57e9400..f1d1fa9b66 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridSearchContentNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridSearchContentNode.swift @@ -180,32 +180,6 @@ final class ThemeGridSearchInteraction { private enum ThemeGridRecentEntryStableId: Hashable { case colors case query(String) - - static func ==(lhs: ThemeGridRecentEntryStableId, rhs: ThemeGridRecentEntryStableId) -> Bool { - switch lhs { - case .colors: - if case .colors = rhs { - return true - } else { - return false - } - case let .query(query): - if case .query(query) = rhs { - return true - } else { - return false - } - } - } - - var hashValue: Int { - switch self { - case .colors: - return 0 - case let .query(query): - return query.hashValue - } - } } private enum ThemeGridRecentEntry: Comparable, Identifiable { diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewController.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewController.swift index 162f11d443..6551db9c2c 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewController.swift @@ -423,7 +423,7 @@ public final class ThemePreviewController: ViewController { Queue.mainQueue().after(0.3) { if layout.size.width >= 375.0 { let navigationController = strongSelf.navigationController as? NavigationController - if let (previousDefaultTheme, previousAccentColor, autoNightMode, theme, existing) = previousDefaultTheme { + if let (previousDefaultTheme, previousAccentColor, autoNightMode, theme, _) = previousDefaultTheme { let _ = (ApplicationSpecificNotice.getThemeChangeTip(accountManager: strongSelf.context.sharedContext.accountManager) |> deliverOnMainQueue).start(next: { [weak self] displayed in guard let strongSelf = self, !displayed else { @@ -485,7 +485,7 @@ public final class ThemePreviewController: ViewController { let subject: ShareControllerSubject let preferredAction: ShareControllerPreferredAction switch self.source { - case let .settings(reference): + case .settings: return case let .theme(theme): subject = .url("https://t.me/addtheme/\(theme.slug)") diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift index c07a304420..3cf8104a6d 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift @@ -125,7 +125,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { self.toolbarNode = WallpaperGalleryToolbarNode(theme: self.previewTheme, strings: self.presentationData.strings, doneButtonType: .set) - if case let .file(file) = previewTheme.chat.defaultWallpaper { + if case .file = previewTheme.chat.defaultWallpaper { self.toolbarNode.setDoneEnabled(false) } @@ -191,8 +191,8 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { if file.settings.blur { self.chatContainerNode.insertSubnode(self.blurredNode, belowSubnode: self.messagesContainerNode) } - } else if case let .gradient(_, colors, _) = self.wallpaper { - gradientColors = colors + } else if case let .gradient(gradient) = self.wallpaper { + gradientColors = gradient.colors } if gradientColors.count >= 3 { @@ -247,7 +247,6 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) let signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> - let fileReference = FileMediaReference.standalone(media: file.file) if wallpaper.isPattern { signal = .complete() } else { diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift index d3a27127ca..515d129297 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift @@ -24,7 +24,7 @@ private enum ThemeSettingsColorEntry: Comparable, Identifiable { var stableId: ThemeSettingsColorEntryId { switch self { - case let .color(index, _, themeReference, accentColor, _): + case let .color(_, _, themeReference, accentColor, _): return .color(themeReference.index &+ Int64(accentColor?.index ?? 0)) case let .theme(_, _, _, theme, _): return .theme(theme.index) @@ -555,8 +555,6 @@ private final class ThemeSettingsAccentColorPickerItemNode : ListViewItemNode { } func asyncLayout() -> (ThemeSettingsAccentColorPickerItem, ListViewItemLayoutParams) -> (ListViewItemNodeLayout, (Bool) -> Void) { - let currentItem = self.item - return { [weak self] item, params in let itemLayout = ListViewItemNodeLayout(contentSize: CGSize(width: 60.0, height: 60.0), insets: UIEdgeInsets()) return (itemLayout, { animated in @@ -767,7 +765,7 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode { } self.enqueuedTransitions.remove(at: 0) - var options = ListViewDeleteAndInsertOptions() + let options = ListViewDeleteAndInsertOptions() var scrollToItem: ListViewScrollToItem? if !self.initialized || transition.updatePosition { if let index = item.colors.firstIndex(where: { $0.index == item.currentColor?.index }) { @@ -776,7 +774,7 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode { } } - self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { [weak self] _ in + self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { _ in }) } @@ -789,11 +787,6 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode { themeUpdated = true } - var colorUpdated: Bool - if currentItem?.currentColor != item.currentColor { - colorUpdated = true - } - let contentSize: CGSize let insets: UIEdgeInsets let separatorHeight = UIScreenPixel @@ -927,10 +920,10 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode { } else { item.updated(color) } - ensureColorVisible(listNode: strongSelf.listNode, accentColor: color, animated: true) + let _ = ensureColorVisible(listNode: strongSelf.listNode, accentColor: color, animated: true) } } - let contextAction: ((ThemeSettingsColorOption?, Bool, ASDisplayNode, ContextGesture?) -> Void)? = { [weak item] color, selected, node, gesture in + let contextAction: ((ThemeSettingsColorOption?, Bool, ASDisplayNode, ContextGesture?) -> Void)? = { color, selected, node, gesture in if let strongSelf = self, let item = strongSelf.item { item.contextAction?(selected, item.generalThemeReference, color, node, gesture) } diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift index e6ff3204de..566acd8dbb 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift @@ -206,8 +206,6 @@ class ThemeSettingsAppIconItemNode: ListViewItemNode, ItemListItemNode { } func asyncLayout() -> (_ item: ThemeSettingsAppIconItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { - let currentItem = self.item - return { item, params, neighbors in let contentSize: CGSize let insets: UIEdgeInsets diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift index b36f14acef..6c082bd9ff 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift @@ -214,8 +214,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { } else { return false } - case let .accentColor(lhsTheme, lhsGeneralTheme, lhsCurrentTheme, lhsThemes, lhsColor): - if case let .accentColor(rhsTheme, rhsGeneralTheme, rhsCurrentTheme, rhsThemes, rhsColor) = rhs, lhsTheme === rhsTheme, lhsCurrentTheme == rhsCurrentTheme, lhsThemes == rhsThemes, lhsColor == rhsColor { + case let .accentColor(lhsTheme, _, lhsCurrentTheme, lhsThemes, lhsColor): + if case let .accentColor(rhsTheme, _, rhsCurrentTheme, rhsThemes, rhsColor) = rhs, lhsTheme === rhsTheme, lhsCurrentTheme == rhsCurrentTheme, lhsThemes == rhsThemes, lhsColor == rhsColor { return true } else { return false @@ -308,7 +308,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! ThemeSettingsControllerArguments switch self { - case let .fontSizeHeader(theme, text): + case let .fontSizeHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .fontSize(theme, fontSize): return ThemeSettingsFontSizeItem(theme: theme, fontSize: fontSize, sectionId: self.section, updated: { value in @@ -316,7 +316,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { }, tag: ThemeSettingsEntryTag.fontSize) case let .chatPreview(theme, wallpaper, fontSize, chatBubbleCorners, strings, dateTimeFormat, nameDisplayOrder, items): return ThemeSettingsChatPreviewItem(context: arguments.context, theme: theme, componentTheme: theme, strings: strings, sectionId: self.section, fontSize: fontSize, chatBubbleCorners: chatBubbleCorners, wallpaper: wallpaper, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, messageItems: items) - case let .wallpaper(theme, text): + case let .wallpaper(_, text): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: { arguments.openWallpaperSettings() }) @@ -403,19 +403,19 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { }, openColorPicker: { create in arguments.openAccentColorPicker(currentTheme, create) }, tag: ThemeSettingsEntryTag.accentColor) - case let .autoNightTheme(theme, text, value): + case let .autoNightTheme(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, icon: nil, title: text, label: value, labelStyle: .text, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: { arguments.openAutoNightTheme() }) - case let .textSize(theme, text, value): + case let .textSize(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, icon: nil, title: text, label: value, labelStyle: .text, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: { arguments.openTextSize() }) - case let .bubbleSettings(theme, text, value): + case let .bubbleSettings(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, icon: nil, title: text, label: value, labelStyle: .text, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: { arguments.openBubbleSettings() }) - case let .themeListHeader(theme, text): + case let .themeListHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .themeItem(theme, strings, themes, allThemes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers, _): return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, allThemes: allThemes, displayUnsupported: true, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in @@ -429,23 +429,23 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { }, contextAction: { theme, node, gesture in arguments.themeContextAction(theme.index == currentTheme.index, theme, node, gesture) }, tag: ThemeSettingsEntryTag.theme) - case let .iconHeader(theme, text): + case let .iconHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .iconItem(theme, strings, icons, value): return ThemeSettingsAppIconItem(theme: theme, strings: strings, sectionId: self.section, icons: icons, currentIconName: value, updated: { iconName in arguments.selectAppIcon(iconName) }) - case let .otherHeader(theme, text): + case let .otherHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .largeEmoji(theme, title, value): + case let .largeEmoji(_, title, value): return ItemListSwitchItem(presentationData: presentationData, title: title, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleLargeEmoji(value) }, tag: ThemeSettingsEntryTag.largeEmoji) - case let .animations(theme, title, value): + case let .animations(_, title, value): return ItemListSwitchItem(presentationData: presentationData, title: title, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.disableAnimations(value) }, tag: ThemeSettingsEntryTag.animations) - case let .animationsInfo(theme, text): + case let .animationsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } @@ -486,7 +486,7 @@ private func themeSettingsControllerEntries(presentationData: PresentationData, } var colorOption: ThemeSettingsColorOption? - if case let .builtin(theme) = themeReference { + if case .builtin = themeReference { colorOption = presentationThemeSettings.themeSpecificAccentColors[themeReference.index].flatMap { .accentColor($0) } } else { colorOption = .theme(themeReference) @@ -656,7 +656,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The if case let .file(file) = wallpaper, file.id == 0 { return cachedWallpaper(account: context.account, slug: file.slug, settings: file.settings) |> map { cachedWallpaper in - if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper { + if let wallpaper = cachedWallpaper?.wallpaper, case .file = wallpaper { return (accentColor, wallpaper) } else { return (accentColor, .builtin(WallpaperSettings())) @@ -826,7 +826,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The return (accentColor, wallpaper) } |> mapToSignal { accentColor, wallpaper -> Signal<(PresentationTheme?, PresentationThemeReference, Bool, TelegramWallpaper?), NoError> in let generalThemeReference: PresentationThemeReference - if let accentColor = accentColor, case let .cloud(theme) = reference, let settings = theme.theme.settings { + if let _ = accentColor, case let .cloud(theme) = reference, let settings = theme.theme.settings { generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)) } else { generalThemeReference = reference @@ -998,7 +998,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The if isCurrent, let settings = cloudTheme.theme.settings { let colorThemes = themes.filter { theme in - if let settings = theme.settings { + if let _ = theme.settings { return true } else { return false @@ -1007,7 +1007,6 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The if let currentThemeIndex = colorThemes.firstIndex(where: { $0.id == cloudTheme.theme.id }) { let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil }) - let newTheme: PresentationThemeReference if let previousThemeIndex = previousThemeIndex { let theme = themes[themes.index(before: previousThemeIndex.base)] selectThemeImpl?(.cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil, creatorAccountId: theme.isCreator ? context.account.id : nil))) @@ -1254,8 +1253,6 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The wallpaperSignal = cachedWallpaper(account: context.account, slug: file.slug, settings: colorWallpaper.settings) |> mapToSignal { cachedWallpaper in if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper { - let resource = file.file.resource - let _ = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)).start() return .single(wallpaper) @@ -1292,7 +1289,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The updatedTheme = generalThemeReference } - guard let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.color, wallpaper: presetWallpaper, baseColor: accentColor?.baseColor) else { + guard let _ = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.color, wallpaper: presetWallpaper, baseColor: accentColor?.baseColor) else { return current } @@ -1300,7 +1297,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The var themeSpecificAccentColors = current.themeSpecificAccentColors themeSpecificAccentColors[generalThemeReference.index] = accentColor?.withUpdatedWallpaper(presetWallpaper) - if case let .builtin(theme) = generalThemeReference { + if case .builtin = generalThemeReference { let index = coloredThemeIndex(reference: currentTheme, accentColor: accentColor) if let wallpaper = current.themeSpecificChatWallpapers[index] { if wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin { diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift index 31869598e4..2844e935cd 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift @@ -268,7 +268,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode { } let title = NSAttributedString(string: item.title, font: item.selected ? selectedTextFont : textFont, textColor: item.selected ? item.theme.list.itemAccentColor : item.theme.list.itemPrimaryTextColor) - let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: title, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) + let (_, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: title, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) let itemLayout = ListViewItemNodeLayout(contentSize: CGSize(width: 116.0, height: 116.0), insets: UIEdgeInsets()) return (itemLayout, { animated in @@ -533,8 +533,6 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode { } func asyncLayout() -> (_ item: ThemeSettingsThemeItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { - let currentItem = self.item - return { item, params, neighbors in let contentSize: CGSize let insets: UIEdgeInsets @@ -614,14 +612,14 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode { var entries: [ThemeSettingsThemeEntry] = [] var index: Int = 0 - for var theme in item.themes { + for theme in item.themes { if case let .cloud(theme) = theme { if !item.displayUnsupported && theme.theme.file == nil { continue } } let title = themeDisplayName(strings: item.strings, reference: theme) - var accentColor = item.themeSpecificAccentColors[theme.generalThemeReference.index] + let accentColor = item.themeSpecificAccentColors[theme.generalThemeReference.index] /*if let customThemeIndex = accentColor?.themeIndex { if let customTheme = themes[customThemeIndex] { theme = customTheme diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift b/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift index 7d1f6b29c5..65aa51cdb6 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift @@ -567,20 +567,15 @@ final class WallpaperColorPanelNode: ASDisplayNode { let fieldHeight: CGFloat = 33.0 let leftInset: CGFloat let rightInset: CGFloat - let fieldSpacing: CGFloat if condensedLayout { leftInset = 6.0 rightInset = 6.0 - fieldSpacing = 40.0 } else { leftInset = 15.0 rightInset = 15.0 - fieldSpacing = 45.0 } - let rightInsetWithButton: CGFloat = 42.0 let buttonSize = CGSize(width: 26.0, height: 26.0) - let buttonOffset: CGFloat = (rightInsetWithButton - 13.0) / 2.0 //let middleButtonFrame = CGRect(origin: CGPoint(x: self.state.secondColor != nil ? floor((size.width - 26.0) / 2.0) : (self.state.secondColorAvailable ? size.width - rightInsetWithButton + floor((rightInsetWithButton - buttonSize.width) / 2.0) : size.width + buttonOffset), y: floor((topPanelHeight - buttonSize.height) / 2.0)), size: buttonSize) //transition.updateFrame(node: self.rotateButton, frame: middleButtonFrame) diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift index 2182bc581b..d9e2e886ad 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift @@ -153,7 +153,7 @@ private func updatedFileWallpaper(id: Int64? = nil, accessHash: Int64? = nil, sl intensityValue = 50 } - return .file(id: id ?? 0, accessHash: accessHash ?? 0, isCreator: false, isDefault: false, isPattern: isPattern, isDark: false, slug: slug, file: file, settings: WallpaperSettings(colors: colorValues, intensity: intensityValue, rotation: rotation)) + return .file(TelegramWallpaper.File(id: id ?? 0, accessHash: accessHash ?? 0, isCreator: false, isDefault: false, isPattern: isPattern, isDark: false, slug: slug, file: file, settings: WallpaperSettings(colors: colorValues, intensity: intensityValue, rotation: rotation))) } public class WallpaperGalleryController: ViewController { @@ -400,8 +400,8 @@ public class WallpaperGalleryController: ViewController { var doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set switch self.source { - case let .wallpaper(wallpaper): - switch wallpaper.0 { + case let .wallpaper(wallpaper, _, _, _, _, _): + switch wallpaper { case let .file(file): if file.id == 0 { doneButtonType = .none @@ -426,7 +426,6 @@ public class WallpaperGalleryController: ViewController { dismissed = true if let centralItemNode = strongSelf.galleryNode.pager.centralItemNode() as? WallpaperGalleryItemNode { let options = centralItemNode.options - let gradientColors = centralItemNode.colors if !strongSelf.entries.isEmpty { let entry = strongSelf.entries[centralItemNode.index] switch entry { @@ -514,7 +513,7 @@ public class WallpaperGalleryController: ViewController { } } } else if case let .file(file) = wallpaper, let resource = resource { - if wallpaper.isPattern, !file.settings.colors.isEmpty, let intensity = file.settings.intensity { + if wallpaper.isPattern, !file.settings.colors.isEmpty, let _ = file.settings.intensity { var data: Data? var thumbnailData: Data? if let path = strongSelf.context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { @@ -633,8 +632,8 @@ public class WallpaperGalleryController: ViewController { switch initialWallpaper { case let .color(color): strongSelf.patternPanelNode?.backgroundColors = ([color], nil, nil) - case let .gradient(_, colors, settings): - strongSelf.patternPanelNode?.backgroundColors = (colors, settings.rotation, nil) + case let .gradient(gradient): + strongSelf.patternPanelNode?.backgroundColors = (gradient.colors, gradient.settings.rotation, nil) case let .file(file) where file.isPattern: strongSelf.patternPanelNode?.backgroundColors = (file.settings.colors, file.settings.rotation, file.settings.intensity) default: @@ -653,7 +652,7 @@ public class WallpaperGalleryController: ViewController { case let .file(file): if !file.settings.colors.isEmpty { if file.settings.colors.count >= 2 { - strongSelf.updateEntries(wallpaper: .gradient(nil, file.settings.colors, WallpaperSettings(rotation: file.settings.rotation))) + strongSelf.updateEntries(wallpaper: .gradient(TelegramWallpaper.Gradient(id: nil, colors: file.settings.colors, settings: WallpaperSettings(rotation: file.settings.rotation)))) } else { strongSelf.updateEntries(wallpaper: .color(file.settings.colors[0])) } @@ -703,16 +702,6 @@ public class WallpaperGalleryController: ViewController { settings.rotation = angle strongSelf.updateEntries(wallpaper: wallpaper.withUpdatedSettings(settings)) } - - if let entry = self.currentEntry(), case let .wallpaper(wallpaper, _) = entry, case let .file(_, _, _, _, true, _, _, _ , settings) = wallpaper, !settings.colors.isEmpty { - /*if self.patternPanelNode?.backgroundColors != nil, let snapshotView = self.patternPanelNode?.scrollNode.view.snapshotContentTree() { - self.patternPanelNode?.view.addSubview(snapshotView) - snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) { [weak snapshotView] _ in - snapshotView?.removeFromSuperview() - } - }*/ - //self.patternPanelNode?.backgroundColors = ([settings.colors[0]], nil) - } if updated { if self.colorsPanelEnabled || self.patternPanelEnabled { @@ -788,22 +777,22 @@ public class WallpaperGalleryController: ViewController { entryColors = [color] } else if case let .file(file) = wallpaper, file.isPattern { entryColors = file.settings.colors - } else if case let .gradient(_, colors, _) = wallpaper { - entryColors = colors + } else if case let .gradient(gradient) = wallpaper { + entryColors = gradient.colors } } if !entryColors.isEmpty { if let pattern = pattern, case let .file(file) = pattern { let newSettings = WallpaperSettings(blur: file.settings.blur, motion: file.settings.motion, colors: entryColors, intensity: intensity) - let newWallpaper = TelegramWallpaper.file(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: pattern.isPattern, isDark: file.isDark, slug: file.slug, file: file.file, settings: newSettings) + let newWallpaper = TelegramWallpaper.file(TelegramWallpaper.File(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: pattern.isPattern, isDark: file.isDark, slug: file.slug, file: file.file, settings: newSettings)) updatedEntries.append(.wallpaper(newWallpaper, nil)) } else { if entryColors.count == 1 { let newWallpaper = TelegramWallpaper.color(entryColors[0]) updatedEntries.append(.wallpaper(newWallpaper, nil)) } else { - let newWallpaper = TelegramWallpaper.gradient(nil, entryColors, WallpaperSettings(rotation: nil)) + let newWallpaper = TelegramWallpaper.gradient(TelegramWallpaper.Gradient(id: nil, colors: entryColors, settings: WallpaperSettings(rotation: nil))) updatedEntries.append(.wallpaper(newWallpaper, nil)) } } @@ -853,9 +842,9 @@ public class WallpaperGalleryController: ViewController { case let .file(file): colors = file.settings.colors rotation = file.settings.rotation - case let .gradient(_, colorsValue, settings): - colors = colorsValue - rotation = settings.rotation + case let .gradient(gradient): + colors = gradient.colors + rotation = gradient.settings.rotation default: break } @@ -863,7 +852,7 @@ public class WallpaperGalleryController: ViewController { case .color, .file, .gradient: if let pattern = pattern, case let .file(file) = pattern { let newSettings = WallpaperSettings(blur: file.settings.blur, motion: file.settings.motion, colors: colors, intensity: intensity) - let newWallpaper = TelegramWallpaper.file(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: pattern.isPattern, isDark: file.isDark, slug: file.slug, file: file.file, settings: newSettings) + let newWallpaper = TelegramWallpaper.file(TelegramWallpaper.File(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: pattern.isPattern, isDark: file.isDark, slug: file.slug, file: file.file, settings: newSettings)) strongSelf.savedPatternWallpaper = newWallpaper strongSelf.savedPatternIntensity = intensity @@ -899,7 +888,7 @@ public class WallpaperGalleryController: ViewController { return } - var wallpaper: TelegramWallpaper = .gradient(nil, colors, WallpaperSettings(blur: false, motion: false, colors: [], intensity: nil, rotation: nil)) + var wallpaper: TelegramWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: colors, settings: WallpaperSettings(blur: false, motion: false, colors: [], intensity: nil, rotation: nil))) if case let .file(file) = currentWallpaper { wallpaper = currentWallpaper.withUpdatedSettings(WallpaperSettings(blur: false, motion: false, colors: colors, intensity: file.settings.intensity, rotation: file.settings.rotation)) @@ -983,14 +972,14 @@ public class WallpaperGalleryController: ViewController { self?.present(shareController, in: .window(.root), blockInteraction: true) } }) - case let .file(_, _, _, _, isPattern, _, slug, _, settings): - if isPattern { - if !settings.colors.isEmpty { - if settings.colors.count == 2 { - options.append("bg_color=\(UIColor(rgb: settings.colors[0]).hexString)-\(UIColor(rgb: settings.colors[1]).hexString)") - } else if settings.colors.count >= 3 { + case let .file(file): + if file.isPattern { + if !file.settings.colors.isEmpty { + if file.settings.colors.count == 2 { + options.append("bg_color=\(UIColor(rgb: file.settings.colors[0]).hexString)-\(UIColor(rgb: file.settings.colors[1]).hexString)") + } else if file.settings.colors.count >= 3 { var colorsString = "" - for color in settings.colors { + for color in file.settings.colors { if !colorsString.isEmpty { colorsString.append("~") } @@ -998,13 +987,13 @@ public class WallpaperGalleryController: ViewController { } options.append("bg_color=\(colorsString)") } else { - options.append("bg_color=\(UIColor(rgb: settings.colors[0]).hexString)") + options.append("bg_color=\(UIColor(rgb: file.settings.colors[0]).hexString)") } } - if let intensity = settings.intensity { + if let intensity = file.settings.intensity { options.append("intensity=\(intensity)") } - if let rotation = settings.rotation { + if let rotation = file.settings.rotation { options.append("rotation=\(rotation)") } } @@ -1014,15 +1003,15 @@ public class WallpaperGalleryController: ViewController { optionsString = "?\(options.joined(separator: "&"))" } - controller = ShareController(context: context, subject: .url("https://t.me/bg/\(slug)\(optionsString)")) + controller = ShareController(context: context, subject: .url("https://t.me/bg/\(file.slug)\(optionsString)")) case let .color(color): controller = ShareController(context: context, subject: .url("https://t.me/bg/\(UIColor(rgb: color).hexString)")) - case let .gradient(_, colors, _): + case let .gradient(gradient): var colorsString = "" - for color in colors { + for color in gradient.colors { if !colorsString.isEmpty { - if colors.count >= 3 { + if gradient.colors.count >= 3 { colorsString.append("~") } else { colorsString.append("-") @@ -1031,7 +1020,7 @@ public class WallpaperGalleryController: ViewController { colorsString.append(UIColor(rgb: color).hexString) } - controller = ShareController(context: context, subject:. url("https://t.me/bg/\(colorsString)")) + controller = ShareController(context: context, subject: .url("https://t.me/bg/\(colorsString)")) default: break } diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index 2d85647375..a2ffa742fa 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -301,21 +301,21 @@ final class WallpaperGalleryItemNode: GalleryItemNode { case let .wallpaper(wallpaper, _): self.nativeNode.update(wallpaper: wallpaper) - if case let .file(_, _, _, _, isPattern, _, _, _, settings) = wallpaper, isPattern { + if case let .file(file) = wallpaper, file.isPattern { self.nativeNode.isHidden = false - self.patternButtonNode.isSelected = isPattern + self.patternButtonNode.isSelected = file.isPattern - if isPattern && settings.colors.count >= 3 { + if file.isPattern && file.settings.colors.count >= 3 { self.playButtonNode.setImage(self.playButtonPlayImage, for: []) } else { self.playButtonNode.setImage(self.playButtonRotateImage, for: []) } - } else if case let .gradient(_, colors, _) = wallpaper { + } else if case let .gradient(gradient) = wallpaper { self.nativeNode.isHidden = false self.nativeNode.update(wallpaper: wallpaper) self.patternButtonNode.isSelected = false - if colors.count >= 3 { + if gradient.colors.count >= 3 { self.playButtonNode.setImage(self.playButtonPlayImage, for: []) } else { self.playButtonNode.setImage(self.playButtonRotateImage, for: []) @@ -354,7 +354,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { subtitleSignal = .single(nil) colorSignal = chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: self.context.account.postbox.mediaBox) isBlurrable = false - case let .color(color): + case .color: displaySize = CGSize(width: 1.0, height: 1.0) contentSize = displaySize signal = .single({ _ in nil }) @@ -364,7 +364,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { actionSignal = .single(defaultAction) colorSignal = chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: self.context.account.postbox.mediaBox) isBlurrable = false - case let .gradient(_, colors, settings): + case .gradient: displaySize = CGSize(width: 1.0, height: 1.0) contentSize = displaySize signal = .single({ _ in nil }) @@ -776,18 +776,18 @@ final class WallpaperGalleryItemNode: GalleryItemNode { switch entry { case let .wallpaper(wallpaper, _): switch wallpaper { - case let .file(_, _, _, _, isPattern, _, _, _, settings): - if isPattern { - if settings.colors.isEmpty { + case let .file(file): + if file.isPattern { + if file.settings.colors.isEmpty { return nil } else { - return settings.colors.map(UIColor.init(rgb:)) + return file.settings.colors.map(UIColor.init(rgb:)) } } else { return nil } - case let .gradient(_, colors, _): - return colors.map(UIColor.init(rgb:)) + case let .gradient(gradient): + return gradient.colors.map(UIColor.init(rgb:)) case let .color(color): return [UIColor(rgb: color)] default: @@ -810,11 +810,11 @@ final class WallpaperGalleryItemNode: GalleryItemNode { return } switch wallpaper { - case let .gradient(_, colors, settings): - if colors.count >= 3 { + case let .gradient(gradient): + if gradient.colors.count >= 3 { self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring)) } else { - let rotation = settings.rotation ?? 0 + let rotation = gradient.settings.rotation ?? 0 self.requestRotateGradient?((rotation + 90) % 360) } case let .file(file): @@ -952,11 +952,11 @@ final class WallpaperGalleryItemNode: GalleryItemNode { blurFrame = leftButtonFrame motionAlpha = 1.0 motionFrame = rightButtonFrame - case let .gradient(_, colors, _): + case let .gradient(gradient): motionAlpha = 0.0 patternAlpha = 1.0 - if colors.count >= 2 { + if gradient.colors.count >= 2 { playAlpha = 1.0 patternFrame = leftButtonFrame.offsetBy(dx: -centerOffset, dy: 0.0) colorsFrame = colorsFrame.offsetBy(dx: centerOffset, dy: 0.0) @@ -1022,7 +1022,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { } private func updateMessagesLayout(layout: ContainerViewLayout, offset: CGPoint, transition: ContainedViewLayoutTransition) { - var bottomInset: CGFloat = 115.0 + let bottomInset: CGFloat = 115.0 if self.patternButtonNode.isSelected || self.colorsButtonNode.isSelected { //bottomInset = 350.0 @@ -1055,8 +1055,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode { if file.settings.colors.count >= 3 { hasAnimatableGradient = true } - case let .gradient(_, colors, _): - if colors.count >= 3 { + case let .gradient(gradient): + if gradient.colors.count >= 3 { hasAnimatableGradient = true } default: @@ -1077,8 +1077,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode { if file.settings.colors.count >= 3 { hasAnimatableGradient = true } - case let .gradient(_, colors, _): - if colors.count >= 3 { + case let .gradient(gradient): + if gradient.colors.count >= 3 { hasAnimatableGradient = true } default: diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift b/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift index b9027cbba3..40ef3d92ad 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift @@ -142,19 +142,7 @@ private final class WallpaperPatternItemNode : ListViewItemNode { } func asyncLayout() -> (WallpaperPatternItem, ListViewItemLayoutParams) -> (ListViewItemNodeLayout, (Bool) -> Void) { - let currentItem = self.item - return { [weak self] item, params in - var updatedWallpaper = false - var updatedSelected = false - - if currentItem?.wallpaper != item.wallpaper { - updatedWallpaper = true - } - if currentItem?.selected != item.selected { - updatedSelected = true - } - let itemLayout = ListViewItemNodeLayout(contentSize: CGSize(width: 112.0, height: 112.0), insets: UIEdgeInsets()) return (itemLayout, { animated in if let strongSelf = self { @@ -365,7 +353,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode { var updatedWallpaper = wallpaper if case let .file(file) = updatedWallpaper { let settings = WallpaperSettings(colors: backgroundColors.0, intensity: intensity, rotation: backgroundColors.1) - updatedWallpaper = .file(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: updatedWallpaper.isPattern, isDark: file.isDark, slug: file.slug, file: file.file, settings: settings) + updatedWallpaper = .file(TelegramWallpaper.File(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: updatedWallpaper.isPattern, isDark: file.isDark, slug: file.slug, file: file.file, settings: settings)) } var selected = false @@ -432,8 +420,9 @@ final class WallpaperPatternPanelNode: ASDisplayNode { let wallpaper: TelegramWallpaper? switch initialWallpaper { - case let .file(id, accessHash, isCreator, isDefault, isPattern, isDark, slug, file, _): - wallpaper = .file(id: id, accessHash: accessHash, isCreator: isCreator, isDefault: isDefault, isPattern: isPattern, isDark: isDark, slug: slug, file: file, settings: self.wallpapers[0].settings ?? WallpaperSettings()) + case var .file(file): + file.settings = self.wallpapers[0].settings ?? WallpaperSettings() + wallpaper = .file(file) default: wallpaper = self.wallpapers.first } @@ -503,9 +492,9 @@ final class WallpaperPatternPanelNode: ASDisplayNode { transition.updateFrame(node: self.scrollNode, frame: scrollViewFrame) let labelSize = self.labelNode.updateLayout(self.bounds.size) - var combinedHeight = labelSize.height + 34.0 + let combinedHeight = labelSize.height + 34.0 - var originY: CGFloat = scrollViewFrame.maxY + floor((size.height - scrollViewFrame.maxY - combinedHeight) / 2.0) + let originY: CGFloat = scrollViewFrame.maxY + floor((size.height - scrollViewFrame.maxY - combinedHeight) / 2.0) transition.updateFrame(node: self.labelNode, frame: CGRect(origin: CGPoint(x: 14.0, y: originY), size: labelSize)) self.sliderView?.frame = CGRect(origin: CGPoint(x: 15.0, y: originY + 8.0), size: CGSize(width: size.width - 15.0 * 2.0, height: 44.0)) diff --git a/submodules/SettingsUI/Sources/UsernameSetupController.swift b/submodules/SettingsUI/Sources/UsernameSetupController.swift index 7deddbc21e..11a86a6b54 100644 --- a/submodules/SettingsUI/Sources/UsernameSetupController.swift +++ b/submodules/SettingsUI/Sources/UsernameSetupController.swift @@ -94,12 +94,12 @@ private enum UsernameSetupEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! UsernameSetupControllerArguments switch self { - case let .editablePublicLink(theme, strings, prefix, currentText, text): + case let .editablePublicLink(theme, _, prefix, currentText, text): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: prefix, textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .username, spacing: 10.0, clearType: .always, tag: UsernameEntryTag.username, sectionId: self.section, textUpdated: { updatedText in arguments.updatePublicLinkText(currentText, updatedText) }, action: { }) - case let .publicLinkInfo(theme, text): + case let .publicLinkInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section, linkAction: { action in if case .tap = action { arguments.shareLink() diff --git a/submodules/SettingsUI/Sources/Watch/WatchSettingsController.swift b/submodules/SettingsUI/Sources/Watch/WatchSettingsController.swift index 6327a204fe..3584a1b00d 100644 --- a/submodules/SettingsUI/Sources/Watch/WatchSettingsController.swift +++ b/submodules/SettingsUI/Sources/Watch/WatchSettingsController.swift @@ -77,13 +77,13 @@ private enum WatchSettingsControllerEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! WatchSettingsControllerArguments switch self { - case let .replyPresetsHeader(theme, text): + case let .replyPresetsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .replyPreset(theme, strings, identifier, placeholder, value, _): + case let .replyPreset(_, _, identifier, placeholder, value, _): return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: ""), text: value, placeholder: placeholder, type: .regular(capitalization: true, autocorrection: true), spacing: 0.0, sectionId: self.section, textUpdated: { updatedText in arguments.updatePreset(identifier, updatedText.trimmingCharacters(in: .whitespacesAndNewlines)) }, action: {}) - case let .replyPresetsInfo(theme, text): + case let .replyPresetsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) } } @@ -113,9 +113,6 @@ private func watchSettingsControllerEntries(presentationData: PresentationData, } public func watchSettingsController(context: AccountContext) -> ViewController { - var pushControllerImpl: ((ViewController) -> Void)? - var presentControllerImpl: ((ViewController) -> Void)? - let updateDisposable = MetaDisposable() let arguments = WatchSettingsControllerArguments(updatePreset: { identifier, text in updateDisposable.set((.complete() |> delay(1.0, queue: Queue.mainQueue()) |> then(updateWatchPresetSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in @@ -141,12 +138,6 @@ public func watchSettingsController(context: AccountContext) -> ViewController { } let controller = ItemListController(context: context, state: signal) - pushControllerImpl = { [weak controller] c in - (controller?.navigationController as? NavigationController)?.pushViewController(c) - } - presentControllerImpl = { [weak controller] c in - controller?.present(c, in: .window(.root)) - } return controller } diff --git a/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift b/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift index ec1a7572a7..95bd44981b 100644 --- a/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift +++ b/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift @@ -138,7 +138,7 @@ private class CallStatusBarBackgroundNode: ASDisplayNode { } private func setupGradientAnimations() { - if let _ = self.foregroundGradientLayer.animation(forKey: "movement") { + /*if let _ = self.foregroundGradientLayer.animation(forKey: "movement") { } else { let previousValue = self.foregroundGradientLayer.startPoint let newValue: CGPoint @@ -162,7 +162,7 @@ private class CallStatusBarBackgroundNode: ASDisplayNode { self.foregroundGradientLayer.add(animation, forKey: "movement") CATransaction.commit() - } + }*/ } func updateAnimations() { @@ -172,7 +172,9 @@ private class CallStatusBarBackgroundNode: ASDisplayNode { return } self.setupGradientAnimations() - self.maskCurveView.startAnimating() + if isCurrentlyInHierarchy { + self.maskCurveView.startAnimating() + } } } @@ -206,6 +208,9 @@ public class CallStatusBarNodeImpl: CallStatusBarNode { private var currentScheduleTimestamp: Int32? private var currentMembers: PresentationGroupCallMembers? private var currentIsConnected = true + + private let hierarchyTrackingNode: HierarchyTrackingNode + private var isCurrentlyInHierarchy = true public override init() { self.backgroundNode = CallStatusBarBackgroundNode() @@ -213,13 +218,29 @@ public class CallStatusBarNodeImpl: CallStatusBarNode { self.subtitleNode = ImmediateAnimatedCountLabelNode() self.subtitleNode.reverseAnimationDirection = true self.speakerNode = ImmediateTextNode() + + var updateInHierarchy: ((Bool) -> Void)? + self.hierarchyTrackingNode = HierarchyTrackingNode({ value in + updateInHierarchy?(value) + }) super.init() + + self.addSubnode(self.hierarchyTrackingNode) self.addSubnode(self.backgroundNode) self.addSubnode(self.titleNode) self.addSubnode(self.subtitleNode) self.addSubnode(self.speakerNode) + + updateInHierarchy = { [weak self] value in + if let strongSelf = self { + strongSelf.isCurrentlyInHierarchy = value + if value { + strongSelf.update() + } + } + } } deinit { @@ -231,13 +252,17 @@ public class CallStatusBarNodeImpl: CallStatusBarNode { public func update(content: Content) { self.currentContent = content - self.update() + if self.isCurrentlyInHierarchy { + self.update() + } } public override func update(size: CGSize) { self.currentSize = size self.update() } + + private let textFont = Font.with(size: 13.0, design: .regular, weight: .regular, traits: [.monospacedNumbers]) private func update() { guard let size = self.currentSize, let content = self.currentContent else { @@ -329,8 +354,10 @@ public class CallStatusBarNodeImpl: CallStatusBarNode { currentIsConnected = false } strongSelf.currentIsConnected = currentIsConnected - - strongSelf.update() + + if strongSelf.isCurrentlyInHierarchy { + strongSelf.update() + } } })) self.audioLevelDisposable.set((combineLatest(call.myAudioLevel, .single([]) |> then(call.audioLevels)) @@ -351,8 +378,7 @@ public class CallStatusBarNodeImpl: CallStatusBarNode { var title: String = "" var speakerSubtitle: String = "" - - let textFont = Font.with(size: 13.0, design: .regular, weight: .regular, traits: [.monospacedNumbers]) + let textColor = UIColor.white var segments: [AnimatedCountLabelNode.Segment] = [] var displaySpeakerSubtitle = false diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift index 2b6b756bbf..b6b3160275 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift @@ -1249,6 +1249,9 @@ private final class VoiceBlobView: UIView { private(set) var isAnimating = false public typealias BlobRange = (min: CGFloat, max: CGFloat) + + private let hierarchyTrackingNode: HierarchyTrackingNode + private var isCurrentlyInHierarchy = true public init( frame: CGRect, @@ -1256,6 +1259,11 @@ private final class VoiceBlobView: UIView { mediumBlobRange: BlobRange, bigBlobRange: BlobRange ) { + var updateInHierarchy: ((Bool) -> Void)? + self.hierarchyTrackingNode = HierarchyTrackingNode({ value in + updateInHierarchy?(value) + }) + self.maxLevel = maxLevel self.mediumBlob = BlobView( @@ -1278,18 +1286,30 @@ private final class VoiceBlobView: UIView { ) super.init(frame: frame) + + addSubnode(hierarchyTrackingNode) addSubview(bigBlob) addSubview(mediumBlob) displayLinkAnimator = ConstantDisplayLinkAnimator() { [weak self] in guard let strongSelf = self else { return } + + if !strongSelf.isCurrentlyInHierarchy { + return + } strongSelf.presentationAudioLevel = strongSelf.presentationAudioLevel * 0.9 + strongSelf.audioLevel * 0.1 strongSelf.mediumBlob.level = strongSelf.presentationAudioLevel strongSelf.bigBlob.level = strongSelf.presentationAudioLevel } + + updateInHierarchy = { [weak self] value in + if let strongSelf = self { + strongSelf.isCurrentlyInHierarchy = value + } + } } required init?(coder: NSCoder) { diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatFullscreenParticipantItem.swift b/submodules/TelegramCallsUI/Sources/VoiceChatFullscreenParticipantItem.swift index 209ef94c91..68eeba736b 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatFullscreenParticipantItem.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatFullscreenParticipantItem.swift @@ -202,6 +202,15 @@ class VoiceChatFullscreenParticipantItemNode: ItemListRevealOptionsItemNode { var item: VoiceChatFullscreenParticipantItem? { return self.layoutParams?.0 } + + private var isCurrentlyInHierarchy = false { + didSet { + if self.isCurrentlyInHierarchy != oldValue { + self.highlightNode.isCurrentlyInHierarchy = self.isCurrentlyInHierarchy + } + } + } + private var isCurrentlyInHierarchyDisposable: Disposable? init() { self.contextSourceNode = ContextExtractedContentContainingNode() @@ -247,7 +256,7 @@ class VoiceChatFullscreenParticipantItemNode: ItemListRevealOptionsItemNode { self.actionContainerNode = ASDisplayNode() self.actionButtonNode = HighlightableButtonNode() - + super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true @@ -293,6 +302,7 @@ class VoiceChatFullscreenParticipantItemNode: ItemListRevealOptionsItemNode { self.audioLevelDisposable.dispose() self.raiseHandTimer?.invalidate() self.silenceTimer?.invalidate() + self.isCurrentlyInHierarchyDisposable?.dispose() } override func selected() { @@ -971,6 +981,16 @@ class VoiceChatFullscreenParticipantItemNode: ItemListRevealOptionsItemNode { transition.updateFrame(node: strongSelf.actionButtonNode, frame: animationFrame) strongSelf.updateIsHighlighted(transition: transition) + + if strongSelf.isCurrentlyInHierarchyDisposable == nil { + strongSelf.isCurrentlyInHierarchyDisposable = (item.context.sharedContext.applicationBindings.applicationInForeground + |> deliverOnMainQueue).start(next: { value in + guard let strongSelf = self else { + return + } + strongSelf.isCurrentlyInHierarchy = value + }) + } } }) } diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatTileItemNode.swift b/submodules/TelegramCallsUI/Sources/VoiceChatTileItemNode.swift index fe02c08b24..1c926dc39f 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatTileItemNode.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatTileItemNode.swift @@ -157,6 +157,9 @@ final class VoiceChatTileItemNode: ASDisplayNode { private var isExtracted = false private let audioLevelDisposable = MetaDisposable() + + private let hierarchyTrackingNode: HierarchyTrackingNode + private var isCurrentlyInHierarchy = false init(context: AccountContext) { self.context = context @@ -201,7 +204,14 @@ final class VoiceChatTileItemNode: ASDisplayNode { self.placeholderIconNode.contentMode = .scaleAspectFit self.placeholderIconNode.displaysAsynchronously = false + var updateInHierarchy: ((Bool) -> Void)? + self.hierarchyTrackingNode = HierarchyTrackingNode({ value in + updateInHierarchy?(value) + }) + super.init() + + self.addSubnode(self.hierarchyTrackingNode) self.containerNode.addSubnode(self.contextSourceNode) self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode @@ -236,6 +246,13 @@ final class VoiceChatTileItemNode: ASDisplayNode { } strongSelf.updateIsExtracted(isExtracted, transition: transition) } + + updateInHierarchy = { [weak self] value in + if let strongSelf = self { + strongSelf.isCurrentlyInHierarchy = value + strongSelf.highlightNode.isCurrentlyInHierarchy = value + } + } } deinit { @@ -634,9 +651,14 @@ class VoiceChatTileHighlightNode: ASDisplayNode { private let maskLayer = CALayer() private let foregroundGradientLayer = CAGradientLayer() - - private let hierarchyTrackingNode: HierarchyTrackingNode - private var isCurrentlyInHierarchy = false + + var isCurrentlyInHierarchy = false { + didSet { + if self.isCurrentlyInHierarchy != oldValue && self.isCurrentlyInHierarchy { + self.updateAnimations() + } + } + } private var audioLevel: CGFloat = 0.0 private var presentationAudioLevel: CGFloat = 0.0 @@ -650,27 +672,13 @@ class VoiceChatTileHighlightNode: ASDisplayNode { self.foregroundGradientLayer.startPoint = CGPoint(x: 1.0, y: 0.0) self.foregroundGradientLayer.endPoint = CGPoint(x: 0.0, y: 1.0) - var updateInHierarchy: ((Bool) -> Void)? - self.hierarchyTrackingNode = HierarchyTrackingNode({ value in - updateInHierarchy?(value) - }) - super.init() - updateInHierarchy = { [weak self] value in - if let strongSelf = self { - strongSelf.isCurrentlyInHierarchy = value - strongSelf.updateAnimations() - } - } - self.displayLinkAnimator = ConstantDisplayLinkAnimator() { [weak self] in guard let strongSelf = self else { return } strongSelf.presentationAudioLevel = strongSelf.presentationAudioLevel * 0.9 + strongSelf.audioLevel * 0.1 } - - self.addSubnode(self.hierarchyTrackingNode) } override func didLoad() { @@ -733,8 +741,11 @@ class VoiceChatTileHighlightNode: ASDisplayNode { animation.toValue = newValue CATransaction.setCompletionBlock { [weak self] in - if let isCurrentlyInHierarchy = self?.isCurrentlyInHierarchy, isCurrentlyInHierarchy { - self?.setupGradientAnimations() + guard let strongSelf = self else { + return + } + if strongSelf.isCurrentlyInHierarchy { + strongSelf.setupGradientAnimations() } } diff --git a/submodules/TelegramCore/Sources/ApiUtils/Wallpaper.swift b/submodules/TelegramCore/Sources/ApiUtils/Wallpaper.swift index d535d5fd15..91badb59b0 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/Wallpaper.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/Wallpaper.swift @@ -71,7 +71,7 @@ extension TelegramWallpaper { } else { wallpaperSettings = WallpaperSettings() } - self = .file(id: id, accessHash: accessHash, isCreator: (flags & 1 << 0) != 0, isDefault: (flags & 1 << 1) != 0, isPattern: (flags & 1 << 3) != 0, isDark: (flags & 1 << 4) != 0, slug: slug, file: file, settings: wallpaperSettings) + self = .file(TelegramWallpaper.File(id: id, accessHash: accessHash, isCreator: (flags & 1 << 0) != 0, isDefault: (flags & 1 << 1) != 0, isPattern: (flags & 1 << 3) != 0, isDark: (flags & 1 << 4) != 0, slug: slug, file: file, settings: wallpaperSettings)) } else { //assertionFailure() self = .color(0xffffff) @@ -82,7 +82,7 @@ extension TelegramWallpaper { return color.flatMap(UInt32.init(bitPattern:)) }) if colors.count > 1 { - self = .gradient(id, colors, WallpaperSettings(rotation: rotation)) + self = .gradient(TelegramWallpaper.Gradient(id: id, colors: colors, settings: WallpaperSettings(rotation: rotation))) } else if colors.count == 1 { self = .color(UInt32(bitPattern: colors[0])) } else { @@ -99,12 +99,12 @@ extension TelegramWallpaper { switch self { case .builtin: return nil - case let .file(_, _, _, _, _, _, slug, _, settings): - return (.inputWallPaperSlug(slug: slug), apiWallpaperSettings(settings)) + case let .file(file): + return (.inputWallPaperSlug(slug: file.slug), apiWallpaperSettings(file.settings)) case let .color(color): return (.inputWallPaperNoFile(id: 0), apiWallpaperSettings(WallpaperSettings(colors: [color]))) - case let .gradient(id, colors, settings): - return (.inputWallPaperNoFile(id: id ?? 0), apiWallpaperSettings(WallpaperSettings(colors: colors, rotation: settings.rotation))) + case let .gradient(gradient): + return (.inputWallPaperNoFile(id: gradient.id ?? 0), apiWallpaperSettings(WallpaperSettings(colors: gradient.colors, rotation: gradient.settings.rotation))) default: return nil } diff --git a/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift b/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift index 22dd00e4a1..08bbca5c45 100644 --- a/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift +++ b/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift @@ -676,8 +676,8 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali return .single(RevalidatedMediaResource(updatedResource: representation.resource, updatedReference: nil)) } } - case let .file(_, _, _, _, _, _, _, file, _): - if let updatedResource = findUpdatedMediaResource(media: file, previousMedia: nil, resource: resource) { + case let .file(file): + if let updatedResource = findUpdatedMediaResource(media: file.file, previousMedia: nil, resource: resource) { return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil)) } default: diff --git a/submodules/TelegramCore/Sources/Network/Network.swift b/submodules/TelegramCore/Sources/Network/Network.swift index 62b4749b69..d374004222 100644 --- a/submodules/TelegramCore/Sources/Network/Network.swift +++ b/submodules/TelegramCore/Sources/Network/Network.swift @@ -1093,13 +1093,25 @@ class Keychain: NSObject, MTKeychain { } func setObject(_ object: Any!, forKey aKey: String!, group: String!) { - let data = NSKeyedArchiver.archivedData(withRootObject: object) - self.set(group + ":" + aKey, data) + guard let object = object else { + return + } + MTContext.perform(objCTry: { + let data = NSKeyedArchiver.archivedData(withRootObject: object) + self.set(group + ":" + aKey, data) + }) } func object(forKey aKey: String!, group: String!) -> Any! { + guard let aKey = aKey, let group = group else { + return nil + } if let data = self.get(group + ":" + aKey) { - return NSKeyedUnarchiver.unarchiveObject(with: data as Data) + var result: Any? + MTContext.perform(objCTry: { + result = NSKeyedUnarchiver.unarchiveObject(with: data as Data) + }) + return result } return nil } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramWallpaper.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramWallpaper.swift index baf2a7aba0..05e7b0224d 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramWallpaper.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramWallpaper.swift @@ -69,11 +69,61 @@ public struct WallpaperSettings: PostboxCoding, Equatable { } public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { + public struct Gradient: Equatable { + public var id: Int64? + public var colors: [UInt32] + public var settings: WallpaperSettings + + public init( + id: Int64?, + colors: [UInt32], + settings: WallpaperSettings + ) { + self.id = id + self.colors = colors + self.settings = settings + } + } + + public struct File: Equatable { + public var id: Int64 + public var accessHash: Int64 + public var isCreator: Bool + public var isDefault: Bool + public var isPattern: Bool + public var isDark: Bool + public var slug: String + public var file: TelegramMediaFile + public var settings: WallpaperSettings + + public init( + id: Int64, + accessHash: Int64, + isCreator: Bool, + isDefault: Bool, + isPattern: Bool, + isDark: Bool, + slug: String, + file: TelegramMediaFile, + settings: WallpaperSettings + ) { + self.id = id + self.accessHash = accessHash + self.isCreator = isCreator + self.isDefault = isDefault + self.isPattern = isPattern + self.isDark = isDark + self.slug = slug + self.file = file + self.settings = settings + } + } + case builtin(WallpaperSettings) case color(UInt32) - case gradient(Int64?, [UInt32], WallpaperSettings) + case gradient(Gradient) case image([TelegramMediaImageRepresentation], WallpaperSettings) - case file(id: Int64, accessHash: Int64, isCreator: Bool, isDefault: Bool, isPattern: Bool, isDark: Bool, slug: String, file: TelegramMediaFile, settings: WallpaperSettings) + case file(File) public init(decoder: PostboxDecoder) { switch decoder.decodeInt32ForKey("v", orElse: 0) { @@ -88,7 +138,7 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { case 3: let settings = decoder.decodeObjectForKey("settings", decoder: { WallpaperSettings(decoder: $0) }) as? WallpaperSettings ?? WallpaperSettings() if let file = decoder.decodeObjectForKey("file", decoder: { TelegramMediaFile(decoder: $0) }) as? TelegramMediaFile { - self = .file(id: decoder.decodeInt64ForKey("id", orElse: 0), accessHash: decoder.decodeInt64ForKey("accessHash", orElse: 0), isCreator: decoder.decodeInt32ForKey("isCreator", orElse: 0) != 0, isDefault: decoder.decodeInt32ForKey("isDefault", orElse: 0) != 0, isPattern: decoder.decodeInt32ForKey("isPattern", orElse: 0) != 0, isDark: decoder.decodeInt32ForKey("isDark", orElse: 0) != 0, slug: decoder.decodeStringForKey("slug", orElse: ""), file: file, settings: settings) + self = .file(File(id: decoder.decodeInt64ForKey("id", orElse: 0), accessHash: decoder.decodeInt64ForKey("accessHash", orElse: 0), isCreator: decoder.decodeInt32ForKey("isCreator", orElse: 0) != 0, isDefault: decoder.decodeInt32ForKey("isDefault", orElse: 0) != 0, isPattern: decoder.decodeInt32ForKey("isPattern", orElse: 0) != 0, isDark: decoder.decodeInt32ForKey("isDark", orElse: 0) != 0, slug: decoder.decodeStringForKey("slug", orElse: ""), file: file, settings: settings)) } else { self = .color(0xffffff) } @@ -106,7 +156,7 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { colors = decoder.decodeInt32ArrayForKey("colors").map(UInt32.init(bitPattern:)) } - self = .gradient(decoder.decodeOptionalInt64ForKey("id"), colors, settings) + self = .gradient(Gradient(id: decoder.decodeOptionalInt64ForKey("id"), colors: colors, settings: settings)) default: assertionFailure() self = .color(0xffffff) @@ -130,30 +180,30 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { case let .color(color): encoder.encodeInt32(1, forKey: "v") encoder.encodeInt32(Int32(bitPattern: color), forKey: "c") - case let .gradient(id, colors, settings): + case let .gradient(gradient): encoder.encodeInt32(4, forKey: "v") - if let id = id { + if let id = gradient.id { encoder.encodeInt64(id, forKey: "id") } else { encoder.encodeNil(forKey: "id") } - encoder.encodeInt32Array(colors.map(Int32.init(bitPattern:)), forKey: "colors") - encoder.encodeObject(settings, forKey: "settings") + encoder.encodeInt32Array(gradient.colors.map(Int32.init(bitPattern:)), forKey: "colors") + encoder.encodeObject(gradient.settings, forKey: "settings") case let .image(representations, settings): encoder.encodeInt32(2, forKey: "v") encoder.encodeObjectArray(representations, forKey: "i") encoder.encodeObject(settings, forKey: "settings") - case let .file(id, accessHash, isCreator, isDefault, isPattern, isDark, slug, file, settings): + case let .file(file): encoder.encodeInt32(3, forKey: "v") - encoder.encodeInt64(id, forKey: "id") - encoder.encodeInt64(accessHash, forKey: "accessHash") - encoder.encodeInt32(isCreator ? 1 : 0, forKey: "isCreator") - encoder.encodeInt32(isDefault ? 1 : 0, forKey: "isDefault") - encoder.encodeInt32(isPattern ? 1 : 0, forKey: "isPattern") - encoder.encodeInt32(isDark ? 1 : 0, forKey: "isDark") - encoder.encodeString(slug, forKey: "slug") - encoder.encodeObject(file, forKey: "file") - encoder.encodeObject(settings, forKey: "settings") + encoder.encodeInt64(file.id, forKey: "id") + encoder.encodeInt64(file.accessHash, forKey: "accessHash") + encoder.encodeInt32(file.isCreator ? 1 : 0, forKey: "isCreator") + encoder.encodeInt32(file.isDefault ? 1 : 0, forKey: "isDefault") + encoder.encodeInt32(file.isPattern ? 1 : 0, forKey: "isPattern") + encoder.encodeInt32(file.isDark ? 1 : 0, forKey: "isDark") + encoder.encodeString(file.slug, forKey: "slug") + encoder.encodeObject(file.file, forKey: "file") + encoder.encodeObject(file.settings, forKey: "settings") } } @@ -171,8 +221,8 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { } else { return false } - case let .gradient(id, colors, settings): - if case .gradient(id, colors, settings) = rhs { + case let .gradient(gradient): + if case .gradient(gradient) = rhs { return true } else { return false @@ -183,8 +233,8 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { } else { return false } - case let .file(lhsId, _, lhsIsCreator, lhsIsDefault, lhsIsPattern, lhsIsDark, lhsSlug, lhsFile, lhsSettings): - if case let .file(rhsId, _, rhsIsCreator, rhsIsDefault, rhsIsPattern, rhsIsDark, rhsSlug, rhsFile, rhsSettings) = rhs, lhsId == rhsId, lhsIsCreator == rhsIsCreator, lhsIsDefault == rhsIsDefault, lhsIsPattern == rhsIsPattern, lhsIsDark == rhsIsDark, lhsSlug == rhsSlug, lhsFile.id == rhsFile.id, lhsSettings == rhsSettings { + case let .file(file): + if case .file(file) = rhs { return true } else { return false @@ -206,8 +256,8 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { } else { return false } - case let .gradient(_, colors, _): - if case .gradient(_, colors, _) = wallpaper { + case let .gradient(lhsGradient): + if case let .gradient(rhsGradient) = wallpaper, lhsGradient.colors == rhsGradient.colors { return true } else { return false @@ -218,8 +268,8 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { } else { return false } - case let .file(_, _, _, _, _, _, lhsSlug, _, lhsSettings): - if case let .file(_, _, _, _, _, _, rhsSlug, _, rhsSettings) = wallpaper, lhsSlug == rhsSlug, lhsSettings.colors == rhsSettings.colors && lhsSettings.intensity == rhsSettings.intensity { + case let .file(lhsFile): + if case let .file(rhsFile) = wallpaper, lhsFile.slug == rhsFile.slug, lhsFile.settings.colors == rhsFile.settings.colors, lhsFile.settings.intensity == rhsFile.settings.intensity { return true } else { return false @@ -229,25 +279,31 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { public var settings: WallpaperSettings? { switch self { - case let .builtin(settings), let .gradient(_, _, settings), let .image(_, settings), let .file(_, _, _, _, _, _, _, _, settings): - return settings - default: - return nil + case let .builtin(settings), let .image(_, settings): + return settings + case let .file(file): + return file.settings + case let .gradient(gradient): + return gradient.settings + default: + return nil } } public func withUpdatedSettings(_ settings: WallpaperSettings) -> TelegramWallpaper { switch self { - case .builtin: - return .builtin(settings) - case .color: - return self - case let .gradient(id, colors, _): - return .gradient(id, colors, settings) - case let .image(representations, _): - return .image(representations, settings) - case let .file(id, accessHash, isCreator, isDefault, isPattern, isDark, slug, file, _): - return .file(id: id, accessHash: accessHash, isCreator: isCreator, isDefault: isDefault, isPattern: isPattern, isDark: isDark, slug: slug, file: file, settings: settings) + case .builtin: + return .builtin(settings) + case .color: + return self + case var .gradient(gradient): + gradient.settings = settings + return .gradient(gradient) + case let .image(representations, _): + return .image(representations, settings) + case var .file(file): + file.settings = settings + return .file(file) } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/Configuration.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/Configuration.swift new file mode 100644 index 0000000000..48f702ccad --- /dev/null +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/Configuration.swift @@ -0,0 +1,93 @@ +import SwiftSignalKit +import Postbox + +public enum EngineConfiguration { + public struct Limits: Equatable { + public static let timeIntervalForever: Int32 = 0x7fffffff + + public var maxPinnedChatCount: Int32 + public var maxArchivedPinnedChatCount: Int32 + public var maxGroupMemberCount: Int32 + public var maxSupergroupMemberCount: Int32 + public var maxMessageForwardBatchSize: Int32 + public var maxSavedGifCount: Int32 + public var maxRecentStickerCount: Int32 + public var maxMessageEditingInterval: Int32 + public var maxMediaCaptionLength: Int32 + public var canRemoveIncomingMessagesInPrivateChats: Bool + public var maxMessageRevokeInterval: Int32 + public var maxMessageRevokeIntervalInPrivateChats: Int32 + + public init( + maxPinnedChatCount: Int32, + maxArchivedPinnedChatCount: Int32, + maxGroupMemberCount: Int32, + maxSupergroupMemberCount: Int32, + maxMessageForwardBatchSize: Int32, + maxSavedGifCount: Int32, + maxRecentStickerCount: Int32, + maxMessageEditingInterval: Int32, + maxMediaCaptionLength: Int32, + canRemoveIncomingMessagesInPrivateChats: Bool, + maxMessageRevokeInterval: Int32, + maxMessageRevokeIntervalInPrivateChats: Int32 + ) { + self.maxPinnedChatCount = maxPinnedChatCount + self.maxArchivedPinnedChatCount = maxArchivedPinnedChatCount + self.maxGroupMemberCount = maxGroupMemberCount + self.maxSupergroupMemberCount = maxSupergroupMemberCount + self.maxMessageForwardBatchSize = maxMessageForwardBatchSize + self.maxSavedGifCount = maxSavedGifCount + self.maxRecentStickerCount = maxRecentStickerCount + self.maxMessageEditingInterval = maxMessageEditingInterval + self.maxMediaCaptionLength = maxMediaCaptionLength + self.canRemoveIncomingMessagesInPrivateChats = canRemoveIncomingMessagesInPrivateChats + self.maxMessageRevokeInterval = maxMessageRevokeInterval + self.maxMessageRevokeIntervalInPrivateChats = maxMessageRevokeIntervalInPrivateChats + } + } +} + +extension EngineConfiguration.Limits { + init(_ limitsConfiguration: LimitsConfiguration) { + self.init( + maxPinnedChatCount: limitsConfiguration.maxPinnedChatCount, + maxArchivedPinnedChatCount: limitsConfiguration.maxArchivedPinnedChatCount, + maxGroupMemberCount: limitsConfiguration.maxGroupMemberCount, + maxSupergroupMemberCount: limitsConfiguration.maxSupergroupMemberCount, + maxMessageForwardBatchSize: limitsConfiguration.maxMessageForwardBatchSize, + maxSavedGifCount: limitsConfiguration.maxSavedGifCount, + maxRecentStickerCount: limitsConfiguration.maxRecentStickerCount, + maxMessageEditingInterval: limitsConfiguration.maxMessageEditingInterval, + maxMediaCaptionLength: limitsConfiguration.maxMediaCaptionLength, + canRemoveIncomingMessagesInPrivateChats: limitsConfiguration.canRemoveIncomingMessagesInPrivateChats, + maxMessageRevokeInterval: limitsConfiguration.maxMessageRevokeInterval, + maxMessageRevokeIntervalInPrivateChats: limitsConfiguration.maxMessageRevokeIntervalInPrivateChats + ) + } +} + +public extension TelegramEngine.EngineData.Item { + enum Configuration { + public struct Limits: TelegramEngineDataItem, PostboxViewDataItem { + public typealias Result = EngineConfiguration.Limits + + public init() { + } + + var key: PostboxViewKey { + return .preferences(keys: Set([PreferencesKeys.limitsConfiguration])) + } + + func extract(view: PostboxView) -> Result { + guard let view = view as? PreferencesView else { + preconditionFailure() + } + guard let limitsConfiguration = view.values[PreferencesKeys.limitsConfiguration] as? LimitsConfiguration else { + return EngineConfiguration.Limits(LimitsConfiguration.defaultValue) + } + return EngineConfiguration.Limits(limitsConfiguration) + } + } + } +} diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift index 76f87ccb93..c66ee732f4 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift @@ -495,8 +495,8 @@ public extension TelegramEngine { return _internal_updatePeerDescription(account: self.account, peerId: peerId, description: description) } - public func getNextUnreadChannel(peerId: PeerId, filter: ChatListFilterPredicate?) -> Signal { - return self.account.postbox.transaction { transaction -> EnginePeer? in + public func getNextUnreadChannel(peerId: PeerId, filter: ChatListFilterPredicate?) -> Signal<(peer: EnginePeer, unreadCount: Int)?, NoError> { + return self.account.postbox.transaction { transaction -> (peer: EnginePeer, unreadCount: Int)? in var results: [(EnginePeer, Int32)] = [] var peerIds: [PeerId] = [] @@ -525,7 +525,12 @@ public extension TelegramEngine { results.sort(by: { $0.1 > $1.1 }) - return results.first?.0 + if let peer = results.first?.0 { + let unreadCount: Int32 = transaction.getCombinedPeerReadState(peer.id)?.count ?? 0 + return (peer: peer, unreadCount: Int(unreadCount)) + } else { + return nil + } } } diff --git a/submodules/TelegramCore/Sources/Wallpapers.swift b/submodules/TelegramCore/Sources/Wallpapers.swift index eab0ab7c11..56c724eadc 100644 --- a/submodules/TelegramCore/Sources/Wallpapers.swift +++ b/submodules/TelegramCore/Sources/Wallpapers.swift @@ -148,10 +148,10 @@ public func deleteWallpaper(account: Account, wallpaper: TelegramWallpaper) -> S } private func saveUnsaveWallpaper(account: Account, wallpaper: TelegramWallpaper, unsave: Bool) -> Signal { - guard case let .file(_, _, _, _, _, _, slug, _, settings) = wallpaper else { + guard case let .file(file) = wallpaper else { return .complete() } - return account.network.request(Api.functions.account.saveWallPaper(wallpaper: Api.InputWallPaper.inputWallPaperSlug(slug: slug), unsave: unsave ? Api.Bool.boolTrue : Api.Bool.boolFalse, settings: apiWallpaperSettings(settings))) + return account.network.request(Api.functions.account.saveWallPaper(wallpaper: Api.InputWallPaper.inputWallPaperSlug(slug: file.slug), unsave: unsave ? Api.Bool.boolTrue : Api.Bool.boolFalse, settings: apiWallpaperSettings(file.settings))) |> `catch` { _ -> Signal in return .complete() } @@ -161,16 +161,16 @@ private func saveUnsaveWallpaper(account: Account, wallpaper: TelegramWallpaper, } public func installWallpaper(account: Account, wallpaper: TelegramWallpaper) -> Signal { - guard case let .file(id, accessHash, _, _, _, _, slug, _, settings) = wallpaper else { + guard case let .file(file) = wallpaper else { return .complete() } let inputWallpaper: Api.InputWallPaper - if id != 0 && accessHash != 0 { - inputWallpaper = .inputWallPaper(id: id, accessHash: accessHash) + if file.id != 0 && file.accessHash != 0 { + inputWallpaper = .inputWallPaper(id: file.id, accessHash: file.accessHash) } else { - inputWallpaper = .inputWallPaperSlug(slug: slug) + inputWallpaper = .inputWallPaperSlug(slug: file.slug) } - return account.network.request(Api.functions.account.installWallPaper(wallpaper: inputWallpaper, settings: apiWallpaperSettings(settings))) + return account.network.request(Api.functions.account.installWallPaper(wallpaper: inputWallpaper, settings: apiWallpaperSettings(file.settings))) |> `catch` { _ -> Signal in return .complete() } diff --git a/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift b/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift index 7f339b778f..f8fc943be9 100644 --- a/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift +++ b/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift @@ -42,19 +42,19 @@ public func chatControllerBackgroundImage(theme: PresentationTheme?, wallpaper i context.setFillColor(UIColor(argb: color).withAlphaComponent(1.0).cgColor) context.fill(CGRect(origin: CGPoint(), size: size)) }) - case let .gradient(_, colors, settings): + case let .gradient(gradient): backgroundImage = generateImage(CGSize(width: 640.0, height: 1280.0), rotatedContext: { size, context in - let gradientColors = [UIColor(argb: colors.count >= 1 ? colors[0] : 0).cgColor, UIColor(argb: colors.count >= 2 ? colors[1] : 0).cgColor] as CFArray + let gradientColors = [UIColor(argb: gradient.colors.count >= 1 ? gradient.colors[0] : 0).cgColor, UIColor(argb: gradient.colors.count >= 2 ? gradient.colors[1] : 0).cgColor] as CFArray var locations: [CGFloat] = [0.0, 1.0] let colorSpace = CGColorSpaceCreateDeviceRGB() - let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! + let cgGradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! context.translateBy(x: 320.0, y: 640.0) - context.rotate(by: CGFloat(settings.rotation ?? 0) * CGFloat.pi / 180.0) + context.rotate(by: CGFloat(gradient.settings.rotation ?? 0) * CGFloat.pi / 180.0) context.translateBy(x: -320.0, y: -640.0) - context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) + context.drawLinearGradient(cgGradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) }) case let .image(representations, settings): if let largest = largestImageRepresentation(representations) { @@ -72,20 +72,20 @@ public func chatControllerBackgroundImage(theme: PresentationTheme?, wallpaper i backgroundImage = UIImage(contentsOfFile: path)?.precomposed() } } - case let .file(_, _, _, _, _, _, _, file, settings): + case let .file(file): if wallpaper.isPattern { backgroundImage = nil } else { - if settings.blur && composed { + if file.settings.blur && composed { var image: UIImage? - let _ = mediaBox.cachedResourceRepresentation(file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true, attemptSynchronously: true).start(next: { data in + let _ = mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true, attemptSynchronously: true).start(next: { data in if data.complete { image = UIImage(contentsOfFile: data.path)?.precomposed() } }) backgroundImage = image } - if backgroundImage == nil, let path = mediaBox.completedResourcePath(file.resource) { + if backgroundImage == nil, let path = mediaBox.completedResourcePath(file.file.resource) { succeed = false backgroundImage = UIImage(contentsOfFile: path)?.precomposed() } @@ -128,19 +128,19 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me |> afterNext { image in cacheWallpaper(image?.0) } - case let .gradient(_, colors, settings): + case let .gradient(gradient): return .single((generateImage(CGSize(width: 640.0, height: 1280.0).fitted(CGSize(width: 100.0, height: 100.0)), rotatedContext: { size, context in - let gradientColors = [UIColor(rgb: colors.count >= 1 ? colors[0] : 0).cgColor, UIColor(rgb: colors.count >= 2 ? colors[1] : 0).cgColor] as CFArray + let gradientColors = [UIColor(rgb: gradient.colors.count >= 1 ? gradient.colors[0] : 0).cgColor, UIColor(rgb: gradient.colors.count >= 2 ? gradient.colors[1] : 0).cgColor] as CFArray var locations: [CGFloat] = [0.0, 1.0] let colorSpace = CGColorSpaceCreateDeviceRGB() - let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! + let cgGradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! context.translateBy(x: size.width / 2.0, y: size.height / 2.0) - context.rotate(by: CGFloat(settings.rotation ?? 0) * CGFloat.pi / 180.0) + context.rotate(by: CGFloat(gradient.settings.rotation ?? 0) * CGFloat.pi / 180.0) context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0) - context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) + context.drawLinearGradient(cgGradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) }), true)) |> afterNext { image in cacheWallpaper(image?.0) @@ -166,17 +166,17 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me } } } - case let .file(_, _, _, _, _, _, slug, file, settings): + case let .file(file): if wallpaper.isPattern { return .single((nil, true)) } else { - if settings.blur { + if file.settings.blur { let representation = CachedBlurredWallpaperRepresentation() - if FileManager.default.fileExists(atPath: mediaBox.cachedRepresentationCompletePath(file.resource.id, representation: representation)) { + if FileManager.default.fileExists(atPath: mediaBox.cachedRepresentationCompletePath(file.file.resource.id, representation: representation)) { let effectiveMediaBox = mediaBox - return effectiveMediaBox.cachedResourceRepresentation(file.resource, representation: representation, complete: true, fetch: true, attemptSynchronously: true) + return effectiveMediaBox.cachedResourceRepresentation(file.file.resource, representation: representation, complete: true, fetch: true, attemptSynchronously: true) |> map { data -> (UIImage?, Bool)? in if data.complete { return (UIImage(contentsOfFile: data.path)?.precomposed(), true) @@ -189,17 +189,17 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me } } else { return Signal { subscriber in - let fetch = fetchedMediaResource(mediaBox: accountMediaBox, reference: MediaResourceReference.wallpaper(wallpaper: WallpaperReference.slug(slug), resource: file.resource)).start() + let fetch = fetchedMediaResource(mediaBox: accountMediaBox, reference: MediaResourceReference.wallpaper(wallpaper: WallpaperReference.slug(file.slug), resource: file.file.resource)).start() var didOutputBlurred = false - let data = accountMediaBox.cachedResourceRepresentation(file.resource, representation: representation, complete: true, fetch: true, attemptSynchronously: true).start(next: { data in + let data = accountMediaBox.cachedResourceRepresentation(file.file.resource, representation: representation, complete: true, fetch: true, attemptSynchronously: true).start(next: { data in if data.complete { if let image = UIImage(contentsOfFile: data.path)?.precomposed() { - mediaBox.copyResourceData(file.resource.id, fromTempPath: data.path) + mediaBox.copyResourceData(file.file.resource.id, fromTempPath: data.path) subscriber.putNext((image, true)) } } else if !didOutputBlurred { didOutputBlurred = true - if let immediateThumbnailData = file.immediateThumbnailData, let decodedData = decodeTinyThumbnail(data: immediateThumbnailData) { + if let immediateThumbnailData = file.file.immediateThumbnailData, let decodedData = decodeTinyThumbnail(data: immediateThumbnailData) { if let image = UIImage(data: decodedData)?.precomposed() { subscriber.putNext((image, false)) } @@ -215,9 +215,9 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me } } else { var path: String? - if let maybePath = mediaBox.completedResourcePath(file.resource) { + if let maybePath = mediaBox.completedResourcePath(file.file.resource) { path = maybePath - } else if let maybePath = accountMediaBox.completedResourcePath(file.resource) { + } else if let maybePath = accountMediaBox.completedResourcePath(file.file.resource) { path = maybePath } if let path = path { @@ -227,17 +227,17 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me } } else { return Signal { subscriber in - let fetch = fetchedMediaResource(mediaBox: accountMediaBox, reference: MediaResourceReference.wallpaper(wallpaper: WallpaperReference.slug(slug), resource: file.resource)).start() + let fetch = fetchedMediaResource(mediaBox: accountMediaBox, reference: MediaResourceReference.wallpaper(wallpaper: WallpaperReference.slug(file.slug), resource: file.file.resource)).start() var didOutputBlurred = false - let data = accountMediaBox.resourceData(file.resource).start(next: { data in + let data = accountMediaBox.resourceData(file.file.resource).start(next: { data in if data.complete { if let image = UIImage(contentsOfFile: data.path)?.precomposed() { - mediaBox.copyResourceData(file.resource.id, fromTempPath: data.path) + mediaBox.copyResourceData(file.file.resource.id, fromTempPath: data.path) subscriber.putNext((image, true)) } } else if !didOutputBlurred { didOutputBlurred = true - if let immediateThumbnailData = file.immediateThumbnailData, let decodedData = decodeTinyThumbnail(data: immediateThumbnailData) { + if let immediateThumbnailData = file.file.immediateThumbnailData, let decodedData = decodeTinyThumbnail(data: immediateThumbnailData) { if let image = UIImage(data: decodedData)?.precomposed() { subscriber.putNext((image, false)) } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift index cca43e6c1b..f1ced61ca5 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift @@ -132,7 +132,7 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit defaultWallpaper = defaultBuiltinWallpaper(data: variant, colors: colors, intensity: intensity) } else if !backgroundColors.isEmpty { if backgroundColors.count >= 2 { - defaultWallpaper = .gradient(nil, backgroundColors, WallpaperSettings()) + defaultWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: backgroundColors, settings: WallpaperSettings())) } else { defaultWallpaper = .color(backgroundColors[0]) } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift index 7ded181b4b..23341096d1 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift @@ -260,7 +260,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme defaultWallpaper = forcedWallpaper } else if !backgroundColors.isEmpty { if backgroundColors.count >= 2 { - defaultWallpaper = .gradient(nil, backgroundColors, WallpaperSettings()) + defaultWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: backgroundColors, settings: WallpaperSettings())) } else { defaultWallpaper = .color(backgroundColors[0]) } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index 0a261f4621..c0adf9e41d 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -20,8 +20,8 @@ public func dateFillNeedsBlur(theme: PresentationTheme, wallpaper: TelegramWallp return false } else if case .color = wallpaper { return false - } else if case let .file(_, _, _, _, isPattern, _, _, _, settings) = wallpaper { - if isPattern, let intensity = settings.intensity, intensity < 0 { + } else if case let .file(file) = wallpaper { + if file.isPattern, let intensity = file.settings.intensity, intensity < 0 { return false } else { return true @@ -66,10 +66,10 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti outgoingAccent = accentColor } - suggestedWallpaper = .gradient(nil, defaultBuiltinWallpaperGradientColors.map(\.rgb), WallpaperSettings()) + suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: defaultBuiltinWallpaperGradientColors.map(\.rgb), settings: WallpaperSettings())) } else { bubbleColors = (UIColor(rgb: 0xe1ffc7), nil) - suggestedWallpaper = .gradient(nil, defaultBuiltinWallpaperGradientColors.map(\.rgb), WallpaperSettings()) + suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: defaultBuiltinWallpaperGradientColors.map(\.rgb), settings: WallpaperSettings())) } } } @@ -228,7 +228,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti defaultWallpaper = forcedWallpaper } else if !backgroundColors.isEmpty { if backgroundColors.count >= 2 { - defaultWallpaper = .gradient(nil, backgroundColors, WallpaperSettings()) + defaultWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: backgroundColors, settings: WallpaperSettings())) } else { defaultWallpaper = .color(backgroundColors[0]) } @@ -1013,19 +1013,19 @@ public extension BuiltinWallpaperData { signals.append(getWallpaper(network: account.network, slug: slug) |> map { wallpaper -> String? in switch wallpaper { - case let .file(id, accessHash, _, _, _, _, _, file, _): - guard let resource = file.resource as? CloudDocumentMediaResource else { + case let .file(file): + guard let resource = file.file.resource as? CloudDocumentMediaResource else { return nil } - guard let size = file.size else { + guard let size = file.file.size else { return nil } return """ static let \(name) = BuiltinWallpaperData( - wallpaperId: \(id), - wallpaperAccessHash: \(accessHash), + wallpaperId: \(file.id), + wallpaperAccessHash: \(file.accessHash), slug: "\(slug)", - fileId: \(file.fileId.id), + fileId: \(file.file.fileId.id), fileAccessHash: \(resource.accessHash), datacenterId: \(resource.datacenterId), fileSize: \(size) @@ -1055,7 +1055,7 @@ static let \(name) = BuiltinWallpaperData( } public func defaultBuiltinWallpaper(data: BuiltinWallpaperData, colors: [UInt32], intensity: Int32 = 50, rotation: Int32? = nil) -> TelegramWallpaper { - return .file( + return .file(TelegramWallpaper.File( id: data.wallpaperId, accessHash: data.wallpaperAccessHash, isCreator: false, @@ -1098,5 +1098,5 @@ public func defaultBuiltinWallpaper(data: BuiltinWallpaperData, colors: [UInt32] ] ), settings: WallpaperSettings(colors: colors, intensity: intensity, rotation: rotation) - ) + )) } diff --git a/submodules/TelegramPresentationData/Sources/PresentationData.swift b/submodules/TelegramPresentationData/Sources/PresentationData.swift index 726ddce651..1c84b844d6 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationData.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationData.swift @@ -444,9 +444,9 @@ public func serviceColor(for wallpaper: (TelegramWallpaper, UIImage?)) -> UIColo return UIColor(rgb: 0x748391, alpha: 0.45) case let .color(color): return serviceColor(with: UIColor(argb: color)) - case let .gradient(_, colors, _): - if colors.count == 2 { - let mixedColor = UIColor(argb: colors[0]).mixedWith(UIColor(argb: colors[1]), alpha: 0.5) + case let .gradient(gradient): + if gradient.colors.count == 2 { + let mixedColor = UIColor(argb: gradient.colors[0]).mixedWith(UIColor(argb: gradient.colors[1]), alpha: 0.5) return serviceColor(with: mixedColor) } else { return UIColor(rgb: 0x000000, alpha: 0.3) @@ -457,12 +457,12 @@ public func serviceColor(for wallpaper: (TelegramWallpaper, UIImage?)) -> UIColo } else { return UIColor(rgb: 0x000000, alpha: 0.3) } - case let .file(_, _, _, _, _, _, _, _, settings): + case let .file(file): if wallpaper.0.isPattern { - if settings.colors.count >= 1 && settings.colors.count <= 2 { - var mixedColor = UIColor(argb: settings.colors[0]) - if settings.colors.count >= 2 { - mixedColor = mixedColor.mixedWith(UIColor(argb: settings.colors[1]), alpha: 0.5) + if file.settings.colors.count >= 1 && file.settings.colors.count <= 2 { + var mixedColor = UIColor(argb: file.settings.colors[0]) + if file.settings.colors.count >= 2 { + mixedColor = mixedColor.mixedWith(UIColor(argb: file.settings.colors[1]), alpha: 0.5) } return serviceColor(with: mixedColor) } else { @@ -503,9 +503,9 @@ public func chatServiceBackgroundColor(wallpaper: TelegramWallpaper, mediaBox: M return .single(UIColor(rgb: 0x000000, alpha: 0.2)) case let .color(color): return .single(serviceColor(with: UIColor(argb: color))) - case let .gradient(_, colors, _): - if colors.count == 2 { - let mixedColor = UIColor(argb: colors[0]).mixedWith(UIColor(argb: colors[1]), alpha: 0.5) + case let .gradient(gradient): + if gradient.colors.count == 2 { + let mixedColor = UIColor(argb: gradient.colors[0]).mixedWith(UIColor(argb: gradient.colors[1]), alpha: 0.5) return .single( serviceColor(with: mixedColor)) } else { @@ -531,12 +531,12 @@ public func chatServiceBackgroundColor(wallpaper: TelegramWallpaper, mediaBox: M } else { return .single(UIColor(rgb: 0x000000, alpha: 0.3)) } - case let .file(_, _, _, _, _, _, _, file, settings): + case let .file(file): if wallpaper.isPattern { - if settings.colors.count >= 1 && settings.colors.count <= 2 { - var mixedColor = UIColor(argb: settings.colors[0]) - if settings.colors.count >= 2 { - mixedColor = mixedColor.mixedWith(UIColor(argb: settings.colors[1]), alpha: 0.5) + if file.settings.colors.count >= 1 && file.settings.colors.count <= 2 { + var mixedColor = UIColor(argb: file.settings.colors[0]) + if file.settings.colors.count >= 2 { + mixedColor = mixedColor.mixedWith(UIColor(argb: file.settings.colors[1]), alpha: 0.5) } return .single(serviceColor(with: mixedColor)) } else { @@ -544,7 +544,7 @@ public func chatServiceBackgroundColor(wallpaper: TelegramWallpaper, mediaBox: M } } else { return Signal { subscriber in - let data = serviceColor(for: mediaBox.resourceData(file.resource)).start(next: { next in + let data = serviceColor(for: mediaBox.resourceData(file.file.resource)).start(next: { next in subscriber.putNext(next) }, completed: { subscriber.putCompletion() diff --git a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift index a9a4a31a22..1a04568e4a 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift @@ -64,7 +64,7 @@ extension TelegramWallpaper: Codable { } } - self = .gradient(nil, [topColor.argb, bottomColor.argb], WallpaperSettings(blur: blur, motion: motion, rotation: rotation)) + self = .gradient(TelegramWallpaper.Gradient(id: nil, colors: [topColor.argb, bottomColor.argb], settings: WallpaperSettings(blur: blur, motion: motion, rotation: rotation))) } else { var slug: String? var colors: [UInt32] = [] @@ -98,7 +98,7 @@ extension TelegramWallpaper: Codable { } } if let slug = slug { - self = .file(id: 0, accessHash: 0, isCreator: false, isDefault: false, isPattern: !colors.isEmpty, isDark: false, slug: slug, file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: WallpaperDataResource(slug: slug), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(blur: blur, motion: motion, colors: colors, intensity: intensity, rotation: rotation)) + self = .file(TelegramWallpaper.File(id: 0, accessHash: 0, isCreator: false, isDefault: false, isPattern: !colors.isEmpty, isDark: false, slug: slug, file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: WallpaperDataResource(slug: slug), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(blur: blur, motion: motion, colors: colors, intensity: intensity, rotation: rotation))) } else { throw PresentationThemeDecodingError.generic } @@ -117,48 +117,48 @@ extension TelegramWallpaper: Codable { try container.encode("builtin") case let .color(color): try container.encode(String(format: "%06x", color)) - case let .gradient(_, colors, settings): + case let .gradient(gradient): var components: [String] = [] - for color in colors { + for color in gradient.colors { components.append(String(format: "%06x", color)) } - if let rotation = settings.rotation { + if let rotation = gradient.settings.rotation { components.append("\(rotation)") } - if settings.motion { + if gradient.settings.motion { components.append("motion") } - if settings.blur { + if gradient.settings.blur { components.append("blur") } try container.encode(components.joined(separator: " ")) - case let .file(_, _, _, _, _, _, slug, _, settings): + case let .file(file): var components: [String] = [] - components.append(slug) + components.append(file.slug) if self.isPattern { - if settings.colors.count >= 1 { - components.append(String(format: "%06x", settings.colors[0])) + if file.settings.colors.count >= 1 { + components.append(String(format: "%06x", file.settings.colors[0])) } - if let intensity = settings.intensity { + if let intensity = file.settings.intensity { components.append("\(intensity)") } - if settings.colors.count >= 2 { - components.append(String(format: "%06x", settings.colors[1])) + if file.settings.colors.count >= 2 { + components.append(String(format: "%06x", file.settings.colors[1])) } - if settings.colors.count >= 3 { - components.append(String(format: "%06x", settings.colors[2])) + if file.settings.colors.count >= 3 { + components.append(String(format: "%06x", file.settings.colors[2])) } - if settings.colors.count >= 4 { - components.append(String(format: "%06x", settings.colors[3])) + if file.settings.colors.count >= 4 { + components.append(String(format: "%06x", file.settings.colors[3])) } - if let rotation = settings.rotation, rotation != 0 { + if let rotation = file.settings.rotation, rotation != 0 { components.append("\(rotation)") } } - if settings.motion { + if file.settings.motion { components.append("motion") } - if settings.blur { + if file.settings.blur { components.append("blur") } try container.encode(components.joined(separator: " ")) diff --git a/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift b/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift index e2e8423c67..e077993a22 100644 --- a/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift +++ b/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift @@ -7,8 +7,8 @@ public extension TelegramWallpaper { switch self { case .image: return false - case let .file(_, _, _, _, _, _, _, _, settings): - if self.isPattern, settings.colors.count == 1 && (settings.colors[0] == 0xffffff || settings.colors[0] == 0xffffffff) { + case let .file(file): + if self.isPattern, file.settings.colors.count == 1 && (file.settings.colors[0] == 0xffffff || file.settings.colors[0] == 0xffffffff) { return true } else { return false @@ -31,8 +31,8 @@ public extension TelegramWallpaper { var isPattern: Bool { switch self { - case let .file(_, _, _, _, isPattern, _, _, file, _): - return isPattern || file.mimeType == "application/x-tgwallpattern" + case let .file(file): + return file.isPattern || file.file.mimeType == "application/x-tgwallpattern" default: return false } @@ -48,8 +48,8 @@ public extension TelegramWallpaper { } var dimensions: CGSize? { - if case let .file(_, _, _, _, _, _, _, file, _) = self { - return file.dimensions?.cgSize + if case let .file(file) = self { + return file.file.dimensions?.cgSize } else { return nil } diff --git a/submodules/TelegramUI/Images.xcassets/Chat/OverscrollArrow.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/OverscrollArrow.imageset/Contents.json new file mode 100644 index 0000000000..85134c7af4 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/OverscrollArrow.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "drag.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/OverscrollArrow.imageset/drag.svg b/submodules/TelegramUI/Images.xcassets/Chat/OverscrollArrow.imageset/drag.svg new file mode 100644 index 0000000000..7be68b60aa --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/OverscrollArrow.imageset/drag.svg @@ -0,0 +1,3 @@ + + + diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index ec899be627..c4106e2d41 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -3324,10 +3324,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } strongSelf.chatDisplayNode.historyNode.offerNextChannelToRead = true - strongSelf.chatDisplayNode.historyNode.nextChannelToRead = nextPeer + strongSelf.chatDisplayNode.historyNode.nextChannelToRead = nextPeer.flatMap { nextPeer -> (peer: EnginePeer, unreadCount: Int) in + return (peer: nextPeer.peer, unreadCount: nextPeer.unreadCount) + } strongSelf.chatDisplayNode.historyNode.nextChannelToReadDisplayName = nextChatSuggestionTip >= 3 - let nextPeerId = nextPeer?.id + let nextPeerId = nextPeer?.peer.id if strongSelf.preloadNextChatPeerId != nextPeerId { strongSelf.preloadNextChatPeerId = nextPeerId @@ -4239,7 +4241,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return message } |> distinctUntilChanged - case let .replyThread(replyThreadMessage): + case .replyThread: return .single(nil) } return topPinnedMessage @@ -7078,7 +7080,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } if let navigationController = strongSelf.effectiveNavigationController { - ApplicationSpecificNotice.incrementNextChatSuggestionTip(accountManager: strongSelf.context.sharedContext.accountManager).start() + let _ = ApplicationSpecificNotice.incrementNextChatSuggestionTip(accountManager: strongSelf.context.sharedContext.accountManager).start() let snapshotState = strongSelf.chatDisplayNode.prepareSnapshotState( titleViewSnapshotState: strongSelf.chatTitleView?.prepareSnapshotState(), @@ -7219,7 +7221,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } self.tempVoicePlaylistItemChanged = { [weak self] previousItem, currentItem in - guard let strongSelf = self, case let .peer(peerId) = strongSelf.chatLocation else { + guard let strongSelf = self, case .peer = strongSelf.chatLocation else { return } @@ -7508,7 +7510,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let avatarSnapshotState = snapshotState.avatarSnapshotState { (self.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.animateFromSnapshot(avatarSnapshotState) } - self.chatDisplayNode.animateFromSnapshot(snapshotState) + self.chatDisplayNode.animateFromSnapshot(snapshotState, completion: { [weak self] in + guard let strongSelf = self else { + return + } + strongSelf.chatDisplayNode.historyNode.preloadPages = true + }) + } else { + self.chatDisplayNode.historyNode.preloadPages = true } } @@ -9689,7 +9698,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private func presentPollCreation(isQuiz: Bool? = nil) { if let peer = self.presentationInterfaceState.renderedPeer?.peer { - self.effectiveNavigationController?.pushViewController(createPollController(context: self.context, peer: peer, isQuiz: isQuiz, completion: { [weak self] message in + self.effectiveNavigationController?.pushViewController(createPollController(context: self.context, peer: EnginePeer(peer), isQuiz: isQuiz, completion: { [weak self] message in guard let strongSelf = self else { return } @@ -10481,7 +10490,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self else { return } - let complete = results.completed strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { current in if let data = current.search, let previousResultsState = data.resultsState { let messageIndices = results.messages.map({ $0.index }).sorted() @@ -11398,7 +11406,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G cancelImpl = { [weak self] in self?.resolvePeerByNameDisposable?.set(nil) } - let account = self.context.account disposable.set((resolveSignal |> take(1) |> mapToSignal { peer -> Signal in @@ -11427,7 +11434,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if self.resolvePeerByNameDisposable == nil { self.resolvePeerByNameDisposable = MetaDisposable() } - let account = self.context.account var resolveSignal: Signal if let peerName = peerName { resolveSignal = self.context.engine.peers.resolvePeerByName(name: peerName) diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 176fb878ce..878ac42dd9 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -107,6 +107,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { private var titleAccessoryPanelNode: ChatTitleAccessoryPanelNode? private var inputPanelNode: ChatInputPanelNode? + private(set) var inputPanelOverscrollNode: ChatInputPanelOverscrollNode? private weak var currentDismissedInputPanelNode: ASDisplayNode? private var secondaryInputPanelNode: ChatInputPanelNode? private(set) var accessoryPanelNode: AccessoryPanelNode? @@ -372,12 +373,12 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { var backgroundColors: [UInt32] = [] switch chatPresentationInterfaceState.chatWallpaper { - case let .file(_, _, _, _, isPattern, _, _, _, settings): - if isPattern { - backgroundColors = settings.colors + case let .file(file): + if file.isPattern { + backgroundColors = file.settings.colors } - case let .gradient(_, colors, _): - backgroundColors = colors + case let .gradient(gradient): + backgroundColors = gradient.colors case let .color(color): backgroundColors = [color] default: @@ -819,7 +820,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } else { insets = layout.insets(options: [.input]) } - + if case .overlay = self.chatPresentationInterfaceState.mode { insets.top = 44.0 } else { @@ -1149,7 +1150,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } var displayTopDimNode = false - var ensureTopInsetForOverlayHighlightedItems: CGFloat? + let ensureTopInsetForOverlayHighlightedItems: CGFloat? = nil var expandTopDimNode = false if case let .media(_, expanded, _) = self.chatPresentationInterfaceState.inputMode, expanded != nil { displayTopDimNode = true @@ -1165,7 +1166,6 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { topInset -= UIScreenPixel } } - let topFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: max(0.0, topInset))) let inputPanelOrigin = layout.size.height - insets.bottom - bottomOverflowOffset - inputPanelsHeight @@ -1283,11 +1283,6 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { let inputContextPanelsFrame = CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: max(0.0, layout.size.height - insets.bottom - inputPanelsHeight - insets.top))) let inputContextPanelsOverMainPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: max(0.0, layout.size.height - insets.bottom - (inputPanelSize == nil ? CGFloat(0.0) : inputPanelSize!.height) - insets.top))) - if transition.isAnimated, let derivedLayoutState = self.derivedLayoutState { - let offset = derivedLayoutState.inputContextPanelsOverMainPanelFrame.maxY - inputContextPanelsOverMainPanelFrame.maxY - //transition.animateOffsetAdditive(node: self.inputContextPanelContainer, offset: -offset) - } - if let inputContextPanelNode = self.inputContextPanelNode { let panelFrame = inputContextPanelNode.placement == .overTextInput ? inputContextPanelsOverMainPanelFrame : inputContextPanelsFrame if immediatelyLayoutInputContextPanelAndAnimateAppearance { @@ -2496,6 +2491,18 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } } + var shouldAllowOverscrollActions: Bool { + if let inputPanelNode = self.inputPanelNode as? ChatTextInputPanelNode { + if inputPanelNode.isFocused { + return false + } + if !inputPanelNode.text.isEmpty { + return false + } + } + return true + } + final class SnapshotState { fileprivate let historySnapshotState: ChatHistoryListNode.SnapshotState let titleViewSnapshotState: ChatTitleView.SnapshotState? @@ -2540,8 +2547,8 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { ) } - func animateFromSnapshot(_ snapshotState: SnapshotState) { - self.historyNode.animateFromSnapshot(snapshotState.historySnapshotState) + func animateFromSnapshot(_ snapshotState: SnapshotState, completion: @escaping () -> Void) { + self.historyNode.animateFromSnapshot(snapshotState.historySnapshotState, completion: completion) self.navigateButtons.animateFromSnapshot(snapshotState.navigationButtonsSnapshotState) if let titleAccessoryPanelSnapshot = snapshotState.titleAccessoryPanelSnapshot { @@ -2577,4 +2584,54 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } } } + + private var preivousChatInputPanelOverscrollNodeTimestamp: Double = 0.0 + + func setChatInputPanelOverscrollNode(overscrollNode: ChatInputPanelOverscrollNode?) { + let directionUp: Bool + if let overscrollNode = overscrollNode { + if let current = self.inputPanelOverscrollNode { + directionUp = current.priority > overscrollNode.priority + } else { + directionUp = true + } + } else { + directionUp = false + } + + let transition: ContainedViewLayoutTransition = .animated(duration: 0.15, curve: .easeInOut) + + let timestamp = CFAbsoluteTimeGetCurrent() + if self.preivousChatInputPanelOverscrollNodeTimestamp > timestamp - 0.05 { + if let inputPanelOverscrollNode = self.inputPanelOverscrollNode { + self.inputPanelOverscrollNode = nil + inputPanelOverscrollNode.removeFromSupernode() + } + } + self.preivousChatInputPanelOverscrollNodeTimestamp = timestamp + + if let inputPanelOverscrollNode = self.inputPanelOverscrollNode { + self.inputPanelOverscrollNode = nil + inputPanelOverscrollNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: directionUp ? -5.0 : 5.0), duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true) + inputPanelOverscrollNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak inputPanelOverscrollNode] _ in + inputPanelOverscrollNode?.removeFromSupernode() + }) + } + + if let inputPanelNode = self.inputPanelNode, let overscrollNode = overscrollNode { + self.inputPanelOverscrollNode = overscrollNode + inputPanelNode.supernode?.insertSubnode(overscrollNode, aboveSubnode: inputPanelNode) + + overscrollNode.frame = inputPanelNode.frame + overscrollNode.update(size: overscrollNode.bounds.size) + + overscrollNode.layer.animatePosition(from: CGPoint(x: 0.0, y: directionUp ? 5.0 : -5.0), to: CGPoint(), duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, additive: true) + overscrollNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15) + } + + if let inputPanelNode = self.inputPanelNode { + transition.updateAlpha(node: inputPanelNode, alpha: overscrollNode == nil ? 1.0 : 0.0) + transition.updateSublayerTransformOffset(layer: inputPanelNode.layer, offset: CGPoint(x: 0.0, y: overscrollNode == nil ? 0.0 : -5.0)) + } + } } diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index a5a9a8a2f9..a8e0771e13 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -549,10 +549,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { var isSelectionGestureEnabled = true private var overscrollView: ComponentHostView? - var nextChannelToRead: EnginePeer? + var nextChannelToRead: (peer: EnginePeer, unreadCount: Int)? var offerNextChannelToRead: Bool = false var nextChannelToReadDisplayName: Bool = false private var currentOverscrollExpandProgress: CGFloat = 0.0 + private var freezeOverscrollControl: Bool = false private var feedback: HapticFeedback? var openNextChannelToRead: ((EnginePeer) -> Void)? @@ -628,7 +629,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } } - self.preloadPages = true + self.preloadPages = false switch self.mode { case .bubbles: self.transform = CATransform3DMakeRotation(CGFloat(Double.pi), 0.0, 0.0, 1.0) @@ -1094,7 +1095,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let previousTheme = strongSelf.currentPresentationData.theme let previousStrings = strongSelf.currentPresentationData.strings let previousWallpaper = strongSelf.currentPresentationData.theme.wallpaper - let previousDisableAnimations = strongSelf.currentPresentationData.disableAnimations let previousAnimatedEmojiScale = strongSelf.currentPresentationData.animatedEmojiScale let animatedEmojiConfig = ChatHistoryAnimatedEmojiConfiguration.with(appConfiguration: appConfiguration) @@ -1171,7 +1171,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { guard let strongSelf = self else { return } - if let channel = strongSelf.nextChannelToRead, strongSelf.currentOverscrollExpandProgress >= 0.99 { + if let channel = strongSelf.nextChannelToRead?.peer, strongSelf.currentOverscrollExpandProgress >= 0.99 { + strongSelf.freezeOverscrollControl = true strongSelf.openNextChannelToRead?(channel) } } @@ -1207,7 +1208,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } private func maybeUpdateOverscrollAction(offset: CGFloat?) { - if let offset = offset, offset < 0.0, self.offerNextChannelToRead { + if self.freezeOverscrollControl { + return + } + if let offset = offset, offset < 0.0, self.offerNextChannelToRead, let chatControllerNode = self.controllerInteraction.chatControllerNode() as? ChatControllerNode, chatControllerNode.shouldAllowOverscrollActions { let overscrollView: ComponentHostView if let current = self.overscrollView { overscrollView = current @@ -1221,24 +1225,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let expandDistance = max(-offset - 12.0, 0.0) let expandProgress: CGFloat = min(1.0, expandDistance / 90.0) - let text: String - if let nextChannelToRead = nextChannelToRead { - if self.nextChannelToReadDisplayName { - if expandProgress >= 0.99 { - //TODO:localize - text = "Release to go to \(nextChannelToRead.compactDisplayTitle)" - } else { - text = "Swipe up to go to \(nextChannelToRead.compactDisplayTitle)" - } - } else { - if expandProgress >= 0.99 { - //TODO:localize - text = "Release to go to the next unread channel" - } else { - text = "Swipe up to go to the next unread channel" - } - } - + if let _ = nextChannelToRead { let previousType = self.currentOverscrollExpandProgress >= 0.99 let currentType = expandProgress >= 0.99 @@ -1250,27 +1237,45 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } self.currentOverscrollExpandProgress = expandProgress + } + + if expandProgress < 0.1 || self.nextChannelToRead == nil { + chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: nil) + } else if expandProgress >= 0.99 { + //TODO:localize + let text: String = "Release to go to the next unread channel" + if chatControllerNode.inputPanelOverscrollNode?.text != text { + chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: ChatInputPanelOverscrollNode(text: text, color: self.currentPresentationData.theme.theme.rootController.navigationBar.secondaryTextColor, priority: 1)) + } } else { - text = "You have no unread channels" + //TODO:localize + let text: String = "Swipe up to go to the next unread channel" + if chatControllerNode.inputPanelOverscrollNode?.text != text { + chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: ChatInputPanelOverscrollNode(text: text, color: self.currentPresentationData.theme.theme.rootController.navigationBar.secondaryTextColor, priority: 2)) + } } let overscrollSize = overscrollView.update( transition: .immediate, component: AnyComponent(ChatOverscrollControl( - text: text, backgroundColor: selectDateFillStaticColor(theme: self.currentPresentationData.theme.theme, wallpaper: self.currentPresentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: self.currentPresentationData.theme.theme.chat.serviceMessage.dateTextColor, wallpaper: self.currentPresentationData.theme.wallpaper), - peer: self.nextChannelToRead, + peer: self.nextChannelToRead?.peer, + unreadCount: self.nextChannelToRead?.unreadCount ?? 0, context: self.context, expandDistance: expandDistance )), environment: {}, containerSize: CGSize(width: self.bounds.width, height: 200.0) ) - overscrollView.frame = CGRect(origin: CGPoint(x: floor((self.bounds.width - overscrollSize.width) / 2.0), y: -offset + self.insets.top - overscrollSize.height - 10.0), size: overscrollSize) + overscrollView.frame = CGRect(origin: CGPoint(x: floor((self.bounds.width - overscrollSize.width) / 2.0), y: self.insets.top), size: overscrollSize) } else if let overscrollView = self.overscrollView { self.overscrollView = nil overscrollView.removeFromSuperview() + + if let chatControllerNode = self.controllerInteraction.chatControllerNode() as? ChatControllerNode { + chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: nil) + } } } @@ -1311,8 +1316,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { var messageIdsWithUnsupportedMedia: [MessageId] = [] var messageIdsWithRefreshMedia: [MessageId] = [] var messageIdsWithUnseenPersonalMention: [MessageId] = [] - var messagesWithPreloadableMediaToEarlier: [(Message, Media)] = [] - var messagesWithPreloadableMediaToLater: [(Message, Media)] = [] if indexRange.0 <= indexRange.1 { for i in (indexRange.0 ... indexRange.1) { @@ -1593,7 +1596,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } else if case let .MessageGroupEntry(_, messages, _) = entry { currentMessage = messages.first?.0 } - if let message = currentMessage, let anchorMessage = self.anchorMessageInCurrentHistoryView() { + if let message = currentMessage, let _ = self.anchorMessageInCurrentHistoryView() { self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .message(message.index), anchorIndex: .message(message.index), sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true, highlight: false), id: self.takeNextHistoryLocationId()) } } @@ -2466,7 +2469,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { ) } - func animateFromSnapshot(_ snapshotState: SnapshotState) { + func animateFromSnapshot(_ snapshotState: SnapshotState, completion: @escaping () -> Void) { var snapshotTopInset: CGFloat = 0.0 var snapshotBottomInset: CGFloat = 0.0 self.forEachItemNode { itemNode in @@ -2488,6 +2491,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { snapshotParentView.layer.animatePosition(from: CGPoint(x: 0.0, y: 0.0), to: CGPoint(x: 0.0, y: -self.view.bounds.height - snapshotState.snapshotBottomInset - snapshotTopInset), duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true, completion: { [weak snapshotParentView] _ in snapshotParentView?.removeFromSuperview() + completion() }) self.view.layer.animatePosition(from: CGPoint(x: 0.0, y: self.view.bounds.height + snapshotTopInset), to: CGPoint(), duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: true, additive: true) diff --git a/submodules/TelegramUI/Sources/ChatHistoryNode.swift b/submodules/TelegramUI/Sources/ChatHistoryNode.swift index 094effabed..66fe663f10 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryNode.swift @@ -22,7 +22,7 @@ public enum ChatHistoryNodeLoadState: Equatable { case messages } -public protocol ChatHistoryNode: class { +public protocol ChatHistoryNode: AnyObject { var historyState: ValuePromise { get } var preloadPages: Bool { get set } diff --git a/submodules/TelegramUI/Sources/ChatHistorySearchContainerNode.swift b/submodules/TelegramUI/Sources/ChatHistorySearchContainerNode.swift index c9fb9f748a..d26c8246e4 100644 --- a/submodules/TelegramUI/Sources/ChatHistorySearchContainerNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistorySearchContainerNode.swift @@ -14,27 +14,8 @@ import ListMessageItem private enum ChatHistorySearchEntryStableId: Hashable { case messageId(MessageId) - - static func ==(lhs: ChatHistorySearchEntryStableId, rhs: ChatHistorySearchEntryStableId) -> Bool { - switch lhs { - case let .messageId(messageId): - if case .messageId(messageId) = rhs { - return true - } else { - return false - } - } - } - - var hashValue: Int { - switch self { - case let .messageId(messageId): - return messageId.hashValue - } - } } - private enum ChatHistorySearchEntry: Comparable, Identifiable { case message(Message, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationFontSize) diff --git a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift index 612fb3f74a..5e35e755f6 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift @@ -223,7 +223,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, context: A return .HistoryView(view: view, type: reportUpdateType, scrollPosition: .index(index: anchorIndex, position: .center(.bottom), directionHint: .Down, animated: false, highlight: highlight), flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id) } } - case let .Navigation(index, anchorIndex, count, highlight): + case let .Navigation(index, anchorIndex, count, _): var first = true return account.viewTracker.aroundMessageHistoryViewForLocation(context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder), index: index, anchorIndex: anchorIndex, count: count, ignoreRelatedChats: ignoreRelatedChats, fixedCombinedReadStates: fixedCombinedReadStates, tagMask: tagMask, appendMessagesFromTheSameGroup: appendMessagesFromTheSameGroup, orderStatistics: orderStatistics, additionalData: additionalData) |> map { view, updateType, initialData -> ChatHistoryViewUpdate in let (cachedData, cachedDataMessages, readStateData) = extractAdditionalData(view: view, chatLocation: chatLocation) diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index 02eec73c71..3c3c118bb3 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -1822,8 +1822,8 @@ final class ChatMediaInputNode: ChatInputNode { searchContainerNode.frame = containerFrame searchContainerNode.updateLayout(size: containerFrame.size, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, inputHeight: inputHeight, deviceMetrics: deviceMetrics, transition: .immediate) var placeholderNode: PaneSearchBarPlaceholderNode? - var anchorTop = CGPoint(x: 0.0, y: 0.0) - var anchorTopView: UIView = self.view + let anchorTop = CGPoint(x: 0.0, y: 0.0) + let anchorTopView: UIView = self.view if let searchMode = searchMode { switch searchMode { case .gif: @@ -2167,7 +2167,7 @@ final class ChatMediaInputNode: ChatInputNode { collectionListPanelOffset = 0.0 } - var listPanelOffset = collectionListPanelOffset * 2.0 + let listPanelOffset = collectionListPanelOffset * 2.0 self.updateAppearanceTransition(transition: transition) transition.updateFrame(node: self.collectionListPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: listPanelOffset), size: self.collectionListPanel.bounds.size)) diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index ae3f0cc1a0..ef39095ec0 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -1396,8 +1396,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode switch item.presentationData.theme.wallpaper { case .color: hasSolidWallpaper = true - case let .gradient(_, colors, _): - hasSolidWallpaper = colors.count <= 2 + case let .gradient(gradient): + hasSolidWallpaper = gradient.colors.count <= 2 default: break } diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index 69be62c976..8f96ccbaf6 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -390,7 +390,6 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD var viaBotApply: (TextNodeLayout, () -> TextNode)? var replyInfoApply: (CGSize, () -> ChatMessageReplyInfoNode)? var updatedReplyBackgroundNode: NavigationBackgroundNode? - var replyBackgroundImage: UIImage? var replyMarkup: ReplyMarkupMessageAttribute? let availableWidth = max(60.0, params.width - params.leftInset - params.rightInset - normalDisplaySize.width - 20.0 - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left) @@ -489,7 +488,6 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD var forwardInfoSizeApply: (CGSize, (CGFloat) -> ChatMessageForwardInfoNode)? var updatedForwardBackgroundNode: NavigationBackgroundNode? - var forwardBackgroundImage: UIImage? if !ignoreForward, let forwardInfo = item.message.forwardInfo { let forwardPsaType = forwardInfo.psaType diff --git a/submodules/TelegramUI/Sources/ChatOverscrollControl.swift b/submodules/TelegramUI/Sources/ChatOverscrollControl.swift index 99ba5e4da8..f8c47db4c9 100644 --- a/submodules/TelegramUI/Sources/ChatOverscrollControl.swift +++ b/submodules/TelegramUI/Sources/ChatOverscrollControl.swift @@ -1,6 +1,7 @@ import UIKit import ComponentFlow import Display +import AsyncDisplayKit import TelegramCore import Postbox import AccountContext @@ -196,6 +197,9 @@ final class CheckComponent: Component { } final class View: UIView { + private var currentValue: CGFloat? + private var animator: DisplayLinkAnimator? + init() { super.init(frame: CGRect()) } @@ -204,10 +208,8 @@ final class CheckComponent: Component { preconditionFailure() } - func update(component: CheckComponent, availableSize: CGSize, transition: Transition) -> CGSize { + private func updateContent(size: CGSize, color: UIColor, lineWidth: CGFloat, value: CGFloat) { func draw(context: CGContext) { - let size = availableSize - let diameter = size.width let factor = diameter / 50.0 @@ -215,19 +217,17 @@ final class CheckComponent: Component { context.saveGState() context.setBlendMode(.normal) - context.setFillColor(component.color.cgColor) - context.setStrokeColor(component.color.cgColor) + context.setFillColor(color.cgColor) + context.setStrokeColor(color.cgColor) let center = CGPoint(x: diameter / 2.0, y: diameter / 2.0) - let lineWidth = component.lineWidth - context.setLineWidth(max(1.7, lineWidth * factor)) context.setLineCap(.round) context.setLineJoin(.round) context.setMiterLimit(10.0) - let progress = component.value + let progress = value let firstSegment: CGFloat = max(0.0, min(1.0, progress * 3.0)) var s = CGPoint(x: center.x - 10.0 * factor, y: center.y + 1.0 * factor) @@ -257,7 +257,7 @@ final class CheckComponent: Component { } if #available(iOS 10.0, *) { - let renderer = UIGraphicsImageRenderer(bounds: CGRect(origin: CGPoint(), size: availableSize)) + let renderer = UIGraphicsImageRenderer(bounds: CGRect(origin: CGPoint(), size: size)) let image = renderer.image { context in UIGraphicsPushContext(context.cgContext) draw(context: context.cgContext) @@ -265,11 +265,37 @@ final class CheckComponent: Component { } self.layer.contents = image.cgImage } else { - UIGraphicsBeginImageContextWithOptions(availableSize, false, 0.0) + UIGraphicsBeginImageContextWithOptions(size, false, 0.0) draw(context: UIGraphicsGetCurrentContext()!) self.layer.contents = UIGraphicsGetImageFromCurrentImageContext()?.cgImage UIGraphicsEndImageContext() } + } + + func update(component: CheckComponent, availableSize: CGSize, transition: Transition) -> CGSize { + if let currentValue = self.currentValue, currentValue != component.value, case .curve = transition.animation { + self.animator?.invalidate() + + let animator = DisplayLinkAnimator(duration: 0.15, from: currentValue, to: component.value, update: { [weak self] value in + guard let strongSelf = self else { + return + } + strongSelf.updateContent(size: availableSize, color: component.color, lineWidth: component.lineWidth, value: value) + }, completion: { [weak self] in + guard let strongSelf = self else { + return + } + strongSelf.animator?.invalidate() + strongSelf.animator = nil + }) + self.animator = animator + } else { + if self.animator == nil { + self.updateContent(size: availableSize, color: component.color, lineWidth: component.lineWidth, value: component.value) + } + } + + self.currentValue = component.value return availableSize } @@ -284,13 +310,101 @@ final class CheckComponent: Component { } } +final class BadgeComponent: CombinedComponent { + let count: Int + let backgroundColor: UIColor + let foregroundColor: UIColor + + init(count: Int, backgroundColor: UIColor, foregroundColor: UIColor) { + self.count = count + self.backgroundColor = backgroundColor + self.foregroundColor = foregroundColor + } + + static func ==(lhs: BadgeComponent, rhs: BadgeComponent) -> Bool { + if lhs.count != rhs.count { + return false + } + if !lhs.backgroundColor.isEqual(rhs.backgroundColor) { + return false + } + if !lhs.foregroundColor.isEqual(rhs.foregroundColor) { + return false + } + return true + } + + static var body: Body { + let background = Child(BlurredRoundedRectangle.self) + let text = Child(Text.self) + + return { context in + let text = text.update( + component: Text( + text: "\(context.component.count)", + font: Font.regular(13.0), + color: context.component.foregroundColor + ), + availableSize: CGSize(width: 100.0, height: 100.0), + transition: .immediate + ) + + let height = text.size.height + 4.0 + let backgroundSize = CGSize(width: max(height, text.size.width + 8.0), height: height) + + let background = background.update( + component: BlurredRoundedRectangle(color: context.component.backgroundColor), + availableSize: backgroundSize, + transition: .immediate + ) + + context.add(background + .position(CGPoint(x: backgroundSize.width / 2.0, y: backgroundSize.height / 2.0)) + ) + + context.add(text + .position(CGPoint(x: backgroundSize.width / 2.0, y: backgroundSize.height / 2.0)) + ) + + return backgroundSize + } + } +} + final class AvatarComponent: Component { + final class Badge: Equatable { + let count: Int + let backgroundColor: UIColor + let foregroundColor: UIColor + + init(count: Int, backgroundColor: UIColor, foregroundColor: UIColor) { + self.count = count + self.backgroundColor = backgroundColor + self.foregroundColor = foregroundColor + } + + static func ==(lhs: Badge, rhs: Badge) -> Bool { + if lhs.count != rhs.count { + return false + } + if !lhs.backgroundColor.isEqual(rhs.backgroundColor) { + return false + } + if !lhs.foregroundColor.isEqual(rhs.foregroundColor) { + return false + } + return true + } + } + let context: AccountContext let peer: EnginePeer + let badge: Badge? - init(context: AccountContext, peer: EnginePeer) { + init(context: AccountContext, peer: EnginePeer, badge: Badge?) { self.context = context self.peer = peer + self.badge = badge } static func ==(lhs: AvatarComponent, rhs: AvatarComponent) -> Bool { @@ -300,14 +414,20 @@ final class AvatarComponent: Component { if lhs.peer != rhs.peer { return false } + if lhs.badge != rhs.badge { + return false + } return true } final class View: UIView { private let avatarNode: AvatarNode + private let avatarMask: CAShapeLayer + private var badgeView: ComponentHostView? init() { self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 26.0)) + self.avatarMask = CAShapeLayer() super.init(frame: CGRect()) @@ -322,6 +442,56 @@ final class AvatarComponent: Component { self.avatarNode.frame = CGRect(origin: CGPoint(), size: availableSize) self.avatarNode.setPeer(context: component.context, theme: component.context.sharedContext.currentPresentationData.with({ $0 }).theme, peer: component.peer, synchronousLoad: true) + if let badge = component.badge { + let badgeView: ComponentHostView + let animateIn = self.badgeView == nil + if let current = self.badgeView { + badgeView = current + } else { + badgeView = ComponentHostView() + self.badgeView = badgeView + self.addSubview(badgeView) + } + + let badgeSize = badgeView.update( + transition: .immediate, + component: AnyComponent(BadgeComponent( + count: badge.count, + backgroundColor: badge.backgroundColor, + foregroundColor: badge.foregroundColor + )), + environment: {}, + containerSize: CGSize(width: 100.0, height: 100.0 + )) + let badgeDiameter = min(badgeSize.width, badgeSize.height) + let circlePoint = CGPoint( + x: availableSize.width / 2.0 + cos(CGFloat.pi / 4) * availableSize.width / 2.0, + y: availableSize.height / 2.0 - sin(CGFloat.pi / 4) * availableSize.width / 2.0 + ) + badgeView.frame = CGRect(origin: CGPoint(x: circlePoint.x - badgeDiameter / 2.0, y: circlePoint.y - badgeDiameter / 2.0), size: badgeSize) + + self.avatarMask.frame = self.avatarNode.bounds + self.avatarMask.fillRule = .evenOdd + + let path = UIBezierPath(rect: self.avatarMask.bounds) + path.append(UIBezierPath(roundedRect: badgeView.frame.insetBy(dx: -2.0, dy: -2.0), cornerRadius: badgeDiameter / 2.0)) + self.avatarMask.path = path.cgPath + + self.avatarNode.view.layer.mask = self.avatarMask + + if animateIn { + badgeView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.14) + } + } else if let badgeView = self.badgeView { + self.badgeView = nil + + badgeView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.14, removeOnCompletion: false, completion: { [weak badgeView] _ in + badgeView?.removeFromSuperview() + }) + + self.avatarNode.view.layer.mask = nil + } + return availableSize } } @@ -335,32 +505,32 @@ final class AvatarComponent: Component { } } -final class ChatOverscrollControl: CombinedComponent { - let text: String +final class OverscrollContentsComponent: Component { + let context: AccountContext let backgroundColor: UIColor let foregroundColor: UIColor let peer: EnginePeer? - let context: AccountContext - let expandDistance: CGFloat + let unreadCount: Int + let expandOffset: CGFloat init( - text: String, + context: AccountContext, backgroundColor: UIColor, foregroundColor: UIColor, peer: EnginePeer?, - context: AccountContext, - expandDistance: CGFloat + unreadCount: Int, + expandOffset: CGFloat ) { - self.text = text + self.context = context self.backgroundColor = backgroundColor self.foregroundColor = foregroundColor self.peer = peer - self.context = context - self.expandDistance = expandDistance + self.unreadCount = unreadCount + self.expandOffset = expandOffset } - static func ==(lhs: ChatOverscrollControl, rhs: ChatOverscrollControl) -> Bool { - if lhs.text != rhs.text { + static func ==(lhs: OverscrollContentsComponent, rhs: OverscrollContentsComponent) -> Bool { + if lhs.context !== rhs.context { return false } if !lhs.backgroundColor.isEqual(rhs.backgroundColor) { @@ -372,6 +542,265 @@ final class ChatOverscrollControl: CombinedComponent { if lhs.peer != rhs.peer { return false } + if lhs.unreadCount != rhs.unreadCount { + return false + } + if lhs.expandOffset != rhs.expandOffset { + return false + } + return true + } + + final class View: UIView { + private let backgroundScalingContainer: ASDisplayNode + private let backgroundNode: NavigationBackgroundNode + private let backgroundClippingNode: ASDisplayNode + private let avatarView = ComponentHostView() + private let checkView = ComponentHostView() + private let arrowNode: ASImageNode + private let avatarScalingContainer: ASDisplayNode + private let avatarExtraScalingContainer: ASDisplayNode + private let avatarOffsetContainer: ASDisplayNode + private let arrowOffsetContainer: ASDisplayNode + + private let titleOffsetContainer: ASDisplayNode + private let titleBackgroundNode: NavigationBackgroundNode + private let titleNode: ImmediateTextNode + + private var isFullyExpanded: Bool = false + + private var validForegroundColor: UIColor? + + init() { + self.backgroundScalingContainer = ASDisplayNode() + self.backgroundNode = NavigationBackgroundNode(color: .clear) + self.backgroundNode.clipsToBounds = true + self.backgroundClippingNode = ASDisplayNode() + self.backgroundClippingNode.clipsToBounds = true + self.arrowNode = ASImageNode() + self.avatarScalingContainer = ASDisplayNode() + self.avatarExtraScalingContainer = ASDisplayNode() + self.avatarOffsetContainer = ASDisplayNode() + self.arrowOffsetContainer = ASDisplayNode() + + self.titleOffsetContainer = ASDisplayNode() + self.titleBackgroundNode = NavigationBackgroundNode(color: .clear) + self.titleNode = ImmediateTextNode() + + super.init(frame: CGRect()) + + self.addSubview(self.backgroundScalingContainer.view) + + self.backgroundClippingNode.addSubnode(self.backgroundNode) + self.backgroundScalingContainer.addSubnode(self.backgroundClippingNode) + + self.avatarScalingContainer.view.addSubview(self.avatarView) + self.avatarScalingContainer.view.addSubview(self.checkView) + self.avatarExtraScalingContainer.addSubnode(self.avatarScalingContainer) + self.avatarOffsetContainer.addSubnode(self.avatarExtraScalingContainer) + self.arrowOffsetContainer.addSubnode(self.arrowNode) + self.backgroundNode.addSubnode(self.arrowOffsetContainer) + self.addSubnode(self.avatarOffsetContainer) + + self.titleOffsetContainer.addSubnode(self.titleBackgroundNode) + self.titleOffsetContainer.addSubnode(self.titleNode) + self.addSubnode(self.titleOffsetContainer) + } + + required init?(coder aDecoder: NSCoder) { + preconditionFailure() + } + + func update(component: OverscrollContentsComponent, availableSize: CGSize, transition: Transition) -> CGSize { + if let _ = component.peer { + self.avatarView.isHidden = false + self.checkView.isHidden = true + } else { + self.avatarView.isHidden = true + self.checkView.isHidden = false + } + + let fullHeight: CGFloat = 90.0 + let backgroundWidth: CGFloat = 50.0 + let minBackgroundHeight: CGFloat = backgroundWidth + 34.0 + let avatarInset: CGFloat = 6.0 + + let isFullyExpanded = component.expandOffset >= fullHeight + + let backgroundHeight: CGFloat = max(minBackgroundHeight, min(fullHeight, component.expandOffset)) + + let backgroundFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - backgroundWidth) / 2.0), y: fullHeight - backgroundHeight), size: CGSize(width: backgroundWidth, height: backgroundHeight)) + + let expandProgress: CGFloat = max(0.1, min(1.0, component.expandOffset / minBackgroundHeight)) + let alphaProgress: CGFloat = max(0.0, min(1.0, component.expandOffset / 10.0)) + + let maxAvatarScale: CGFloat = 1.0 + let avatarExpandProgress: CGFloat = max(0.01, min(maxAvatarScale, component.expandOffset / fullHeight)) + + transition.setAlpha(view: self.backgroundScalingContainer.view, alpha: alphaProgress) + transition.setFrame(view: self.backgroundScalingContainer.view, frame: CGRect(origin: CGPoint(x: floor(availableSize.width / 2.0), y: fullHeight), size: CGSize(width: 0.0, height: 0.0))) + transition.setSublayerTransform(view: self.backgroundScalingContainer.view, transform: CATransform3DMakeScale(expandProgress, expandProgress, 1.0)) + + transition.setFrame(view: self.backgroundNode.view, frame: CGRect(origin: CGPoint(x: 0.0, y: fullHeight - backgroundFrame.size.height), size: backgroundFrame.size)) + self.backgroundNode.updateColor(color: component.backgroundColor, transition: .immediate) + self.backgroundNode.update(size: backgroundFrame.size, cornerRadius: backgroundWidth / 2.0, transition: .immediate) + + self.avatarView.frame = CGRect(origin: CGPoint(x: floor(-backgroundWidth / 2.0), y: floor(-backgroundWidth / 2.0)), size: CGSize(width: backgroundWidth, height: backgroundWidth)) + + transition.setFrame(view: self.avatarOffsetContainer.view, frame: CGRect()) + transition.setFrame(view: self.avatarScalingContainer.view, frame: CGRect()) + transition.setFrame(view: self.avatarExtraScalingContainer.view, frame: CGRect(origin: CGPoint(x: availableSize.width / 2.0, y: fullHeight - backgroundWidth / 2.0), size: CGSize()).offsetBy(dx: 0.0, dy: (1.0 - avatarExpandProgress) * backgroundWidth * 0.5)) + transition.setSublayerTransform(view: self.avatarScalingContainer.view, transform: CATransform3DMakeScale(avatarExpandProgress, avatarExpandProgress, 1.0)) + + let titleText: String + if let peer = component.peer { + titleText = peer.compactDisplayTitle + } else { + //TODO:localize + titleText = "You have no unread channels" + } + self.titleNode.attributedText = NSAttributedString(string: titleText, font: Font.semibold(13.0), textColor: component.foregroundColor) + let titleSize = self.titleNode.updateLayout(CGSize(width: availableSize.width - 32.0, height: 100.0)) + let titleBackgroundSize = CGSize(width: titleSize.width + 18.0, height: titleSize.height + 8.0) + let titleBackgroundFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - titleBackgroundSize.width) / 2.0), y: fullHeight - titleBackgroundSize.height - 8.0), size: titleBackgroundSize) + self.titleBackgroundNode.frame = titleBackgroundFrame + self.titleBackgroundNode.updateColor(color: component.backgroundColor, transition: .immediate) + self.titleBackgroundNode.update(size: titleBackgroundFrame.size, cornerRadius: titleBackgroundFrame.size.height / 2.0, transition: .immediate) + self.titleNode.frame = titleSize.centered(in: titleBackgroundFrame) + + let backgroundClippingFrame = CGRect(origin: CGPoint(x: floor(-backgroundWidth / 2.0), y: -fullHeight), size: CGSize(width: backgroundWidth, height: isFullyExpanded ? backgroundWidth : fullHeight)) + self.backgroundClippingNode.cornerRadius = backgroundWidth / 2.0 + self.backgroundNode.cornerRadius = backgroundWidth / 2.0 + + if !(self.validForegroundColor?.isEqual(component.foregroundColor) ?? false) { + self.validForegroundColor = component.foregroundColor + self.arrowNode.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/OverscrollArrow"), color: component.foregroundColor) + } + + if let arrowImage = self.arrowNode.image { + self.arrowNode.frame = CGRect(origin: CGPoint(x: floor((backgroundWidth - arrowImage.size.width) / 2.0), y: floor((backgroundWidth - arrowImage.size.width) / 2.0)), size: arrowImage.size) + } + + let transformTransition: ContainedViewLayoutTransition + if self.isFullyExpanded != isFullyExpanded { + self.isFullyExpanded = isFullyExpanded + transformTransition = .animated(duration: 0.12, curve: .easeInOut) + + if isFullyExpanded { + func animateBounce(layer: CALayer) { + layer.animateScale(from: 1.0, to: 1.1, duration: 0.1, removeOnCompletion: false, completion: { [weak layer] _ in + layer?.animateScale(from: 1.1, to: 1.0, duration: 0.14, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue) + }) + } + + animateBounce(layer: self.backgroundClippingNode.layer) + animateBounce(layer: self.avatarExtraScalingContainer.layer) + + func animateOffsetBounce(layer: CALayer) { + let firstAnimation = layer.makeAnimation(from: 0.0 as NSNumber, to: -5.0 as NSNumber, keyPath: "transform.translation.y", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.1, removeOnCompletion: false, additive: true, completion: { [weak layer] _ in + guard let layer = layer else { + return + } + let secondAnimation = layer.makeAnimation(from: -5.0 as NSNumber, to: 0.0 as NSNumber, keyPath: "transform.translation.y", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, duration: 0.14, removeOnCompletion: true, additive: true) + layer.add(secondAnimation, forKey: "bounceY") + }) + layer.add(firstAnimation, forKey: "bounceY") + } + + animateOffsetBounce(layer: self.layer) + } + } else { + transformTransition = .immediate + } + + let checkSize: CGFloat = 50.0 + self.checkView.frame = CGRect(origin: CGPoint(x: floor(-checkSize / 2.0), y: floor(-checkSize / 2.0)), size: CGSize(width: checkSize, height: checkSize)) + let _ = self.checkView.update( + transition: Transition(animation: transformTransition.isAnimated ? .curve(duration: 0.2, curve: .easeInOut) : .none), + component: AnyComponent(CheckComponent( + color: component.foregroundColor, + lineWidth: 3.0, + value: isFullyExpanded ? 1.0 : 0.0 + )), + environment: {}, + containerSize: CGSize(width: checkSize, height: checkSize) + ) + + if let peer = component.peer { + let _ = self.avatarView.update( + transition: Transition(animation: transformTransition.isAnimated ? .curve(duration: 0.2, curve: .easeInOut) : .none), + component: AnyComponent(AvatarComponent( + context: component.context, + peer: peer, + badge: isFullyExpanded ? AvatarComponent.Badge(count: component.unreadCount, backgroundColor: component.backgroundColor, foregroundColor: component.foregroundColor) : nil + )), + environment: {}, + containerSize: self.avatarView.bounds.size + ) + } + + transformTransition.updateAlpha(node: self.backgroundNode, alpha: (isFullyExpanded && component.peer != nil) ? 0.0 : 1.0) + transformTransition.updateAlpha(node: self.arrowNode, alpha: isFullyExpanded ? 0.0 : 1.0) + + transformTransition.updateSublayerTransformOffset(layer: self.avatarOffsetContainer.layer, offset: CGPoint(x: 0.0, y: isFullyExpanded ? -(fullHeight - backgroundWidth) : 0.0)) + transformTransition.updateSublayerTransformOffset(layer: self.arrowOffsetContainer.layer, offset: CGPoint(x: 0.0, y: isFullyExpanded ? -(fullHeight - backgroundWidth) : 0.0)) + + transformTransition.updateSublayerTransformOffset(layer: self.titleOffsetContainer.layer, offset: CGPoint(x: 0.0, y: isFullyExpanded ? 0.0 : (titleBackgroundSize.height + 50.0))) + + transformTransition.updateSublayerTransformScale(node: self.avatarExtraScalingContainer, scale: isFullyExpanded ? 1.0 : ((backgroundWidth - avatarInset * 2.0) / backgroundWidth)) + + transformTransition.updateFrame(node: self.backgroundClippingNode, frame: backgroundClippingFrame) + + return CGSize(width: availableSize.width, height: fullHeight) + } + } + + func makeView() -> View { + return View() + } + + func update(view: View, availableSize: CGSize, transition: Transition) -> CGSize { + return view.update(component: self, availableSize: availableSize, transition: transition) + } +} + +final class ChatOverscrollControl: CombinedComponent { + let backgroundColor: UIColor + let foregroundColor: UIColor + let peer: EnginePeer? + let unreadCount: Int + let context: AccountContext + let expandDistance: CGFloat + + init( + backgroundColor: UIColor, + foregroundColor: UIColor, + peer: EnginePeer?, + unreadCount: Int, + context: AccountContext, + expandDistance: CGFloat + ) { + self.backgroundColor = backgroundColor + self.foregroundColor = foregroundColor + self.peer = peer + self.unreadCount = unreadCount + self.context = context + self.expandDistance = expandDistance + } + + static func ==(lhs: ChatOverscrollControl, rhs: ChatOverscrollControl) -> Bool { + if !lhs.backgroundColor.isEqual(rhs.backgroundColor) { + return false + } + if !lhs.foregroundColor.isEqual(rhs.foregroundColor) { + return false + } + if lhs.peer != rhs.peer { + return false + } + if lhs.unreadCount != rhs.unreadCount { + return false + } if lhs.context !== rhs.context { return false } @@ -382,156 +811,51 @@ final class ChatOverscrollControl: CombinedComponent { } static var body: Body { - let avatarBackground = Child(BlurredRoundedRectangle.self) - let avatarExpandProgress = Child(RadialProgressComponent.self) - let avatarCheck = Child(CheckComponent.self) - let avatar = Child(AvatarComponent.self) - let textBackground = Child(BlurredRoundedRectangle.self) - let text = Child(Text.self) + let contents = Child(OverscrollContentsComponent.self) return { context in - let text = text.update( - component: Text( - text: context.component.text, - font: Font.regular(12.0), - color: context.component.foregroundColor + let contents = contents.update( + component: OverscrollContentsComponent( + context: context.component.context, + backgroundColor: context.component.backgroundColor, + foregroundColor: context.component.foregroundColor, + peer: context.component.peer, + unreadCount: context.component.unreadCount, + expandOffset: context.component.expandDistance ), - availableSize: CGSize(width: context.availableSize.width, height: 100.0), + availableSize: context.availableSize, transition: context.transition ) - let textHorizontalPadding: CGFloat = 6.0 - let textVerticalPadding: CGFloat = 2.0 - let avatarSize: CGFloat = 48.0 - let avatarPadding: CGFloat = 8.0 - let avatarTextSpacing: CGFloat = 8.0 - let avatarProgressPadding: CGFloat = 2.5 + let size = CGSize(width: context.availableSize.width, height: contents.size.height) - let avatarBackgroundSize: CGFloat = context.component.peer != nil ? (avatarSize + avatarPadding * 2.0) : avatarSize - - let avatarBackground = avatarBackground.update( - component: BlurredRoundedRectangle( - color: context.component.backgroundColor - ), - availableSize: CGSize(width: avatarBackgroundSize, height: avatarBackgroundSize), - transition: context.transition - ) - - let avatarCheck = Condition(context.component.peer == nil, { () -> _UpdatedChildComponent in - let avatarCheckSize = avatarBackgroundSize + 2.0 - - return avatarCheck.update( - component: CheckComponent( - color: context.component.foregroundColor, - lineWidth: 2.5, - value: 1.0 - ), - availableSize: CGSize(width: avatarCheckSize, height: avatarCheckSize), - transition: context.transition - ) - }) - - let progressSize = avatarBackground.size.width - avatarProgressPadding * 2.0 - - let halfDistance = progressSize - let quarterDistance = halfDistance / 2.0 - - let clippedDistance = max(0.0, min(halfDistance * 2.0, context.component.expandDistance)) - - var mappedProgress: CGFloat - if clippedDistance <= quarterDistance { - mappedProgress = acos(1.0 - clippedDistance / quarterDistance) / (CGFloat.pi * 2.0) - } else if clippedDistance <= halfDistance { - let sectionDistance = halfDistance - clippedDistance - mappedProgress = 0.25 + asin(1.0 - sectionDistance / quarterDistance) / (CGFloat.pi * 2.0) - } else { - let restDistance = clippedDistance - halfDistance - mappedProgress = min(1.0, 0.5 + restDistance / 60.0) - } - mappedProgress = max(0.01, mappedProgress) - - let avatarExpandProgress = avatarExpandProgress.update( - component: RadialProgressComponent( - color: context.component.foregroundColor, - lineWidth: 2.5, - value: context.component.peer == nil ? 0.0 : mappedProgress - ), - availableSize: CGSize(width: progressSize, height: progressSize), - transition: context.transition - ) - - let textBackground = textBackground.update( - component: BlurredRoundedRectangle( - color: context.component.backgroundColor - ), - availableSize: CGSize(width: text.size.width + textHorizontalPadding * 2.0, height: text.size.height + textVerticalPadding * 2.0), - transition: context.transition - ) - - let size = CGSize(width: context.availableSize.width, height: avatarBackground.size.height + avatarTextSpacing + textBackground.size.height) - - let avatarBackgroundFrame = avatarBackground.size.topCentered(in: CGRect(origin: CGPoint(), size: size)) - - let avatar = context.component.peer.flatMap { peer in - avatar.update( - component: AvatarComponent( - context: context.component.context, - peer: peer - ), - availableSize: CGSize(width: avatarSize, height: avatarSize), - transition: context.transition - ) - } - - context.add(avatarBackground - .position(CGPoint( - x: avatarBackgroundFrame.midX, - y: avatarBackgroundFrame.midY - )) - ) - - if let avatarCheck = avatarCheck { - context.add(avatarCheck - .position(CGPoint( - x: avatarBackgroundFrame.midX, - y: avatarBackgroundFrame.midY - )) - ) - } - - context.add(avatarExpandProgress - .position(CGPoint( - x: avatarBackgroundFrame.midX, - y: avatarBackgroundFrame.midY - )) - ) - - if let avatar = avatar { - context.add(avatar - .position(CGPoint( - x: avatarBackgroundFrame.midX, - y: avatarBackgroundFrame.midY - )) - ) - } - - let textBackgroundFrame = textBackground.size.bottomCentered(in: CGRect(origin: CGPoint(), size: size)) - context.add(textBackground - .position(CGPoint( - x: textBackgroundFrame.midX, - y: textBackgroundFrame.midY - )) - ) - - let textFrame = text.size.centered(in: textBackgroundFrame) - context.add(text - .position(CGPoint( - x: textFrame.midX, - y: textFrame.midY - )) + context.add(contents + .position(CGPoint(x: size.width / 2.0, y: size.height / 2.0)) ) return size } } } + +final class ChatInputPanelOverscrollNode: ASDisplayNode { + let text: String + let priority: Int + private let titleNode: ImmediateTextNode + + init(text: String, color: UIColor, priority: Int) { + self.text = text + self.priority = priority + self.titleNode = ImmediateTextNode() + + super.init() + + self.titleNode.attributedText = NSAttributedString(string: text, font: Font.regular(14.0), textColor: color) + self.addSubnode(self.titleNode) + } + + func update(size: CGSize) { + let titleSize = self.titleNode.updateLayout(size) + self.titleNode.frame = titleSize.centered(in: CGRect(origin: CGPoint(), size: size)) + } +} diff --git a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift index 9fffe16a45..a895fb85fc 100644 --- a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift @@ -327,24 +327,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { if let animation = animation { animationTransition = .animated(duration: 0.2, curve: .easeInOut) - if false, let copyView = self.contentContainer.view.snapshotView(afterScreenUpdates: false) { - let offset: CGFloat - switch animation { - case .slideToTop: - offset = -40.0 - case .slideToBottom: - offset = 40.0 - } - - copyView.frame = self.contentContainer.frame - self.clippingContainer.view.addSubview(copyView) - copyView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: offset), duration: 0.2, removeOnCompletion: false, additive: true) - copyView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak copyView] _ in - copyView?.removeFromSuperview() - }) - self.contentContainer.layer.animatePosition(from: CGPoint(x: 0.0, y: -offset), to: CGPoint(), duration: 0.2, additive: true) - self.contentContainer.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - } else if let copyView = self.textNode.view.snapshotView(afterScreenUpdates: false) { + if let copyView = self.textNode.view.snapshotView(afterScreenUpdates: false) { let offset: CGFloat switch animation { case .slideToTop: diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index ce85ec7d92..4b233555f4 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -781,7 +781,6 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { } private func openPeerMention(_ name: String) { - let postbox = self.context.account.postbox self.navigationActionDisposable.set((self.context.engine.peers.resolvePeerByName(name: name, ageLimit: 10) |> take(1) |> deliverOnMainQueue).start(next: { [weak self] peer in diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsFilterController.swift b/submodules/TelegramUI/Sources/ChatRecentActionsFilterController.swift index 3c4606e7e3..4318cfcf24 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsFilterController.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsFilterController.swift @@ -36,32 +36,6 @@ private enum ChatRecentActionsFilterSection: Int32 { private enum ChatRecentActionsFilterEntryStableId: Hashable { case index(Int32) case peer(PeerId) - - var hashValue: Int { - switch self { - case let .index(index): - return index.hashValue - case let .peer(peerId): - return peerId.hashValue - } - } - - static func ==(lhs: ChatRecentActionsFilterEntryStableId, rhs: ChatRecentActionsFilterEntryStableId) -> Bool { - switch lhs { - case let .index(index): - if case .index(index) = rhs { - return true - } else { - return false - } - case let .peer(peerId): - if case .peer(peerId) = rhs { - return true - } else { - return false - } - } - } } private enum ChatRecentActionsFilterEntry: ItemListNodeEntry { diff --git a/submodules/TelegramUI/Sources/ChatSecretAutoremoveTimerActionSheet.swift b/submodules/TelegramUI/Sources/ChatSecretAutoremoveTimerActionSheet.swift index 5dbe277004..c1bc4e7f40 100644 --- a/submodules/TelegramUI/Sources/ChatSecretAutoremoveTimerActionSheet.swift +++ b/submodules/TelegramUI/Sources/ChatSecretAutoremoveTimerActionSheet.swift @@ -19,7 +19,6 @@ final class ChatSecretAutoremoveTimerActionSheetController: ActionSheetControlle init(context: AccountContext, currentValue: Int32, availableValues: [Int32]? = nil, applyValue: @escaping (Int32) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } - let theme = presentationData.theme let strings = presentationData.strings super.init(theme: ActionSheetControllerTheme(presentationData: presentationData)) diff --git a/submodules/TelegramUI/Sources/ChatSendMessageActionSheetControllerNode.swift b/submodules/TelegramUI/Sources/ChatSendMessageActionSheetControllerNode.swift index ac6881df7c..dac19b9c0f 100644 --- a/submodules/TelegramUI/Sources/ChatSendMessageActionSheetControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatSendMessageActionSheetControllerNode.swift @@ -370,7 +370,6 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, let outgoing: PresentationThemeBubbleColorComponents = self.presentationData.chatWallpaper.isEmpty ? self.presentationData.theme.chat.message.outgoing.bubble.withoutWallpaper : self.presentationData.theme.chat.message.outgoing.bubble.withWallpaper let maxCornerRadius = self.presentationData.chatBubbleCorners.mainRadius - let minCornerRadius = self.presentationData.chatBubbleCorners.auxiliaryRadius self.messageBackgroundNode.image = messageBubbleImage(maxCornerRadius: maxCornerRadius, minCornerRadius: maxCornerRadius, incoming: false, fillColor: outgoing.gradientFill, strokeColor: outgoing.fill == outgoing.gradientFill ? outgoing.stroke : .clear, neighbors: .none, theme: self.presentationData.theme.chat, wallpaper: self.presentationData.chatWallpaper, knockout: false) for node in self.contentNodes { diff --git a/submodules/TelegramUI/Sources/CreateGroupController.swift b/submodules/TelegramUI/Sources/CreateGroupController.swift index 56219133fd..b3f79558bd 100644 --- a/submodules/TelegramUI/Sources/CreateGroupController.swift +++ b/submodules/TelegramUI/Sources/CreateGroupController.swift @@ -232,32 +232,32 @@ private enum CreateGroupEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! CreateGroupArguments switch self { - case let .groupInfo(theme, strings, dateTimeFormat, peer, state, avatar): + case let .groupInfo(_, _, dateTimeFormat, peer, state, avatar): return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .editSettings, peer: peer, presence: nil, cachedData: nil, state: state, sectionId: ItemListSectionId(self.section), style: .blocks(withTopInset: false, withExtendedBottomInset: false), editingNameUpdated: { editingName in arguments.updateEditingName(editingName) }, avatarTapped: { arguments.changeProfilePhoto() }, updatingImage: avatar, tag: CreateGroupEntryTag.info) - case let .setProfilePhoto(theme, text): + case let .setProfilePhoto(_, text): return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: ItemListSectionId(self.section), style: .blocks, action: { arguments.changeProfilePhoto() }) - case let .member(_, theme, strings, dateTimeFormat, nameDisplayOrder, peer, presence): + case let .member(_, _, _, dateTimeFormat, nameDisplayOrder, peer, presence): return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer, presence: presence, text: .presence, label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: nil, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }) - case let .locationHeader(theme, title): + case let .locationHeader(_, title): return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section) case let .location(theme, location): let imageSignal = chatMapSnapshotImage(account: arguments.context.account, resource: MapSnapshotMediaResource(latitude: location.latitude, longitude: location.longitude, width: 90, height: 90)) return ItemListAddressItem(theme: theme, label: "", text: location.address.replacingOccurrences(of: ", ", with: "\n"), imageSignal: imageSignal, selected: nil, sectionId: self.section, style: .blocks, action: nil) - case let .changeLocation(theme, text): + case let .changeLocation(_, text): return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: ItemListSectionId(self.section), style: .blocks, action: { arguments.changeLocation() }) - case let .locationInfo(theme, text): + case let .locationInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) - case let .venueHeader(theme, title): + case let .venueHeader(_, title): return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section) - case let .venue(_, theme, venue): + case let .venue(_, _, venue): return ItemListVenueItem(presentationData: presentationData, account: arguments.context.account, venue: venue, sectionId: self.section, style: .blocks, action: { arguments.updateWithVenue(venue) }) @@ -375,7 +375,6 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] var presentControllerImpl: ((ViewController, Any?) -> Void)? var pushImpl: ((ViewController) -> Void)? var endEditingImpl: (() -> Void)? - var clearHighlightImpl: (() -> Void)? var ensureItemVisibleImpl: ((CreateGroupEntryTag, Bool) -> Void)? let actionsDisposable = DisposableSet() @@ -777,7 +776,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] updateState { current in var current = current if current.editingName.isEmpty || current.nameSetFromVenue { - current.editingName = .title(title: venueData.title ?? "", type: .group) + current.editingName = .title(title: venueData.title, type: .group) current.nameSetFromVenue = true } current.location = PeerGeoLocation(latitude: venue.latitude, longitude: venue.longitude, address: presentationData.strings.Map_Locating + "\n\n") @@ -846,9 +845,6 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] [weak controller] in controller?.view.endEditing(true) } - clearHighlightImpl = { [weak controller] in - controller?.clearItemNodesHighlight(animated: true) - } ensureItemVisibleImpl = { [weak controller] targetTag, animated in controller?.afterLayout({ guard let controller = controller else { @@ -856,7 +852,6 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] } var resultItemNode: ListViewItemNode? - let state = stateValue.with({ $0 }) let _ = controller.frameForItemNode({ itemNode in if let itemNode = itemNode as? ItemListItemNode { if let tag = itemNode.tag, tag.isEqual(to: targetTag) { diff --git a/submodules/TelegramUI/Sources/DeviceContactDataManager.swift b/submodules/TelegramUI/Sources/DeviceContactDataManager.swift index 508978d238..c4bcab957c 100644 --- a/submodules/TelegramUI/Sources/DeviceContactDataManager.swift +++ b/submodules/TelegramUI/Sources/DeviceContactDataManager.swift @@ -3,7 +3,6 @@ import SwiftSignalKit import Postbox import TelegramCore import Contacts -import AddressBook import TelegramUIPreferences import DeviceAccess import AccountContext @@ -308,157 +307,6 @@ private final class DeviceContactDataModernContext: DeviceContactDataContext { } } -private func withAddressBook(_ f: (ABAddressBook) -> Void) { - let addressBookRef = ABAddressBookCreateWithOptions(nil, nil) - - if let addressBook = addressBookRef?.takeRetainedValue() { - f(addressBook) - } -} - -private final class DeviceContactDataLegacyContext: DeviceContactDataContext { - var currentContacts: [DeviceContactStableId: DeviceContactBasicData] = [:] - - init(queue: Queue, updated: @escaping ([DeviceContactStableId: DeviceContactBasicData]) -> Void) { - self.currentContacts = self.retrieveContacts() - updated(self.currentContacts) - /*let handle = NotificationCenter.default.addObserver(forName: NSNotification.Name.CNContactStoreDidChange, object: nil, queue: nil, using: { [weak self] _ in - queue.async { - guard let strongSelf = self else { - return - } - let contacts = strongSelf.retrieveContacts() - if strongSelf.currentContacts != contacts { - strongSelf.currentContacts = contacts - updated(strongSelf.currentContacts) - } - } - })*/ - //self.updateHandle = handle - } - - deinit { - /*if let updateHandle = updateHandle { - NotificationCenter.default.removeObserver(updateHandle) - }*/ - } - - private func retrieveContacts() -> [DeviceContactStableId: DeviceContactBasicData] { - var result: [DeviceContactStableId: DeviceContactBasicData] = [:] - withAddressBook { addressBook in - guard let peopleRef = ABAddressBookCopyArrayOfAllPeople(addressBook)?.takeRetainedValue() else { - return - } - - for recordRef in peopleRef as NSArray { - let record = recordRef as ABRecord - let (stableId, basicData) = DeviceContactDataLegacyContext.parseContact(record) - result[stableId] = basicData - } - } - return result - } - - private func getContactById(stableId: String) -> ABRecord? { - let recordId: ABRecordID - if stableId.hasPrefix("ab-"), let idValue = Int(String(stableId[stableId.index(stableId.startIndex, offsetBy: 3)])) { - recordId = Int32(clamping: idValue) - } else { - return nil - } - - var result: ABRecord? - withAddressBook { addressBook in - result = ABAddressBookGetPersonWithRecordID(addressBook, recordId)?.takeUnretainedValue() - } - return result - } - - private static func parseContact(_ contact: ABRecord) -> (DeviceContactStableId, DeviceContactBasicData) { - let stableId = "ab-\(ABRecordGetRecordID(contact))" - var firstName = "" - var lastName = "" - if let value = ABRecordCopyValue(contact, kABPersonFirstNameProperty)?.takeRetainedValue() { - firstName = value as! CFString as String - } - if let value = ABRecordCopyValue(contact, kABPersonLastNameProperty)?.takeRetainedValue() { - lastName = value as! CFString as String - } - - var phoneNumbers: [DeviceContactPhoneNumberData] = [] - if let value = ABRecordCopyValue(contact, kABPersonPhoneProperty)?.takeRetainedValue() { - let phones = value as ABMultiValue - let count = ABMultiValueGetCount(phones) - for i in 0 ..< count { - if let phoneRef = ABMultiValueCopyValueAtIndex(phones, i)?.takeRetainedValue() { - let phone = phoneRef as! CFString as String - var label = "" - if let labelRef = ABMultiValueCopyLabelAtIndex(phones, i)?.takeRetainedValue() { - label = labelRef as String - } - phoneNumbers.append(DeviceContactPhoneNumberData(label: label, value: phone)) - } - } - } - - return (stableId, DeviceContactBasicData(firstName: firstName, lastName: lastName, phoneNumbers: phoneNumbers)) - } - - func personNameDisplayOrder() -> PresentationPersonNameOrder { - if ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatFirstNameFirst { - return .firstLast - } else { - return .lastFirst - } - } - - func getExtendedContactData(stableId: DeviceContactStableId) -> DeviceContactExtendedData? { - if let contact = self.getContactById(stableId: stableId) { - let basicData = DeviceContactDataLegacyContext.parseContact(contact).1 - return DeviceContactExtendedData(basicData: basicData, middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "") - } else { - return nil - } - } - - func appendContactData(_ contactData: DeviceContactExtendedData, to stableId: DeviceContactStableId) -> DeviceContactExtendedData? { - return nil - } - - func appendPhoneNumber(_ phoneNumber: DeviceContactPhoneNumberData, to stableId: DeviceContactStableId) -> DeviceContactExtendedData? { - return nil - } - - func createContactWithData(_ contactData: DeviceContactExtendedData) -> (DeviceContactStableId, DeviceContactExtendedData)? { - var result: (DeviceContactStableId, DeviceContactExtendedData)? - withAddressBook { addressBook in - let contact = ABPersonCreate()?.takeRetainedValue() - ABRecordSetValue(contact, kABPersonFirstNameProperty, contactData.basicData.firstName as CFString, nil) - ABRecordSetValue(contact, kABPersonLastNameProperty, contactData.basicData.lastName as CFString, nil) - - let phones = ABMultiValueCreateMutable(ABPropertyType(kABMultiStringPropertyType))?.takeRetainedValue() - for phone in contactData.basicData.phoneNumbers { - ABMultiValueAddValueAndLabel(phones, phone.value as CFString, phone.label as CFString, nil) - } - ABRecordSetValue(contact, kABPersonPhoneProperty, phones, nil) - - if ABAddressBookAddRecord(addressBook, contact, nil) { - ABAddressBookSave(addressBook, nil) - - let stableId = "ab-\(ABRecordGetRecordID(contact))" - if let contact = self.getContactById(stableId: stableId) { - let parsedContact = DeviceContactDataLegacyContext.parseContact(contact).1 - result = (stableId, DeviceContactExtendedData(basicData: parsedContact, middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")) - } - } - } - return result - } - - func deleteContactWithAppSpecificReference(peerId: PeerId) { - } -} - private final class ExtendedContactDataContext { var value: DeviceContactExtendedData? let subscribers = Bag<(DeviceContactExtendedData) -> Void>() @@ -507,30 +355,19 @@ private final class DeviceContactDataManagerPrivateImpl { } strongSelf.accessInitialized = true if authorizationStatus == .allowed { - if #available(iOSApplicationExtension 9.0, iOS 9.0, *) { - let dataContext = DeviceContactDataModernContext(queue: strongSelf.queue, updated: { stableIdToBasicContactData in - guard let strongSelf = self else { - return - } - strongSelf.updateAll(stableIdToBasicContactData) - }, appSpecificReferencesUpdated: { appSpecificReferences in - guard let strongSelf = self else { - return - } - strongSelf.updateAppSpecificReferences(appSpecificReferences: appSpecificReferences) - }) - strongSelf.dataContext = dataContext - strongSelf.personNameDisplayOrder.set(dataContext.personNameDisplayOrder()) - } else { - let dataContext = DeviceContactDataLegacyContext(queue: strongSelf.queue, updated: { stableIdToBasicContactData in - guard let strongSelf = self else { - return - } - strongSelf.updateAll(stableIdToBasicContactData) - }) - strongSelf.dataContext = dataContext - strongSelf.personNameDisplayOrder.set(dataContext.personNameDisplayOrder()) - } + let dataContext = DeviceContactDataModernContext(queue: strongSelf.queue, updated: { stableIdToBasicContactData in + guard let strongSelf = self else { + return + } + strongSelf.updateAll(stableIdToBasicContactData) + }, appSpecificReferencesUpdated: { appSpecificReferences in + guard let strongSelf = self else { + return + } + strongSelf.updateAppSpecificReferences(appSpecificReferences: appSpecificReferences) + }) + strongSelf.dataContext = dataContext + strongSelf.personNameDisplayOrder.set(dataContext.personNameDisplayOrder()) } else { strongSelf.updateAll([:]) } diff --git a/submodules/TelegramUI/Sources/DocumentPreviewController.swift b/submodules/TelegramUI/Sources/DocumentPreviewController.swift index e18a9d7fa9..186561cdd0 100644 --- a/submodules/TelegramUI/Sources/DocumentPreviewController.swift +++ b/submodules/TelegramUI/Sources/DocumentPreviewController.swift @@ -125,26 +125,6 @@ final class CompactDocumentPreviewController: QLPreviewController, QLPreviewCont self.delegate = self self.dataSource = self - /*self.navigationBar.barTintColor = theme.rootController.navigationBar.backgroundColor - self.navigationBar.tintColor = theme.rootController.navigationBar.accentTextColor - self.navigationBar.shadowImage = generateImage(CGSize(width: 1.0, height: 1.0), rotatedContext: { size, context in - context.clear(CGRect(origin: CGPoint(), size: size)) - context.setFillColor(theme.rootController.navigationBar.separatorColor.cgColor) - context.fill(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: UIScreenPixel))) - }) - self.navigationBar.isTranslucent = false - self.navigationBar.titleTextAttributes = [NSAttributedString.Key.font: Font.semibold(17.0), NSAttributedString.Key.foregroundColor: theme.rootController.navigationBar.primaryTextColor] - controller.navigationItem.setLeftBarButton(UIBarButtonItem(title: strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false) - self.setViewControllers([controller], animated: false)*/ - - var pathExtension: String? - if let fileName = self.file.fileName { - let pathExtensionCandidate = (fileName as NSString).pathExtension - if !pathExtensionCandidate.isEmpty { - pathExtension = pathExtensionCandidate - } - } - if let path = self.postbox.mediaBox.completedResourcePath(self.file.resource) { var updatedPath = path if let fileName = self.file.fileName { diff --git a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift index bbf46d8a78..6cc86fdb8a 100644 --- a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift +++ b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift @@ -952,14 +952,14 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode { } func updateLayout(width: CGFloat, topInset: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, deviceMetrics: DeviceMetrics, isVisible: Bool) -> (CGFloat, CGFloat) { - var searchMode: ChatMediaInputSearchMode? + let searchMode: ChatMediaInputSearchMode? = nil - var displaySearch = false + let displaySearch = false let separatorHeight = max(UIScreenPixel, 1.0 - UIScreenPixel) let topPanelHeight: CGFloat = 56.0 let panelHeight: CGFloat - var isExpanded: Bool = true + let isExpanded: Bool = true // switch expanded { // case .content: panelHeight = maximumHeight @@ -991,8 +991,8 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode { searchContainerNode.frame = containerFrame searchContainerNode.updateLayout(size: containerFrame.size, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, inputHeight: inputHeight, deviceMetrics: deviceMetrics, transition: .immediate) var placeholderNode: PaneSearchBarPlaceholderNode? - var anchorTop = CGPoint(x: 0.0, y: 0.0) - var anchorTopView: UIView = self.view + let anchorTop = CGPoint(x: 0.0, y: 0.0) + let anchorTopView: UIView = self.view if let searchMode = searchMode { switch searchMode { case .sticker: @@ -1007,7 +1007,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode { } if let placeholderNode = placeholderNode { - searchContainerNode.animateIn(from: placeholderNode, anchorTop: anchorTop, anhorTopView: anchorTopView, transition: transition, completion: { [weak self] in + searchContainerNode.animateIn(from: placeholderNode, anchorTop: anchorTop, anhorTopView: anchorTopView, transition: transition, completion: { }) } } diff --git a/submodules/TelegramUI/Sources/FeaturedStickersScreen.swift b/submodules/TelegramUI/Sources/FeaturedStickersScreen.swift index 0c4ea61d5d..660730c184 100644 --- a/submodules/TelegramUI/Sources/FeaturedStickersScreen.swift +++ b/submodules/TelegramUI/Sources/FeaturedStickersScreen.swift @@ -612,14 +612,7 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode { return controller } return nil - }, updateContent: { [weak self] content in - if let strongSelf = self { - var item: StickerPreviewPeekItem? - if let content = content as? StickerPreviewPeekContent { - item = content.item - } - //strongSelf.updatePreviewingItem(item: item, animated: true) - } + }, updateContent: { _ in })) } @@ -1124,7 +1117,6 @@ private final class FeaturedPaneSearchContentNode: ASDisplayNode { guard let strongSelf = self else { return } - let account = strongSelf.context.account if install { let _ = strongSelf.context.engine.stickers.addStickerPackInteractively(info: info, items: []).start() } else { diff --git a/submodules/TelegramUI/Sources/FetchVideoMediaResource.swift b/submodules/TelegramUI/Sources/FetchVideoMediaResource.swift index a9b3b6855a..99d89c1a8e 100644 --- a/submodules/TelegramUI/Sources/FetchVideoMediaResource.swift +++ b/submodules/TelegramUI/Sources/FetchVideoMediaResource.swift @@ -214,7 +214,6 @@ public func fetchVideoLibraryMediaResource(account: Account, resource: VideoLibr } |> castError(MediaResourceDataFetchError.self) |> mapToSignal { appConfiguration -> Signal in - let config = VideoConversionConfiguration.with(appConfiguration: appConfiguration) let signal = Signal { subscriber in subscriber.putNext(.reset) let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [resource.localIdentifier], options: nil) @@ -328,7 +327,6 @@ func fetchLocalFileVideoMediaResource(account: Account, resource: LocalFileVideo } |> castError(MediaResourceDataFetchError.self) |> mapToSignal { appConfiguration -> Signal in - let config = VideoConversionConfiguration.with(appConfiguration: appConfiguration) let signal = Signal { subscriber in subscriber.putNext(.reset) @@ -522,7 +520,6 @@ func fetchLocalFileGifMediaResource(resource: LocalFileGifMediaResource) -> Sign let disposable = MetaDisposable() if let data = try? Data(contentsOf: URL(fileURLWithPath: resource.path), options: Data.ReadingOptions.mappedIfSafe) { - let updatedSize = Atomic(value: 0) let signal = TGGifConverter.convertGif(toMp4: data)! let signalDisposable = signal.start(next: { next in if let result = next as? NSDictionary, let path = result["path"] as? String { diff --git a/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift b/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift index d2b0ed9670..e3279bc37a 100644 --- a/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift @@ -149,7 +149,6 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { let baseWidth = params.width - params.leftInset - params.rightInset let leftInset: CGFloat = 15.0 + params.leftInset - let rightInset: CGFloat = 10.0 + params.rightInset let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "#\(item.text)", font: textFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: baseWidth, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) @@ -186,7 +185,7 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { } func updateRevealOffset(offset: CGFloat, transition: ContainedViewLayoutTransition) { - if let (size, leftInset, rightInset) = self.validLayout { + if let (_, leftInset, _) = self.validLayout { transition.updateFrameAdditive(node: self.textNode, frame: CGRect(origin: CGPoint(x: min(offset, 0.0) + 15.0 + leftInset, y: self.textNode.frame.minY), size: self.textNode.frame.size)) } } @@ -194,7 +193,7 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { override func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { super.setHighlighted(highlighted, at: point, animated: animated) - if let revealNode = self.revealNode, self.revealOffset != 0 { + if let _ = self.revealNode, self.revealOffset != 0 { return } @@ -225,7 +224,6 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { if self.revealOptions == options { return } - let previousOptions = self.revealOptions let wasEmpty = self.revealOptions.isEmpty self.revealOptions = options let isEmpty = options.isEmpty @@ -374,7 +372,7 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { private func updateRevealOffsetInternal(offset: CGFloat, transition: ContainedViewLayoutTransition) { self.revealOffset = offset - guard let (size, leftInset, rightInset) = self.validLayout else { + guard let (size, _, rightInset) = self.validLayout else { return } diff --git a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift index be66ae6644..14f0660861 100644 --- a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift @@ -191,7 +191,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.actionSheet.primaryTextColor) }, action: { _, f in f(.default) - item.resultSelected(item.result, itemNode, itemNode.bounds) + let _ = item.resultSelected(item.result, itemNode, itemNode.bounds) }))) selectedItemNodeAndContent = (itemNode, ChatContextResultPeekContent(account: item.account, contextResult: item.result, menu: menuItems)) } diff --git a/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift b/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift index fce7434361..1da6c74a9c 100755 --- a/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift +++ b/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift @@ -225,10 +225,8 @@ final class HorizontalStickerGridItemNode: GridItemNode { } func updatePreviewing(animated: Bool) { - var isPreviewing = false - if let (_, item, _) = self.currentState { - //isPreviewing = item.isPreviewed(self.stickerItem) - } + let isPreviewing = false + if self.currentIsPreviewing != isPreviewing { self.currentIsPreviewing = isPreviewing diff --git a/submodules/TelegramUI/Sources/LegacyCamera.swift b/submodules/TelegramUI/Sources/LegacyCamera.swift index d687b115fd..b74f6e4d8d 100644 --- a/submodules/TelegramUI/Sources/LegacyCamera.swift +++ b/submodules/TelegramUI/Sources/LegacyCamera.swift @@ -217,7 +217,7 @@ func presentedLegacyShortcutCamera(context: AccountContext, saveCapturedMedia: B legacyController?.dismiss() } - controller.finishedWithResults = { [weak controller, weak parentController, weak legacyController] overlayController, selectionContext, editingContext, currentItem, _, _ in + controller.finishedWithResults = { [weak parentController] overlayController, selectionContext, editingContext, currentItem, _, _ in if let selectionContext = selectionContext, let editingContext = editingContext { let nativeGenerator = legacyAssetPickerItemGenerator() let signals = TGCameraController.resultSignals(for: selectionContext, editingContext: editingContext, currentItem: currentItem, storeAssets: saveCapturedMedia, saveEditedPhotos: saveEditedPhotos, descriptionGenerator: { _1, _2, _3, _4 in diff --git a/submodules/TelegramUI/Sources/LegacyInstantVideoController.swift b/submodules/TelegramUI/Sources/LegacyInstantVideoController.swift index 85f3fda22d..7018299088 100644 --- a/submodules/TelegramUI/Sources/LegacyInstantVideoController.swift +++ b/submodules/TelegramUI/Sources/LegacyInstantVideoController.swift @@ -197,7 +197,7 @@ func legacyInstantVideoController(theme: PresentationTheme, panelFrame: CGRect, finalDuration = adjustments.trimEndValue - adjustments.trimStartValue } - let adjustmentsData = MemoryBuffer(data: NSKeyedArchiver.archivedData(withRootObject: adjustments.dictionary())) + let adjustmentsData = MemoryBuffer(data: NSKeyedArchiver.archivedData(withRootObject: adjustments.dictionary()!)) let digest = MemoryBuffer(data: adjustmentsData.md5Digest()) resourceAdjustments = VideoMediaResourceAdjustments(data: adjustmentsData, digest: digest) } diff --git a/submodules/TelegramUI/Sources/ManagedAudioRecorder.swift b/submodules/TelegramUI/Sources/ManagedAudioRecorder.swift index 73a70d40ec..8e806c494d 100644 --- a/submodules/TelegramUI/Sources/ManagedAudioRecorder.swift +++ b/submodules/TelegramUI/Sources/ManagedAudioRecorder.swift @@ -595,8 +595,8 @@ final class ManagedAudioRecorderContext { func takeData() -> RecordedAudioData? { if self.oggWriter.writeFrame(nil, frameByteCount: 0) { - var scaledSamplesMemory = malloc(100 * 2)! - var scaledSamples: UnsafeMutablePointer = scaledSamplesMemory.assumingMemoryBound(to: Int16.self) + let scaledSamplesMemory = malloc(100 * 2)! + let scaledSamples: UnsafeMutablePointer = scaledSamplesMemory.assumingMemoryBound(to: Int16.self) defer { free(scaledSamplesMemory) } diff --git a/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift b/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift index 3c3373f2fa..d7c4606ef0 100644 --- a/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift @@ -228,7 +228,7 @@ final class MentionChatInputPanelItemNode: ListViewItemNode { } func updateRevealOffset(offset: CGFloat, transition: ContainedViewLayoutTransition) { - if let (size, leftInset, _) = self.validLayout { + if let (_, leftInset, _) = self.validLayout { transition.updateFrameAdditive(node: self.avatarNode, frame: CGRect(origin: CGPoint(x: min(offset, 0.0) + 12.0 + leftInset, y: self.avatarNode.frame.minY), size: self.avatarNode.frame.size)) transition.updateFrameAdditive(node: self.textNode, frame: CGRect(origin: CGPoint(x: min(offset, 0.0) + 55.0 + leftInset, y: self.textNode.frame.minY), size: self.textNode.frame.size)) } diff --git a/submodules/TelegramUI/Sources/OpenChatMessage.swift b/submodules/TelegramUI/Sources/OpenChatMessage.swift index a379d9859f..c705e9bbcb 100644 --- a/submodules/TelegramUI/Sources/OpenChatMessage.swift +++ b/submodules/TelegramUI/Sources/OpenChatMessage.swift @@ -262,7 +262,7 @@ func openChatWallpaper(context: AccountContext, message: Message, present: @esca case let .color(color): source = .wallpaper(.color(color.argb), nil, [], nil, nil, message) case let .gradient(colors, rotation): - source = .wallpaper(.gradient(nil, colors, WallpaperSettings(rotation: rotation)), nil, [], nil, rotation, message) + source = .wallpaper(.gradient(TelegramWallpaper.Gradient(id: nil, colors: colors, settings: WallpaperSettings(rotation: rotation))), nil, [], nil, rotation, message) } let controller = WallpaperGalleryController(context: context, source: source) diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index f7a2fe8dfc..ff61025692 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -299,7 +299,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur case let .color(color): signal = .single(.color(color.argb)) case let .gradient(colors, rotation): - signal = .single(.gradient(nil, colors, WallpaperSettings(rotation: rotation))) + signal = .single(.gradient(TelegramWallpaper.Gradient(id: nil, colors: colors, settings: WallpaperSettings(rotation: rotation)))) } let _ = (signal diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift index 09b136507d..ee4c88a016 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift @@ -187,6 +187,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu } self.historyNode = ChatHistoryListNode(context: context, chatLocation: .peer(peerId), chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, source: source, subject: .message(id: initialMessageId, highlight: true, timecode: nil), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch)) + self.historyNode.clipsToBounds = true super.init() @@ -528,6 +529,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu let chatLocationContextHolder = Atomic(value: nil) let historyNode = ChatHistoryListNode(context: self.context, chatLocation: .peer(self.peerId), chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: .message(id: messageId, highlight: true, timecode: nil), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch)) + historyNode.clipsToBounds = true historyNode.preloadPages = true historyNode.stackFromBottom = true historyNode.updateFloatingHeaderOffset = { [weak self] offset, _ in diff --git a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift index 777ff43130..f3f7d8bcc2 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift @@ -224,11 +224,11 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode { } else { let fontSize: CGFloat = 17.0 - var baseFont = Font.regular(fontSize) - var linkFont = baseFont - var boldFont = Font.medium(fontSize) - var italicFont = Font.italic(fontSize) - var boldItalicFont = Font.semiboldItalic(fontSize) + let baseFont = Font.regular(fontSize) + let linkFont = baseFont + let boldFont = Font.medium(fontSize) + let italicFont = Font.italic(fontSize) + let boldItalicFont = Font.semiboldItalic(fontSize) let titleFixedFont = Font.monospace(fontSize) let entities = generateTextEntities(item.text, enabledTypes: enabledEntities) diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift index 1fb029429a..8384900f4a 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift @@ -179,7 +179,7 @@ final class PeerInfoGroupsInCommonPaneNode: ASDisplayNode, PeerInfoPaneNode { } private func dequeueTransaction() { - guard let (layout, _, _) = self.currentParams, let transaction = self.enqueuedTransactions.first else { + guard let _ = self.currentParams, let transaction = self.enqueuedTransactions.first else { return } diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift index c5bd2ad74a..caaa6c1401 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift @@ -60,6 +60,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { let chatLocationContextHolder = Atomic(value: nil) self.listNode = ChatHistoryListNode(context: context, chatLocation: .peer(peerId), chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: nil, controllerInteraction: chatControllerInteraction, selectedMessages: self.selectedMessagesPromise.get(), mode: .list(search: false, reversed: false, displayHeaders: .allButLast, hintLinks: tagMask == .webPage, isGlobalSearch: false)) + self.listNode.clipsToBounds = true self.listNode.defaultToSynchronousTransactionWhileScrolling = true self.listNode.scroller.bounces = false diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift index 676828b575..bfe3e5513e 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift @@ -408,7 +408,6 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: PeerId, account let proxySettings: ProxySettings = sharedPreferences.entries[SharedDataKeys.proxySettings] as? ProxySettings ?? ProxySettings.defaultSettings let inAppNotificationSettings: InAppNotificationSettings = sharedPreferences.entries[ApplicationSpecificSharedDataKeys.inAppNotificationSettings] as? InAppNotificationSettings ?? InAppNotificationSettings.defaultSettings - let experimentalUISettings: ExperimentalUISettings = sharedPreferences.entries[ApplicationSpecificSharedDataKeys.experimentalUISettings] as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings let unreadTrendingStickerPacks = featuredStickerPacks.reduce(0, { count, item -> Int in return item.unread ? count + 1 : count @@ -644,7 +643,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen if currentInvitationsContext == nil { var canManageInvitations = false - if let channel = peerViewMainPeer(peerView) as? TelegramChannel, let cachedData = peerView.cachedData as? CachedChannelData, channel.flags.contains(.isCreator) || (channel.adminRights?.rights.contains(.canInviteUsers) == true) { + if let channel = peerViewMainPeer(peerView) as? TelegramChannel, let _ = peerView.cachedData as? CachedChannelData, channel.flags.contains(.isCreator) || (channel.adminRights?.rights.contains(.canInviteUsers) == true) { canManageInvitations = true } if canManageInvitations { @@ -1063,11 +1062,7 @@ func peerInfoHeaderButtons(peer: Peer?, cachedData: CachedPeerData?, isOpenedFro result.append(.more) } } else if let group = peer as? TelegramGroup { - var canEditGroupInfo = false - var canEditMembers = false var canAddMembers = false - var isPublic = false - var isCreator = false var hasVoiceChat = false var canStartVoiceChat = false @@ -1081,21 +1076,13 @@ func peerInfoHeaderButtons(peer: Peer?, cachedData: CachedPeerData?, isOpenedFro canStartVoiceChat = true } } - - if case .creator = group.role { - isCreator = true - } + switch group.role { case .admin, .creator: - canEditGroupInfo = true - canEditMembers = true canAddMembers = true case .member: break } - if !group.hasBannedPermission(.banChangeInfo) { - canEditGroupInfo = true - } if !group.hasBannedPermission(.banAddMembers) { canAddMembers = true } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift index 8d8a84b24f..3ef709dae0 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift @@ -38,7 +38,7 @@ final class PeerInfoPaneWrapper { } func update(size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition) { - if let (currentSize, currentSideInset, currentBottomInset, visibleHeight, currentIsScrollingLockedAtTop, currentExpandProgress, currentPresentationData) = self.appliedParams { + if let (currentSize, currentSideInset, currentBottomInset, _, currentIsScrollingLockedAtTop, currentExpandProgress, currentPresentationData) = self.appliedParams { if currentSize == size && currentSideInset == sideInset && currentBottomInset == bottomInset, currentIsScrollingLockedAtTop == isScrollingLockedAtTop && currentExpandProgress == expandProgress && currentPresentationData === presentationData { return } @@ -180,11 +180,9 @@ final class PeerInfoPaneTabsContainerNode: ASDisplayNode { self.currentParams = (paneList, selectedPane, presentationData) for specifier in paneList { let paneNode: PeerInfoPaneTabsContainerPaneNode - var wasAdded = false if let current = self.paneNodes[specifier.key] { paneNode = current } else { - wasAdded = true paneNode = PeerInfoPaneTabsContainerPaneNode(pressed: { [weak self] in self?.paneSelected(specifier.key) }) @@ -597,7 +595,6 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat directionIsToRight = translation.x > size.width / 2.0 } } - var updated = false if let directionIsToRight = directionIsToRight { var updatedIndex = currentIndex if directionIsToRight { @@ -608,7 +605,6 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat let switchToKey = availablePanes[updatedIndex] if switchToKey != self.currentPaneKey && self.currentPanes[switchToKey] != nil{ self.currentPaneKey = switchToKey - updated = true } } self.transitionFraction = 0.0 @@ -787,8 +783,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat var paneSwitchAnimationOffset: CGFloat = 0.0 var updatedCurrentIndex = currentIndex - var animatePaneTransitionOffset: CGFloat? - if let pendingSwitchToPaneKey = self.pendingSwitchToPaneKey, let pane = self.currentPanes[pendingSwitchToPaneKey] { + if let pendingSwitchToPaneKey = self.pendingSwitchToPaneKey, let _ = self.currentPanes[pendingSwitchToPaneKey] { self.pendingSwitchToPaneKey = nil previousPaneKey = self.currentPaneKey self.currentPaneKey = pendingSwitchToPaneKey @@ -821,7 +816,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat return } pane.isAnimatingOut = false - if let (size, sideInset, bottomInset, visibleHeight, expansionFraction, presentationData, data) = strongSelf.currentParams { + if let (_, _, _, _, _, _, data) = strongSelf.currentParams { if let availablePanes = data?.availablePanes, let currentPaneKey = strongSelf.currentPaneKey, let currentIndex = availablePanes.firstIndex(of: currentPaneKey), let paneIndex = availablePanes.firstIndex(of: key), abs(paneIndex - currentIndex) <= 1 { } else { if let pane = strongSelf.currentPanes.removeValue(forKey: key) { @@ -838,7 +833,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat transition.animateFrame(node: pane.node, from: paneFrame, to: paneFrame.offsetBy(dx: -paneSwitchAnimationOffset, dy: 0.0), completion: isAnimatingOut ? nil : { _ in paneCompletion() }) - } else if let previousPaneKey = previousPaneKey, key == self.currentPaneKey { + } else if let _ = previousPaneKey, key == self.currentPaneKey { pane.node.frame = adjustedFrame let isAnimatingOut = pane.isAnimatingOut pane.isAnimatingOut = true diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index f31d6c0c16..21b5aa76e3 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -61,7 +61,7 @@ import TelegramCallsUI import PeerInfoAvatarListNode import PasswordSetupUI -protocol PeerInfoScreenItem: class { +protocol PeerInfoScreenItem: AnyObject { var id: AnyHashable { get } func node() -> PeerInfoScreenItemNode } @@ -1188,7 +1188,6 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr let ItemDiscussionGroup = 3 let ItemSignMessages = 4 let ItemSignMessagesHelp = 5 - let ItemAutoremove = 6 if channel.flags.contains(.isCreator) { let linkText: String @@ -1261,7 +1260,6 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr let ItemLocationHeader = 110 let ItemLocation = 111 let ItemLocationSetup = 112 - let ItemAutoremove = 113 let ItemDeleteGroup = 114 let isCreator = channel.flags.contains(.isCreator) @@ -1399,7 +1397,6 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr let ItemPreHistory = 103 let ItemPermissions = 104 let ItemAdmins = 105 - let ItemAutoremove = 106 var canViewAdminsAndBanned = false @@ -3128,7 +3125,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD } }) }), centralItemUpdated: { [weak self] messageId in - self?.paneContainerNode.requestExpandTabs?() + let _ = self?.paneContainerNode.requestExpandTabs?() self?.paneContainerNode.currentPane?.node.ensureMessageIsVisible(id: messageId) })) } @@ -3159,7 +3156,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD break } }, sendFile: nil, - sendSticker: { _, _, _ in + sendSticker: { _, _, _ in return false }, requestMessageActionUrlAuth: nil, joinVoiceChat: { peerId, invite, call in @@ -3270,7 +3267,6 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD cancelImpl = { [weak self] in self?.resolvePeerByNameDisposable?.set(nil) } - disposable.set((resolveSignal |> take(1) |> mapToSignal { peer -> Signal in @@ -3297,7 +3293,6 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD if self.resolvePeerByNameDisposable == nil { self.resolvePeerByNameDisposable = MetaDisposable() } - let account = self.context.account var resolveSignal: Signal if let peerName = peerName { resolveSignal = self.context.engine.peers.resolvePeerByName(name: peerName) @@ -6592,16 +6587,6 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen { drawPeerAvatarLetters(context: context, size: CGSize(width: size.width - inset * 2.0, height: size.height - inset * 2.0), font: avatarFont, letters: displayLetters, peerId: primary.1.id) })?.withRenderingMode(.alwaysOriginal) - let selectedImage = generateImage(size, rotatedContext: { size, context in - context.clear(CGRect(origin: CGPoint(), size: size)) - context.translateBy(x: inset, y: inset) - drawPeerAvatarLetters(context: context, size: CGSize(width: size.width - inset * 2.0, height: size.height - inset * 2.0), font: avatarFont, letters: displayLetters, peerId: primary.1.id) - context.translateBy(x: -inset, y: -inset) - context.setLineWidth(1.0) - context.setStrokeColor(primary.2.rootController.tabBar.selectedIconColor.cgColor) - context.strokeEllipse(in: CGRect(x: 1.0, y: 1.0, width: 27.0, height: 27.0)) - })?.withRenderingMode(.alwaysOriginal) - subscriber.putNext(image.flatMap { ($0, $0) }) subscriber.putCompletion() return EmptyDisposable @@ -7036,7 +7021,7 @@ private final class PeerInfoNavigationTransitionNode: ASDisplayNode, CustomNavig transition.updateAlpha(node: self.headerNode.navigationButtonContainer, alpha: (1.0 - fraction)) - if case let .animated(duration, _) = transition, (bottomNavigationBar.additionalContentNode.alpha.isZero || bottomNavigationBar.additionalContentNode.alpha == 1.0) { + if case .animated = transition, (bottomNavigationBar.additionalContentNode.alpha.isZero || bottomNavigationBar.additionalContentNode.alpha == 1.0) { bottomNavigationBar.additionalContentNode.alpha = fraction if fraction.isZero { bottomNavigationBar.additionalContentNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15) diff --git a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift index aaa02a6c6a..a53e1eb2eb 100644 --- a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift +++ b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift @@ -29,14 +29,6 @@ private enum PeerMessagesMediaPlaylistNavigation { struct MessageMediaPlaylistItemStableId: Hashable { let stableId: UInt32 - - var hashValue: Int { - return self.stableId.hashValue - } - - static func ==(lhs: MessageMediaPlaylistItemStableId, rhs: MessageMediaPlaylistItemStableId) -> Bool { - return lhs.stableId == rhs.stableId - } } private func extractFileMedia(_ message: Message) -> TelegramMediaFile? { @@ -736,12 +728,6 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist { } if case .all = looping { - let viewIndex: HistoryViewInputAnchor - if case .earlier = navigation { - viewIndex = .upperBound - } else { - viewIndex = .lowerBound - } return .single((nil, messages.count, false)) } else { if hasMore { diff --git a/submodules/TelegramUI/Sources/PeerSelectionControllerNode.swift b/submodules/TelegramUI/Sources/PeerSelectionControllerNode.swift index c599ae7588..d2eb9bf39a 100644 --- a/submodules/TelegramUI/Sources/PeerSelectionControllerNode.swift +++ b/submodules/TelegramUI/Sources/PeerSelectionControllerNode.swift @@ -286,10 +286,7 @@ final class PeerSelectionControllerNode: ASDisplayNode { guard let textInputNode = textInputPanelNode.textInputNode else { return } - let controller = ChatSendMessageActionSheetController(context: strongSelf.context, interfaceState: strongSelf.presentationInterfaceState, gesture: gesture, sourceSendButton: node, textInputNode: textInputNode, completion: { [weak self] in - if let strongSelf = self { -// strongSelf.supportedOrientations = previousSupportedOrientations - } + let controller = ChatSendMessageActionSheetController(context: strongSelf.context, interfaceState: strongSelf.presentationInterfaceState, gesture: gesture, sourceSendButton: node, textInputNode: textInputNode, completion: { }, sendMessage: { [weak textInputPanelNode] silently in textInputPanelNode?.sendMessage(silently ? .silent : .generic) }, schedule: { [weak textInputPanelNode] in diff --git a/submodules/TelegramUI/Sources/PeerSelectionTextInputPanelNode.swift b/submodules/TelegramUI/Sources/PeerSelectionTextInputPanelNode.swift index 85638d8729..cfd7f85ebd 100644 --- a/submodules/TelegramUI/Sources/PeerSelectionTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/PeerSelectionTextInputPanelNode.swift @@ -394,9 +394,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDel self.validLayout = (width, leftInset, rightInset, additionalSideInsets, maxHeight, metrics, isSecondary) var transition = transition - var additionalOffset: CGFloat = 0.0 if let previousAdditionalSideInsets = previousAdditionalSideInsets, previousAdditionalSideInsets.right != additionalSideInsets.right { - additionalOffset = (previousAdditionalSideInsets.right - additionalSideInsets.right) / 3.0 if case .animated = transition { transition = .animated(duration: 0.2, curve: .easeInOut) @@ -520,19 +518,13 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDel textFieldMinHeight = calclulateTextFieldMinHeight(presentationInterfaceState, metrics: metrics) } let minimalHeight: CGFloat = 14.0 + textFieldMinHeight - let minimalInputHeight: CGFloat = 2.0 + textFieldMinHeight - - var animatedTransition = true - if case .immediate = transition { - animatedTransition = false - } let baseWidth = width - leftInset - rightInset - let (accessoryButtonsWidth, textFieldHeight) = self.calculateTextFieldMetrics(width: baseWidth, maxHeight: maxHeight, metrics: metrics) + let (_, textFieldHeight) = self.calculateTextFieldMetrics(width: baseWidth, maxHeight: maxHeight, metrics: metrics) let panelHeight = self.panelHeight(textFieldHeight: textFieldHeight, metrics: metrics) - var composeButtonsOffset: CGFloat = 0.0 - var textInputBackgroundWidthOffset: CGFloat = 0.0 + let composeButtonsOffset: CGFloat = 0.0 + let textInputBackgroundWidthOffset: CGFloat = 0.0 self.updateCounterTextNode(transition: transition) @@ -542,8 +534,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDel if let presentationInterfaceState = self.presentationInterfaceState { self.actionButtons.updateLayout(size: CGSize(width: 44.0, height: minimalHeight), transition: transition, interfaceState: presentationInterfaceState) } - - let searchLayoutClearButtonSize = CGSize(width: 44.0, height: minimalHeight) + var textFieldInsets = self.textFieldInsets(metrics: metrics) if additionalSideInsets.right > 0.0 { textFieldInsets.right += additionalSideInsets.right / 3.0 @@ -619,7 +610,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDel } if let (width, leftInset, rightInset, _, maxHeight, metrics, _) = self.validLayout { - var composeButtonsOffset: CGFloat = 0.0 + let composeButtonsOffset: CGFloat = 0.0 let (_, textFieldHeight) = self.calculateTextFieldMetrics(width: width - leftInset - rightInset, maxHeight: maxHeight, metrics: metrics) let panelHeight = self.panelHeight(textFieldHeight: textFieldHeight, metrics: metrics) diff --git a/submodules/TelegramUI/Sources/ShareExtensionContext.swift b/submodules/TelegramUI/Sources/ShareExtensionContext.swift index 4d9c7abe63..7db09e7585 100644 --- a/submodules/TelegramUI/Sources/ShareExtensionContext.swift +++ b/submodules/TelegramUI/Sources/ShareExtensionContext.swift @@ -951,7 +951,7 @@ public class ShareRootControllerImpl { strongSelf.mainWindow?.present(controller, on: .root) } else { let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 } - if let user = peer as? TelegramUser { + if let _ = peer as? TelegramUser { let text: String switch result { case .allowed: diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index 8aec63ba38..b6fd0e5700 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -1132,7 +1132,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { if !found { let controllerParams = LocationViewParams(sendLiveLocation: { location in - let outMessage: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: location), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil) + //let outMessage: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: location), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil) // params.enqueueMessage(outMessage) }, stopLiveLocation: { messageId in if let messageId = messageId { @@ -1376,7 +1376,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { let controller = generator(legacyController.context) legacyController.bind(controller: controller) legacyController.deferScreenEdgeGestures = [.top] - controller.selectionBlock = { [weak legacyController, weak controller] asset, _ in + controller.selectionBlock = { [weak legacyController] asset, _ in if let asset = asset { let _ = (fetchPhotoLibraryImage(localIdentifier: asset.backingAsset.localIdentifier, thumbnail: false) |> deliverOnMainQueue).start(next: { imageAndFlag in diff --git a/submodules/TelegramUI/Sources/SpotlightContacts.swift b/submodules/TelegramUI/Sources/SpotlightContacts.swift index a618da2ec4..d1e97aeb19 100644 --- a/submodules/TelegramUI/Sources/SpotlightContacts.swift +++ b/submodules/TelegramUI/Sources/SpotlightContacts.swift @@ -90,7 +90,7 @@ private final class SpotlightIndexStorage { func update(items: [PeerId: SpotlightIndexStorageItem]) { let validPeerIds = Set(items.keys) var removePeerIds: [PeerId] = [] - for (peerId, item) in self.items { + for (peerId, _) in self.items { if !validPeerIds.contains(peerId) { removePeerIds.append(peerId) } diff --git a/submodules/TelegramUI/Sources/StickersChatInputContextPanelItem.swift b/submodules/TelegramUI/Sources/StickersChatInputContextPanelItem.swift index e850e9e665..23aec1d1db 100644 --- a/submodules/TelegramUI/Sources/StickersChatInputContextPanelItem.swift +++ b/submodules/TelegramUI/Sources/StickersChatInputContextPanelItem.swift @@ -125,7 +125,7 @@ final class StickersChatInputContextPanelItemNode: ListViewItemNode { for i in 0 ..< self.nodes.count { if self.nodes[i].frame.contains(location) { let file = item.files[i] - item.interfaceInteraction.sendSticker(.standalone(media: file), true, self.nodes[i], self.nodes[i].bounds) + let _ = item.interfaceInteraction.sendSticker(.standalone(media: file), true, self.nodes[i], self.nodes[i].bounds) break } } diff --git a/submodules/TelegramUI/Sources/ThemeUpdateManager.swift b/submodules/TelegramUI/Sources/ThemeUpdateManager.swift index 7a9d169ea1..cc9014cef7 100644 --- a/submodules/TelegramUI/Sources/ThemeUpdateManager.swift +++ b/submodules/TelegramUI/Sources/ThemeUpdateManager.swift @@ -90,8 +90,8 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager { } let resolvedWallpaper: Signal - if case let .file(id, _, _, _, _, _, slug, _, settings) = presentationTheme.chat.defaultWallpaper, id == 0 { - resolvedWallpaper = cachedWallpaper(account: account, slug: slug, settings: settings) + if case let .file(file) = presentationTheme.chat.defaultWallpaper, file.id == 0 { + resolvedWallpaper = cachedWallpaper(account: account, slug: file.slug, settings: file.settings) |> map { wallpaper in return wallpaper?.wallpaper } @@ -101,15 +101,15 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager { return resolvedWallpaper |> mapToSignal { wallpaper -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in - if let wallpaper = wallpaper, case let .file(_, _, _, _, _, _, slug, file, _) = wallpaper { + if let wallpaper = wallpaper, case let .file(file) = wallpaper { var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(slug), resource: file.resource))) - return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) + return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in guard complete, let fullSizeData = fullSizeData else { return .complete() } - accountManager.mediaBox.storeResourceData(file.resource.id, data: fullSizeData, synchronous: true) + accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData, synchronous: true) return .single((.cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: wallpaper, creatorAccountId: theme.isCreator ? account.id : nil)), presentationTheme)) } } else { diff --git a/submodules/TelegramUI/Sources/TonePlayer.swift b/submodules/TelegramUI/Sources/TonePlayer.swift index 553cc62e39..ff5bebc67a 100644 --- a/submodules/TelegramUI/Sources/TonePlayer.swift +++ b/submodules/TelegramUI/Sources/TonePlayer.swift @@ -45,7 +45,6 @@ private final class TonePlayerContext { func start() { do { - let currentVolume = AVAudioSession.sharedInstance().outputVolume //let gainFactor = max(0.1, min(1.5, self.initialVolume / currentVolume)) try self.audioEngine.start() diff --git a/submodules/TelegramUI/Sources/WallpaperUploadManager.swift b/submodules/TelegramUI/Sources/WallpaperUploadManager.swift index 7e9ffe3c48..af4adbb5ca 100644 --- a/submodules/TelegramUI/Sources/WallpaperUploadManager.swift +++ b/submodules/TelegramUI/Sources/WallpaperUploadManager.swift @@ -94,9 +94,9 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager { |> map { result -> UploadWallpaperStatus in switch result { case let .complete(wallpaper): - if case let .file(_, _, _, _, _, _, _, file, _) = wallpaper { - sharedContext.accountManager.mediaBox.moveResourceData(from: currentResource.id, to: file.resource.id) - account.postbox.mediaBox.moveResourceData(from: currentResource.id, to: file.resource.id) + if case let .file(file) = wallpaper { + sharedContext.accountManager.mediaBox.moveResourceData(from: currentResource.id, to: file.file.resource.id) + account.postbox.mediaBox.moveResourceData(from: currentResource.id, to: file.file.resource.id) } default: break @@ -105,7 +105,7 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager { } let autoNightModeTriggered = presentationData.autoNightModeTriggered - disposable.set(uploadSignal.start(next: { [weak self] status in + disposable.set(uploadSignal.start(next: { status in if case let .complete(wallpaper) = status { let updateWallpaper: (TelegramWallpaper) -> Void = { wallpaper in if let resource = wallpaper.mainResource { @@ -133,10 +133,10 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager { })).start() } - if case let .file(_, _, _, _, _, _, _, file, settings) = wallpaper, settings.blur { - let _ = account.postbox.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start(completed: { + if case let .file(file) = wallpaper, file.settings.blur { + let _ = account.postbox.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start(completed: { }) - let _ = sharedContext.accountManager.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start(completed: { + let _ = sharedContext.accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start(completed: { updateWallpaper(wallpaper) }) } else { diff --git a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift index 1e6418db67..8f5d568e00 100644 --- a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift @@ -573,10 +573,10 @@ public struct PresentationThemeSettings: PreferencesEntry { switch wallpaper { case let .image(representations, _): return representations.map { $0.resource.id } - case let .file(_, _, _, _, _, _, _, file, _): + case let .file(file): var resources: [MediaResourceId] = [] - resources.append(file.resource.id) - resources.append(contentsOf: file.previewRepresentations.map { $0.resource.id }) + resources.append(file.file.resource.id) + resources.append(contentsOf: file.file.previewRepresentations.map { $0.resource.id }) return resources default: return [] diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index e7ab2e6551..d6ae34201c 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -116,13 +116,13 @@ public final class WallpaperBackgroundNode: ASDisplayNode { var isInvertedGradient = false var hasComplexGradient = false switch wallpaper { - case let .file(_, _, _, _, _, _, _, _, settings): - hasComplexGradient = settings.colors.count >= 3 - if let intensity = settings.intensity, intensity < 0 { + case let .file(file): + hasComplexGradient = file.settings.colors.count >= 3 + if let intensity = file.settings.intensity, intensity < 0 { isInvertedGradient = true } - case let .gradient(_, colors, _): - hasComplexGradient = colors.count >= 3 + case let .gradient(gradient): + hasComplexGradient = gradient.colors.count >= 3 default: break } @@ -417,13 +417,13 @@ public final class WallpaperBackgroundNode: ASDisplayNode { if case let .color(color) = wallpaper { gradientColors = [color] self._isReady.set(true) - } else if case let .gradient(_, colors, settings) = wallpaper { - gradientColors = colors - gradientAngle = settings.rotation ?? 0 + } else if case let .gradient(gradient) = wallpaper { + gradientColors = gradient.colors + gradientAngle = gradient.settings.rotation ?? 0 self._isReady.set(true) - } else if case let .file(_, _, _, _, isPattern, _, _, _, settings) = wallpaper, isPattern { - gradientColors = settings.colors - gradientAngle = settings.rotation ?? 0 + } else if case let .file(file) = wallpaper, file.isPattern { + gradientColors = file.settings.colors + gradientAngle = file.settings.rotation ?? 0 } if gradientColors.count >= 3 { @@ -526,11 +526,11 @@ public final class WallpaperBackgroundNode: ASDisplayNode { } switch wallpaper { - case let .file(_, _, _, _, isPattern, _, _, _, settings) where isPattern: - let brightness = UIColor.average(of: settings.colors.map(UIColor.init(rgb:))).hsb.b + case let .file(file) where file.isPattern: + let brightness = UIColor.average(of: file.settings.colors.map(UIColor.init(rgb:))).hsb.b let patternIsBlack = brightness <= 0.01 - let intensity = CGFloat(settings.intensity ?? 50) / 100.0 + let intensity = CGFloat(file.settings.intensity ?? 50) / 100.0 if intensity < 0 { self.patternImageNode.alpha = 1.0 self.patternImageNode.layer.compositingFilter = nil @@ -580,14 +580,14 @@ public final class WallpaperBackgroundNode: ASDisplayNode { var patternIsLight: Bool = false switch wallpaper { - case let .file(_, _, _, _, isPattern, _, slug, file, settings) where isPattern: + case let .file(file) where file.isPattern: var updated = true - let brightness = UIColor.average(of: settings.colors.map(UIColor.init(rgb:))).hsb.b + let brightness = UIColor.average(of: file.settings.colors.map(UIColor.init(rgb:))).hsb.b patternIsLight = brightness > 0.3 if let previousWallpaper = self.validPatternImage?.wallpaper { switch previousWallpaper { - case let .file(_, _, _, _, _, _, _, previousFile, _): - if file.id == previousFile.id { + case let .file(previousFile): + if file.file.id == previousFile.file.id { updated = false } default: @@ -606,15 +606,15 @@ public final class WallpaperBackgroundNode: ASDisplayNode { if let message = message { return .media(media: .message(message: MessageReference(message), media: media), resource: resource) } - return .wallpaper(wallpaper: .slug(slug), resource: resource) + return .wallpaper(wallpaper: .slug(file.slug), resource: resource) } var convertedRepresentations: [ImageRepresentationWithReference] = [] - for representation in file.previewRepresentations { - convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: reference(for: representation.resource, media: file, message: nil))) + for representation in file.file.previewRepresentations { + convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: reference(for: representation.resource, media: file.file, message: nil))) } - let dimensions = file.dimensions ?? PixelDimensions(width: 2000, height: 4000) - convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: reference(for: file.resource, media: file, message: nil))) + let dimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000) + convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: reference(for: file.file.resource, media: file.file, message: nil))) let signal = patternWallpaperImage(account: self.context.account, accountManager: self.context.sharedContext.accountManager, representations: convertedRepresentations, mode: .screen, autoFetchFullSize: true) self.patternImageDisposable.set((signal @@ -636,7 +636,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode { })) } } - let intensity = CGFloat(settings.intensity ?? 50) / 100.0 + let intensity = CGFloat(file.settings.intensity ?? 50) / 100.0 invertPattern = intensity < 0 default: self.updatePatternPresentation() diff --git a/submodules/WallpaperResources/Sources/WallpaperCache.swift b/submodules/WallpaperResources/Sources/WallpaperCache.swift index fd4f6bef3e..3a0a933cd7 100644 --- a/submodules/WallpaperResources/Sources/WallpaperCache.swift +++ b/submodules/WallpaperResources/Sources/WallpaperCache.swift @@ -48,8 +48,8 @@ public func cachedWallpaper(account: Account, slug: String, settings: WallpaperS let id = ItemCacheEntryId(collectionId: ApplicationSpecificItemCacheCollectionId.cachedWallpapers, key: key) if var wallpaper = wallpaper { switch wallpaper { - case let .file(id, accessHash, isCreator, isDefault, isPattern, isDark, slug, file, settings): - wallpaper = .file(id: id, accessHash: accessHash, isCreator: isCreator, isDefault: isDefault, isPattern: isPattern, isDark: isDark, slug: slug, file: file.withUpdatedResource(WallpaperDataResource(slug: slug)), settings: settings) + case let .file(file): + wallpaper = .file(TelegramWallpaper.File(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: file.isPattern, isDark: file.isDark, slug: file.slug, file: file.file.withUpdatedResource(WallpaperDataResource(slug: slug)), settings: file.settings)) default: break } @@ -71,12 +71,12 @@ public func cachedWallpaper(account: Account, slug: String, settings: WallpaperS } public func updateCachedWallpaper(account: Account, wallpaper: TelegramWallpaper) { - guard case let .file(id, _, _, _, _, _, slug, _, _) = wallpaper, id != 0 else { + guard case let .file(file) = wallpaper, file.id != 0 else { return } let _ = (account.postbox.transaction { transaction in let key = ValueBoxKey(length: 8) - key.setInt64(0, value: Int64(bitPattern: slug.persistentHashValue)) + key.setInt64(0, value: Int64(bitPattern: file.slug.persistentHashValue)) let id = ItemCacheEntryId(collectionId: ApplicationSpecificItemCacheCollectionId.cachedWallpapers, key: key) transaction.putItemCacheEntry(id: id, entry: CachedWallpaper(wallpaper: wallpaper), collectionSpec: collectionSpec) }).start() diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index 84466da289..d27283c899 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -918,25 +918,25 @@ public func drawThemeImage(context c: CGContext, theme: PresentationTheme, wallp case let .color(color): c.setFillColor(UIColor(rgb: color).cgColor) c.fill(drawingRect) - case let .gradient(_, colors, _): - if colors.count >= 3 { - let image = GradientBackgroundNode.generatePreview(size: CGSize(width: 60.0, height: 60.0), colors: colors.map(UIColor.init(rgb:))) + case let .gradient(gradient): + if gradient.colors.count >= 3 { + let image = GradientBackgroundNode.generatePreview(size: CGSize(width: 60.0, height: 60.0), colors: gradient.colors.map(UIColor.init(rgb:))) c.draw(image.cgImage!, in: drawingRect) - } else if colors.count >= 2 { - let gradientColors = colors.map({ UIColor(rgb: $0).cgColor }) as CFArray + } else if gradient.colors.count >= 2 { + let gradientColors = gradient.colors.map({ UIColor(rgb: $0).cgColor }) as CFArray var locations: [CGFloat] = [0.0, 1.0] let colorSpace = CGColorSpaceCreateDeviceRGB() - let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! - c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: drawingRect.height), end: CGPoint(x: 0.0, y: 0.0), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) - } else if colors.count >= 1 { - let gradientColors = [UIColor(rgb: colors[0]), UIColor(rgb: colors[0])] as CFArray + let cgGradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! + c.drawLinearGradient(cgGradient, start: CGPoint(x: 0.0, y: drawingRect.height), end: CGPoint(x: 0.0, y: 0.0), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) + } else if gradient.colors.count >= 1 { + let gradientColors = [UIColor(rgb: gradient.colors[0]), UIColor(rgb: gradient.colors[0])] as CFArray var locations: [CGFloat] = [0.0, 1.0] let colorSpace = CGColorSpaceCreateDeviceRGB() - let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! - c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: drawingRect.height), end: CGPoint(x: 0.0, y: 0.0), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) + let cgGradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! + c.drawLinearGradient(cgGradient, start: CGPoint(x: 0.0, y: drawingRect.height), end: CGPoint(x: 0.0, y: 0.0), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) } - case let .file(_, _, _, _, isPattern, _, _, _, settings): - if isPattern, let intensity = settings.intensity, intensity < 0 { + case let .file(file): + if file.isPattern, let intensity = file.settings.intensity, intensity < 0 { c.setFillColor(UIColor.black.cgColor) c.fill(CGRect(origin: CGPoint(), size: size)) } else { @@ -1143,31 +1143,31 @@ public func themeImage(account: Account, accountManager: AccountManager, source: let data = theme |> mapToSignal { (theme, thumbnailData) -> Signal<(PresentationTheme?, WallpaperImage?, Data?), NoError> in if let theme = theme { - if case let .file(_, _, _, _, _, _, slug, _, settings) = theme.chat.defaultWallpaper { - return cachedWallpaper(account: account, slug: slug, settings: settings) + if case let .file(file) = theme.chat.defaultWallpaper { + return cachedWallpaper(account: account, slug: file.slug, settings: file.settings) |> mapToSignal { wallpaper -> Signal<(PresentationTheme?, WallpaperImage?, Data?), NoError> in - if let wallpaper = wallpaper, case let .file(_, _, _, _, _, _, slug, file, settings) = wallpaper.wallpaper { + if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(slug), resource: file.resource))) - return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) + return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationTheme?, WallpaperImage?, Data?), NoError> in guard complete, let fullSizeData = fullSizeData else { return .complete() } - accountManager.mediaBox.storeResourceData(file.resource.id, data: fullSizeData) - let _ = accountManager.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start() + accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData) + let _ = accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start() - if wallpaper.wallpaper.isPattern, !settings.colors.isEmpty, let intensity = settings.intensity { - return accountManager.mediaBox.resourceData(file.resource) + if wallpaper.wallpaper.isPattern, !file.settings.colors.isEmpty, let intensity = file.settings.intensity { + return accountManager.mediaBox.resourceData(file.file.resource) |> mapToSignal { data in if data.complete, let imageData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) { - return .single((theme, .pattern(data: imageData, colors: settings.colors, intensity: intensity), thumbnailData)) + return .single((theme, .pattern(data: imageData, colors: file.settings.colors, intensity: intensity), thumbnailData)) } else { return .complete() } } - } else if settings.blur { - return accountManager.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true) + } else if file.settings.blur { + return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true) |> mapToSignal { data in if data.complete, let data = try? Data(contentsOf: URL(fileURLWithPath: data.path)), let image = UIImage(data: data) { return .single((theme, .image(image), thumbnailData)) @@ -1327,52 +1327,52 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the backgroundColor = (UIColor(rgb: 0xd6e2ee), nil, []) case let .color(color): backgroundColor = (UIColor(rgb: color), nil, []) - case let .gradient(_, colors, settings): - if colors.count >= 2 { - backgroundColor = (UIColor(rgb: colors[0]), UIColor(rgb: colors[1]), colors) + case let .gradient(gradient): + if gradient.colors.count >= 2 { + backgroundColor = (UIColor(rgb: gradient.colors[0]), UIColor(rgb: gradient.colors[1]), gradient.colors) } else { backgroundColor = (.white, nil, []) } - rotation = settings.rotation + rotation = gradient.settings.rotation case .image: backgroundColor = (.black, nil, []) - case let .file(_, _, _, _, isPattern, _, slug, _, settings): - rotation = settings.rotation - if isPattern, let intensity = settings.intensity, intensity < 0 { + case let .file(file): + rotation = file.settings.rotation + if file.isPattern, let intensity = file.settings.intensity, intensity < 0 { backgroundColor = (.black, nil, []) - } else if !settings.colors.isEmpty { + } else if !file.settings.colors.isEmpty { var bottomColor: UIColor? - if settings.colors.count >= 2 { - bottomColor = UIColor(rgb: settings.colors[1]) + if file.settings.colors.count >= 2 { + bottomColor = UIColor(rgb: file.settings.colors[1]) } - backgroundColor = (UIColor(rgb: settings.colors[0]), bottomColor, settings.colors) + backgroundColor = (UIColor(rgb: file.settings.colors[0]), bottomColor, file.settings.colors) } else { backgroundColor = (theme.chatList.backgroundColor, nil, []) } - wallpaperSignal = cachedWallpaper(account: account, slug: slug, settings: settings) + wallpaperSignal = cachedWallpaper(account: account, slug: file.slug, settings: file.settings) |> mapToSignal { wallpaper in - if let wallpaper = wallpaper, case let .file(_, _, _, _, _, _, _, file, settings) = wallpaper.wallpaper { + if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { var effectiveBackgroundColor = backgroundColor - if !settings.colors.isEmpty { + if !file.settings.colors.isEmpty { var bottomColor: UIColor? - if settings.colors.count >= 2 { - bottomColor = UIColor(rgb: settings.colors[1]) + if file.settings.colors.count >= 2 { + bottomColor = UIColor(rgb: file.settings.colors[1]) } - effectiveBackgroundColor = (UIColor(rgb: settings.colors[0]), bottomColor, settings.colors) + effectiveBackgroundColor = (UIColor(rgb: file.settings.colors[0]), bottomColor, file.settings.colors) } var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(slug), resource: file.resource))) - return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) + return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal<((UIColor, UIColor?, [UInt32]), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in guard complete, let fullSizeData = fullSizeData else { return .complete() } - accountManager.mediaBox.storeResourceData(file.resource.id, data: fullSizeData) - let _ = accountManager.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start() + accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData) + let _ = accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start() if wallpaper.wallpaper.isPattern { - if !settings.colors.isEmpty, let intensity = settings.intensity { + if !file.settings.colors.isEmpty, let intensity = file.settings.intensity { if intensity < 0 { return .single(((.black, nil, []), incomingColor, outgoingColor, nil, rotation)) } else { @@ -1381,8 +1381,8 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the } else { return .complete() } - } else if settings.blur { - return accountManager.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true) + } else if file.settings.blur { + return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true) |> mapToSignal { _ in if let image = UIImage(data: fullSizeData) { return .single((backgroundColor, incomingColor, outgoingColor, image, rotation)) @@ -1480,8 +1480,8 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the public func wallpaperThumbnail(account: Account, accountManager: AccountManager, fileReference: FileMediaReference, wallpaper: TelegramWallpaper, synchronousLoad: Bool) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { switch wallpaper { - case let .file(_, _, _, _, _, _, _, file, settings): - guard let thumbnail = smallestImageRepresentation(file.previewRepresentations) else { + case let .file(file): + guard let thumbnail = smallestImageRepresentation(file.file.previewRepresentations) else { return .single({ _ in nil }) } let signal: Signal = Signal { subscriber in @@ -1514,12 +1514,12 @@ public func wallpaperThumbnail(account: Account, accountManager: AccountManager, let context = DrawingContext(size: arguments.boundingSize, clear: true) context.withFlippedContext { c in - let colors = settings.colors.map(UIColor.init(rgb:)) + let colors = file.settings.colors.map(UIColor.init(rgb:)) if colors.count == 1 { c.setFillColor(colors[0].cgColor) c.fill(arguments.drawingRect) - } else if settings.colors.count >= 3 { + } else if file.settings.colors.count >= 3 { let image = GradientBackgroundNode.generatePreview(size: CGSize(width: 60.0, height: 60.0), colors: colors) c.translateBy(x: drawingRect.midX, y: drawingRect.midY) c.scaleBy(x: 1.0, y: -1.0) @@ -1528,12 +1528,12 @@ public func wallpaperThumbnail(account: Account, accountManager: AccountManager, c.translateBy(x: drawingRect.midX, y: drawingRect.midY) c.scaleBy(x: 1.0, y: -1.0) c.translateBy(x: -drawingRect.midX, y: -drawingRect.midY) - } else if settings.colors.count >= 2 { - let gradientColors = settings.colors.map { UIColor(rgb: $0).cgColor } as CFArray - let delta: CGFloat = 1.0 / (CGFloat(settings.colors.count) - 1.0) + } else if file.settings.colors.count >= 2 { + let gradientColors = file.settings.colors.map { UIColor(rgb: $0).cgColor } as CFArray + let delta: CGFloat = 1.0 / (CGFloat(file.settings.colors.count) - 1.0) var locations: [CGFloat] = [] - for i in 0 ..< settings.colors.count { + for i in 0 ..< file.settings.colors.count { locations.append(delta * CGFloat(i)) } let colorSpace = CGColorSpaceCreateDeviceRGB() @@ -1541,7 +1541,7 @@ public func wallpaperThumbnail(account: Account, accountManager: AccountManager, c.saveGState() c.translateBy(x: arguments.drawingSize.width / 2.0, y: arguments.drawingSize.height / 2.0) - c.rotate(by: CGFloat(settings.rotation ?? 0) * CGFloat.pi / -180.0) + c.rotate(by: CGFloat(file.settings.rotation ?? 0) * CGFloat.pi / -180.0) c.translateBy(x: -arguments.drawingSize.width / 2.0, y: -arguments.drawingSize.height / 2.0) c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: arguments.drawingSize.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])