diff --git a/Telegram-iOS.xcworkspace/contents.xcworkspacedata b/Telegram-iOS.xcworkspace/contents.xcworkspacedata index 8e6a323970..1637111a1d 100644 --- a/Telegram-iOS.xcworkspace/contents.xcworkspacedata +++ b/Telegram-iOS.xcworkspace/contents.xcworkspacedata @@ -75,6 +75,9 @@ + + diff --git a/buildbox/build-telegram.sh b/buildbox/build-telegram.sh index ef9ab5d8be..f9a2bc03be 100644 --- a/buildbox/build-telegram.sh +++ b/buildbox/build-telegram.sh @@ -5,7 +5,7 @@ set -e BUILD_TELEGRAM_VERSION="1" MACOS_VERSION="10.14" -XCODE_VERSION="10.1" +XCODE_VERSION="10.3" VM_BASE_NAME="macos$(echo $MACOS_VERSION | sed -e 's/\.'/_/g)_Xcode$(echo $XCODE_VERSION | sed -e 's/\.'/_/g)" diff --git a/submodules/AccountContext/AccountContext_Xcode.xcodeproj/project.pbxproj b/submodules/AccountContext/AccountContext_Xcode.xcodeproj/project.pbxproj index 2e1f470179..e9f1cc4ae8 100644 --- a/submodules/AccountContext/AccountContext_Xcode.xcodeproj/project.pbxproj +++ b/submodules/AccountContext/AccountContext_Xcode.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - D06018E522F36A3900796784 /* DeviceAccess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018E422F36A3900796784 /* DeviceAccess.framework */; }; D06018E722F36A3F00796784 /* TelegramPresentationData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018E622F36A3F00796784 /* TelegramPresentationData.framework */; }; D0D3285422F329A900D07EE2 /* AccountContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D3285222F329A900D07EE2 /* AccountContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; D0D3285F22F335B000D07EE2 /* AccountContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3285E22F335B000D07EE2 /* AccountContext.swift */; }; @@ -36,7 +35,6 @@ buildActionMask = 2147483647; files = ( D06018E722F36A3F00796784 /* TelegramPresentationData.framework in Frameworks */, - D06018E522F36A3900796784 /* DeviceAccess.framework in Frameworks */, D0D328A322F3462800D07EE2 /* SwiftSignalKit.framework in Frameworks */, D0D328A122F3462400D07EE2 /* Postbox.framework in Frameworks */, D0D3289F22F3462000D07EE2 /* TelegramCore.framework in Frameworks */, diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index bbb43bd555..23d33f4f83 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -5,7 +5,6 @@ import TelegramPresentationData import TelegramUIPreferences import SwiftSignalKit import Display -import DeviceAccess public final class TelegramApplicationOpenUrlCompletion { public let completion: (Bool) -> Void @@ -15,6 +14,14 @@ public final class TelegramApplicationOpenUrlCompletion { } } +public enum AccessType { + case notDetermined + case allowed + case denied + case restricted + case unreachable +} + public final class TelegramApplicationBindings { public let isMainApp: Bool public let containerPath: String diff --git a/submodules/DeviceAccess/DeviceAccess_Xcode.xcodeproj/project.pbxproj b/submodules/DeviceAccess/DeviceAccess_Xcode.xcodeproj/project.pbxproj index a801764776..16d0d369ee 100644 --- a/submodules/DeviceAccess/DeviceAccess_Xcode.xcodeproj/project.pbxproj +++ b/submodules/DeviceAccess/DeviceAccess_Xcode.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + D068EE9222F4ABB60064E921 /* AccountContext.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D068EE9122F4ABB60064E921 /* AccountContext.framework */; }; D0AE31FE22B281300058D3BC /* DeviceAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = D0AE31FC22B281300058D3BC /* DeviceAccess.h */; settings = {ATTRIBUTES = (Public, ); }; }; D0AE320522B2818D0058D3BC /* DeviceAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AE320422B2818D0058D3BC /* DeviceAccess.swift */; }; D0AE320A22B281CA0058D3BC /* Display.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0AE320922B281CA0058D3BC /* Display.framework */; }; @@ -17,6 +18,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + D068EE9122F4ABB60064E921 /* AccountContext.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AccountContext.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0AE31F922B281300058D3BC /* DeviceAccess.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DeviceAccess.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0AE31FC22B281300058D3BC /* DeviceAccess.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceAccess.h; sourceTree = ""; }; D0AE31FD22B281300058D3BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -33,6 +35,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D068EE9222F4ABB60064E921 /* AccountContext.framework in Frameworks */, D0AE321222B2821B0058D3BC /* TelegramPresentationData.framework in Frameworks */, D0AE321022B281E50058D3BC /* LegacyComponents.framework in Frameworks */, D0AE320E22B281D30058D3BC /* SwiftSignalKit.framework in Frameworks */, @@ -74,6 +77,7 @@ D0AE320822B281CA0058D3BC /* Frameworks */ = { isa = PBXGroup; children = ( + D068EE9122F4ABB60064E921 /* AccountContext.framework */, D0AE321122B2821B0058D3BC /* TelegramPresentationData.framework */, D0AE320F22B281E50058D3BC /* LegacyComponents.framework */, D0AE320D22B281D30058D3BC /* SwiftSignalKit.framework */, diff --git a/submodules/DeviceAccess/Sources/DeviceAccess.swift b/submodules/DeviceAccess/Sources/DeviceAccess.swift index 6a63829cef..3a2ec05ec6 100644 --- a/submodules/DeviceAccess/Sources/DeviceAccess.swift +++ b/submodules/DeviceAccess/Sources/DeviceAccess.swift @@ -12,6 +12,7 @@ import UserNotifications import CoreTelephony import TelegramPresentationData import LegacyComponents +import AccountContext public enum DeviceAccessMicrophoneSubject { case audio @@ -42,14 +43,6 @@ public enum DeviceAccessSubject { case cellularData } -public enum AccessType { - case notDetermined - case allowed - case denied - case restricted - case unreachable -} - private let cachedMediaLibraryAccessStatus = Atomic(value: nil) public func shouldDisplayNotificationsPermissionWarning(status: AccessType, suppressed: Bool) -> Bool { diff --git a/submodules/Display/Display/GenerateImage.swift b/submodules/Display/Display/GenerateImage.swift index 7fd2d96038..b77f26efdb 100644 --- a/submodules/Display/Display/GenerateImage.swift +++ b/submodules/Display/Display/GenerateImage.swift @@ -2,7 +2,7 @@ import Foundation import UIKit import Accelerate -private let deviceColorSpace: CGColorSpace = { +public let deviceColorSpace: CGColorSpace = { if #available(iOSApplicationExtension 9.3, *) { if let colorSpace = CGColorSpace(name: CGColorSpace.displayP3) { return colorSpace diff --git a/submodules/Display/Display/ListView.swift b/submodules/Display/Display/ListView.swift index e9585eba04..68364a7b6b 100644 --- a/submodules/Display/Display/ListView.swift +++ b/submodules/Display/Display/ListView.swift @@ -664,8 +664,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } for itemNode in self.itemNodes { - let position = itemNode.position - itemNode.position = CGPoint(x: position.x, y: position.y - deltaY) + itemNode.updateFrame(itemNode.frame.offsetBy(dx: 0.0, dy: -deltaY), within: self.visibleSize) if self.dynamicBounceEnabled && itemNode.wantsScrollDynamics { useScrollDynamics = true @@ -895,7 +894,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture for itemNode in self.itemNodes { var frame = itemNode.frame frame.origin.y += offset - itemNode.frame = frame + itemNode.updateFrame(frame, within: self.visibleSize) if let accessoryItemNode = itemNode.accessoryItemNode { itemNode.layoutAccessoryItemNode(accessoryItemNode, leftInset: self.insets.left, rightInset: self.insets.right) } @@ -1867,7 +1866,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture node.contentSize = layout.contentSize node.insets = layout.insets node.apparentHeight = animated ? 0.0 : layout.size.height - node.frame = nodeFrame + node.updateFrame(nodeFrame, within: self.visibleSize) if let accessoryItemNode = node.accessoryItemNode { node.layoutAccessoryItemNode(accessoryItemNode, leftInset: listInsets.left, rightInset: listInsets.right) } @@ -1887,9 +1886,8 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture offsetHeight = 0.0 - var offsetPosition = nextNode.position - offsetPosition.y += nextHeight - nextNode.position = offsetPosition + nextNode.updateFrame(nextNode.frame.offsetBy(dx: 0.0, dy: nextHeight), within: self.visibleSize) + nextNode.apparentHeight = 0.0 nextNode.removeApparentHeightAnimation() @@ -1992,7 +1990,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture while i >= 0 { var frame = self.itemNodes[i].frame frame.origin.y -= offsetHeight - self.itemNodes[i].frame = frame + self.itemNodes[i].updateFrame(frame, within: self.visibleSize) if let accessoryItemNode = self.itemNodes[i].accessoryItemNode { self.itemNodes[i].layoutAccessoryItemNode(accessoryItemNode, leftInset: listInsets.left, rightInset: listInsets.right) } @@ -2003,7 +2001,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture while i < self.itemNodes.count { var frame = self.itemNodes[i].frame frame.origin.y += offsetHeight - self.itemNodes[i].frame = frame + self.itemNodes[i].updateFrame(frame, within: self.visibleSize) if let accessoryItemNode = self.itemNodes[i].accessoryItemNode { self.itemNodes[i].layoutAccessoryItemNode(accessoryItemNode, leftInset: listInsets.left, rightInset: listInsets.right) } @@ -2230,7 +2228,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture for i in index + 1 ..< self.itemNodes.count { var frame = self.itemNodes[i].frame frame.origin.y -= height - self.itemNodes[i].frame = frame + self.itemNodes[i].updateFrame(frame, within: self.visibleSize) if let accessoryItemNode = self.itemNodes[i].accessoryItemNode { self.itemNodes[i].layoutAccessoryItemNode(accessoryItemNode, leftInset: listInsets.left, rightInset: listInsets.right) } @@ -2241,7 +2239,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture for i in (0 ..< index).reversed() { var frame = self.itemNodes[i].frame frame.origin.y += height - self.itemNodes[i].frame = frame + self.itemNodes[i].updateFrame(frame, within: self.visibleSize) if let accessoryItemNode = self.itemNodes[i].accessoryItemNode { self.itemNodes[i].layoutAccessoryItemNode(accessoryItemNode, leftInset: listInsets.left, rightInset: listInsets.right) } @@ -2327,7 +2325,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if offset != 0.0 { var frame = itemNode.frame frame.origin.y += offset - itemNode.frame = frame + itemNode.updateFrame(frame, within: self.visibleSize) } index += 1 @@ -2396,7 +2394,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture for itemNode in self.itemNodes { var frame = itemNode.frame frame.origin.y += offset - itemNode.frame = frame + itemNode.updateFrame(frame, within: self.visibleSize) if let accessoryItemNode = itemNode.accessoryItemNode { itemNode.layoutAccessoryItemNode(accessoryItemNode, leftInset: listInsets.left, rightInset: listInsets.right) } @@ -2416,7 +2414,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture for itemNode in self.itemNodes { var frame = itemNode.frame frame.origin.y += offset - itemNode.frame = frame + itemNode.updateFrame(frame, within: self.visibleSize) if let accessoryItemNode = itemNode.accessoryItemNode { itemNode.layoutAccessoryItemNode(accessoryItemNode, leftInset: listInsets.left, rightInset: listInsets.right) } @@ -2464,8 +2462,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture self.visibleSize = updateSizeAndInsets.size for itemNode in self.itemNodes { - let position = itemNode.position - itemNode.position = CGPoint(x: position.x, y: position.y + offsetFix) + itemNode.updateFrame(itemNode.frame.offsetBy(dx: 0.0, dy: offsetFix), within: self.visibleSize) } let (snappedTopInset, snapToBoundsOffset) = self.snapToBounds(snapTopItem: scrollToItem != nil, stackFromBottom: self.stackFromBottom, updateSizeAndInsets: updateSizeAndInsets, isExperimentalSnapToScrollToItem: isExperimentalSnapToScrollToItem) @@ -2474,8 +2471,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture offsetFix += snappedTopInset for itemNode in self.itemNodes { - let position = itemNode.position - itemNode.position = CGPoint(x: position.x, y: position.y + snappedTopInset) + itemNode.updateFrame(itemNode.frame.offsetBy(dx: 0.0, dy: snappedTopInset), within: self.visibleSize) } } @@ -2490,9 +2486,12 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if !updateSizeAndInsets.duration.isZero && !isExperimentalSnapToScrollToItem { let animation: CABasicAnimation + let animationCurve: ContainedViewLayoutTransitionCurve + let animationDuration: Double switch updateSizeAndInsets.curve { case let .Spring(duration): headerNodesTransition = (.animated(duration: duration, curve: .spring), false, -completeOffset) + animationCurve = .spring let springAnimation = makeSpringAnimation("sublayerTransform") springAnimation.fromValue = NSValue(caTransform3D: CATransform3DMakeTranslation(0.0, -completeOffset, 0.0)) springAnimation.toValue = NSValue(caTransform3D: CATransform3DIdentity) @@ -2506,11 +2505,14 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if !duration.isZero { springAnimation.speed = speed * Float(springAnimation.duration / duration) } + animationDuration = duration springAnimation.isAdditive = true animation = springAnimation case let .Default(duration): headerNodesTransition = (.animated(duration: max(duration ?? 0.3, updateSizeAndInsets.duration), curve: .easeInOut), false, -completeOffset) + animationCurve = .easeInOut + animationDuration = duration ?? 0.3 let basicAnimation = CABasicAnimation(keyPath: "sublayerTransform") basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = updateSizeAndInsets.duration * UIView.animationDurationFactor() @@ -2526,6 +2528,9 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture self?.updateItemNodesVisibilities(onlyPositive: false) } self.layer.add(animation, forKey: nil) + for itemNode in self.itemNodes { + itemNode.applyAbsoluteOffset(value: -completeOffset, animationCurve: animationCurve, duration: animationDuration) + } } } else { self.visibleSize = updateSizeAndInsets.size @@ -2563,6 +2568,9 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture springAnimation.isAdditive = true self.layer.add(springAnimation, forKey: nil) + for itemNode in self.itemNodes { + itemNode.applyAbsoluteOffset(value: -completeOffset, animationCurve: .spring, duration: duration) + } } else { if let snapshotView = snapshotView { snapshotView.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: snapshotView.frame.size) @@ -2585,8 +2593,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if !snappedTopInset.isZero && previousApparentFrames.isEmpty { for itemNode in self.itemNodes { - let position = itemNode.position - itemNode.position = CGPoint(x: position.x, y: position.y + snappedTopInset) + itemNode.updateFrame(itemNode.frame.offsetBy(dx: 0.0, dy: snappedTopInset), within: self.visibleSize) } } @@ -2630,7 +2637,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture for (previousNode, previousFrame) in previousApparentFrames { if previousNode.supernode == nil { temporaryPreviousNodes.append(previousNode) - previousNode.frame = previousFrame + previousNode.updateFrame(previousFrame, within: self.visibleSize) if previousUpperBound == nil || previousUpperBound! > previousFrame.minY { previousUpperBound = previousFrame.minY } @@ -2648,7 +2655,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture for (previousNode, previousFrame) in previousApparentFrames { if previousNode.supernode == nil { temporaryPreviousNodes.append(previousNode) - previousNode.frame = previousFrame + previousNode.updateFrame(previousFrame, within: self.visibleSize) if previousUpperBound == nil || previousUpperBound! > previousFrame.minY { previousUpperBound = previousFrame.minY } @@ -2696,7 +2703,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if let offset = offset, !offset.isZero { let lowestNodeToInsertBelow = self.lowestNodeToInsertBelow() for itemNode in temporaryPreviousNodes { - itemNode.frame = itemNode.frame.offsetBy(dx: 0.0, dy: offset) + itemNode.updateFrame(itemNode.frame.offsetBy(dx: 0.0, dy: offset), within: self.visibleSize) if let lowestNodeToInsertBelow = lowestNodeToInsertBelow { self.insertSubnode(itemNode, belowSubnode: lowestNodeToInsertBelow) } else if let verticalScrollIndicator = self.verticalScrollIndicator { @@ -2721,8 +2728,12 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture let animation: CABasicAnimation let reverseAnimation: CABasicAnimation + let animationCurve: ContainedViewLayoutTransitionCurve + let animationDuration: Double switch scrollToItem.curve { case let .Spring(duration): + animationCurve = .spring + animationDuration = duration let springAnimation = makeSpringAnimation("sublayerTransform") springAnimation.fromValue = NSValue(caTransform3D: CATransform3DMakeTranslation(0.0, -offset, 0.0)) springAnimation.toValue = NSValue(caTransform3D: CATransform3DIdentity) @@ -2752,6 +2763,8 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture reverseAnimation = reverseSpringAnimation case let .Default(duration): if let duration = duration { + animationCurve = .easeInOut + animationDuration = duration let basicAnimation = CABasicAnimation(keyPath: "sublayerTransform") basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = duration * UIView.animationDurationFactor() @@ -2771,6 +2784,9 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture animation = basicAnimation reverseAnimation = reverseBasicAnimation } else { + animationCurve = .slide + animationDuration = duration ?? 0.3 + let basicAnimation = CABasicAnimation(keyPath: "sublayerTransform") basicAnimation.timingFunction = ContainedViewLayoutTransitionCurve.slide.mediaTimingFunction basicAnimation.duration = (duration ?? 0.3) * UIView.animationDurationFactor() @@ -2800,6 +2816,12 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } } self.layer.add(animation, forKey: nil) + for itemNode in self.itemNodes { + itemNode.applyAbsoluteOffset(value: -offset, animationCurve: animationCurve, duration: animationDuration) + } + for itemNode in temporaryPreviousNodes { + itemNode.applyAbsoluteOffset(value: -offset, animationCurve: animationCurve, duration: animationDuration) + } if let verticalScrollIndicator = self.verticalScrollIndicator { verticalScrollIndicator.layer.add(reverseAnimation, forKey: nil) } @@ -3482,9 +3504,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture for itemNode in self.itemNodes { let offset = offsetRanges.offsetForIndex(index) if offset != 0.0 { - var position = itemNode.position - position.y += offset - itemNode.position = position + itemNode.updateFrame(itemNode.frame.offsetBy(dx: 0.0, dy: offset), within: self.visibleSize) } index += 1 diff --git a/submodules/Display/Display/ListViewItemNode.swift b/submodules/Display/Display/ListViewItemNode.swift index 898047167a..af74876d61 100644 --- a/submodules/Display/Display/ListViewItemNode.swift +++ b/submodules/Display/Display/ListViewItemNode.swift @@ -549,4 +549,15 @@ open class ListViewItemNode: ASDisplayNode { override open func accessibilityElementDidBecomeFocused() { (self.supernode as? ListView)?.ensureItemNodeVisible(self, animated: false, overflow: 22.0) } + + public func updateFrame(_ frame: CGRect, within containerSize: CGSize) { + self.frame = frame + self.updateAbsoluteRect(frame, within: containerSize) + } + + open func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { + } + + open func applyAbsoluteOffset(value: CGFloat, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + } } diff --git a/submodules/ItemListUI/Sources/ItemListController.swift b/submodules/ItemListUI/Sources/ItemListController.swift index 10048b4693..ec1af48c4c 100644 --- a/submodules/ItemListUI/Sources/ItemListController.swift +++ b/submodules/ItemListUI/Sources/ItemListController.swift @@ -147,6 +147,14 @@ open class ItemListController: ViewController, KeyShor } } + public var alwaysSynchronous = false { + didSet { + if self.isNodeLoaded { + (self.displayNode as! ItemListControllerNode).alwaysSynchronous = self.alwaysSynchronous + } + } + } + public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)? { didSet { if self.isNodeLoaded { @@ -413,6 +421,7 @@ open class ItemListController: ViewController, KeyShor self?.presentingViewController?.dismiss(animated: true, completion: nil) } displayNode.enableInteractiveDismiss = self.enableInteractiveDismiss + displayNode.alwaysSynchronous = self.alwaysSynchronous displayNode.visibleEntriesUpdated = self.visibleEntriesUpdated displayNode.visibleBottomContentOffsetChanged = self.visibleBottomContentOffsetChanged displayNode.contentOffsetChanged = self.contentOffsetChanged diff --git a/submodules/ItemListUI/Sources/ItemListControllerNode.swift b/submodules/ItemListUI/Sources/ItemListControllerNode.swift index 71a54c2aee..8955f4eba2 100644 --- a/submodules/ItemListUI/Sources/ItemListControllerNode.swift +++ b/submodules/ItemListUI/Sources/ItemListControllerNode.swift @@ -196,6 +196,8 @@ open class ItemListControllerNode: ASDisplayNode, UISc didSet { } } + + var alwaysSynchronous = false public init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, state: Signal<(PresentationTheme, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>) { self.navigationBar = navigationBar @@ -439,6 +441,10 @@ open class ItemListControllerNode: ASDisplayNode, UISc options.insert(.Synchronous) options.insert(.PreferSynchronousDrawing) } + if self.alwaysSynchronous { + options.insert(.Synchronous) + options.insert(.LowLatency) + } let focusItemTag = transition.focusItemTag let ensureVisibleItemTag = transition.ensureVisibleItemTag var scrollToItem: ListViewScrollToItem? diff --git a/submodules/MediaResources/Info.plist b/submodules/MediaResources/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/MediaResources/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/MediaResources/MediaResources_Xcode.xcodeproj/project.pbxproj b/submodules/MediaResources/MediaResources_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..a56a3d3252 --- /dev/null +++ b/submodules/MediaResources/MediaResources_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,555 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D084FA0222F435FD004874CE /* MediaResources.h in Headers */ = {isa = PBXBuildFile; fileRef = D084FA0022F435FD004874CE /* MediaResources.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D084FA0D22F436C9004874CE /* CachedResourceRepresentations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D084FA0C22F436C9004874CE /* CachedResourceRepresentations.swift */; }; + D084FA1022F436D3004874CE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D084FA0F22F436D3004874CE /* UIKit.framework */; }; + D084FA1222F436D6004874CE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D084FA1122F436D6004874CE /* Foundation.framework */; }; + D084FA1422F436DA004874CE /* Postbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D084FA1322F436DA004874CE /* Postbox.framework */; }; + D084FA1622F436DE004874CE /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D084FA1522F436DE004874CE /* SwiftSignalKit.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D084F9FD22F435FD004874CE /* MediaResources.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MediaResources.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D084FA0022F435FD004874CE /* MediaResources.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaResources.h; sourceTree = ""; }; + D084FA0122F435FD004874CE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D084FA0C22F436C9004874CE /* CachedResourceRepresentations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedResourceRepresentations.swift; sourceTree = ""; }; + D084FA0F22F436D3004874CE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D084FA1122F436D6004874CE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D084FA1322F436DA004874CE /* Postbox.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Postbox.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D084FA1522F436DE004874CE /* SwiftSignalKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D084F9FA22F435FD004874CE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D084FA1622F436DE004874CE /* SwiftSignalKit.framework in Frameworks */, + D084FA1422F436DA004874CE /* Postbox.framework in Frameworks */, + D084FA1222F436D6004874CE /* Foundation.framework in Frameworks */, + D084FA1022F436D3004874CE /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D084F9F322F435FD004874CE = { + isa = PBXGroup; + children = ( + D084FA0122F435FD004874CE /* Info.plist */, + D084F9FF22F435FD004874CE /* Sources */, + D084F9FE22F435FD004874CE /* Products */, + D084FA0E22F436D2004874CE /* Frameworks */, + ); + sourceTree = ""; + }; + D084F9FE22F435FD004874CE /* Products */ = { + isa = PBXGroup; + children = ( + D084F9FD22F435FD004874CE /* MediaResources.framework */, + ); + name = Products; + sourceTree = ""; + }; + D084F9FF22F435FD004874CE /* Sources */ = { + isa = PBXGroup; + children = ( + D084FA0C22F436C9004874CE /* CachedResourceRepresentations.swift */, + D084FA0022F435FD004874CE /* MediaResources.h */, + ); + path = Sources; + sourceTree = ""; + }; + D084FA0E22F436D2004874CE /* Frameworks */ = { + isa = PBXGroup; + children = ( + D084FA1522F436DE004874CE /* SwiftSignalKit.framework */, + D084FA1322F436DA004874CE /* Postbox.framework */, + D084FA1122F436D6004874CE /* Foundation.framework */, + D084FA0F22F436D3004874CE /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D084F9F822F435FD004874CE /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D084FA0222F435FD004874CE /* MediaResources.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D084F9FC22F435FD004874CE /* MediaResources */ = { + isa = PBXNativeTarget; + buildConfigurationList = D084FA0522F435FD004874CE /* Build configuration list for PBXNativeTarget "MediaResources" */; + buildPhases = ( + D084F9F822F435FD004874CE /* Headers */, + D084F9F922F435FD004874CE /* Sources */, + D084F9FA22F435FD004874CE /* Frameworks */, + D084F9FB22F435FD004874CE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MediaResources; + productName = MediaResources; + productReference = D084F9FD22F435FD004874CE /* MediaResources.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D084F9F422F435FD004874CE /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1030; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D084F9FC22F435FD004874CE = { + CreatedOnToolsVersion = 10.3; + LastSwiftMigration = 1030; + }; + }; + }; + buildConfigurationList = D084F9F722F435FD004874CE /* Build configuration list for PBXProject "MediaResources_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D084F9F322F435FD004874CE; + productRefGroup = D084F9FE22F435FD004874CE /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D084F9FC22F435FD004874CE /* MediaResources */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D084F9FB22F435FD004874CE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D084F9F922F435FD004874CE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D084FA0D22F436C9004874CE /* CachedResourceRepresentations.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D084FA0322F435FD004874CE /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D084FA0422F435FD004874CE /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D084FA0622F435FD004874CE /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.MediaResources; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D084FA0722F435FD004874CE /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.MediaResources; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D084FA0822F4361A004874CE /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D084FA0922F4361A004874CE /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.MediaResources; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D084FA0A22F43625004874CE /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D084FA0B22F43625004874CE /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.MediaResources; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D084F9F722F435FD004874CE /* Build configuration list for PBXProject "MediaResources_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D084FA0322F435FD004874CE /* DebugAppStoreLLC */, + D084FA0822F4361A004874CE /* DebugHockeyapp */, + D084FA0422F435FD004874CE /* ReleaseAppStoreLLC */, + D084FA0A22F43625004874CE /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D084FA0522F435FD004874CE /* Build configuration list for PBXNativeTarget "MediaResources" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D084FA0622F435FD004874CE /* DebugAppStoreLLC */, + D084FA0922F4361A004874CE /* DebugHockeyapp */, + D084FA0722F435FD004874CE /* ReleaseAppStoreLLC */, + D084FA0B22F43625004874CE /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D084F9F422F435FD004874CE /* Project object */; +} diff --git a/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift b/submodules/MediaResources/Sources/CachedResourceRepresentations.swift similarity index 50% rename from submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift rename to submodules/MediaResources/Sources/CachedResourceRepresentations.swift index fb7229d802..426255d1f0 100644 --- a/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift +++ b/submodules/MediaResources/Sources/CachedResourceRepresentations.swift @@ -3,11 +3,11 @@ import UIKit import Postbox import SwiftSignalKit -final class CachedStickerAJpegRepresentation: CachedMediaResourceRepresentation { - let size: CGSize? - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedStickerAJpegRepresentation: CachedMediaResourceRepresentation { + public let size: CGSize? + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - var uniqueId: String { + public var uniqueId: String { if let size = self.size { return "sticker-ajpeg-\(Int(size.width))x\(Int(size.height))" } else { @@ -15,11 +15,11 @@ final class CachedStickerAJpegRepresentation: CachedMediaResourceRepresentation } } - init(size: CGSize?) { + public init(size: CGSize?) { self.size = size } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedStickerAJpegRepresentation { return self.size == to.size } else { @@ -28,27 +28,27 @@ final class CachedStickerAJpegRepresentation: CachedMediaResourceRepresentation } } -enum CachedScaledImageRepresentationMode: Int32 { +public enum CachedScaledImageRepresentationMode: Int32 { case fill = 0 case aspectFit = 1 } -final class CachedScaledImageRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedScaledImageRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - let size: CGSize - let mode: CachedScaledImageRepresentationMode + public let size: CGSize + public let mode: CachedScaledImageRepresentationMode - var uniqueId: String { + public var uniqueId: String { return "scaled-image-\(Int(self.size.width))x\(Int(self.size.height))-\(self.mode.rawValue)" } - init(size: CGSize, mode: CachedScaledImageRepresentationMode) { + public init(size: CGSize, mode: CachedScaledImageRepresentationMode) { self.size = size self.mode = mode } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedScaledImageRepresentation { return self.size == to.size && self.mode == to.mode } else { @@ -57,14 +57,17 @@ final class CachedScaledImageRepresentation: CachedMediaResourceRepresentation { } } -final class CachedVideoFirstFrameRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedVideoFirstFrameRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - var uniqueId: String { + public var uniqueId: String { return "first-frame" } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public init() { + } + + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if to is CachedVideoFirstFrameRepresentation { return true } else { @@ -73,20 +76,20 @@ final class CachedVideoFirstFrameRepresentation: CachedMediaResourceRepresentati } } -final class CachedScaledVideoFirstFrameRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedScaledVideoFirstFrameRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - let size: CGSize + public let size: CGSize - var uniqueId: String { + public var uniqueId: String { return "scaled-frame-\(Int(self.size.width))x\(Int(self.size.height))" } - init(size: CGSize) { + public init(size: CGSize) { self.size = size } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedScaledVideoFirstFrameRepresentation { return self.size == to.size } else { @@ -95,14 +98,17 @@ final class CachedScaledVideoFirstFrameRepresentation: CachedMediaResourceRepres } } -final class CachedBlurredWallpaperRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedBlurredWallpaperRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - var uniqueId: String { + public var uniqueId: String { return "blurred-wallpaper" } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public init() { + } + + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if to is CachedBlurredWallpaperRepresentation { return true } else { @@ -111,12 +117,12 @@ final class CachedBlurredWallpaperRepresentation: CachedMediaResourceRepresentat } } -final class CachedPatternWallpaperMaskRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedPatternWallpaperMaskRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - let size: CGSize? + public let size: CGSize? - var uniqueId: String { + public var uniqueId: String { if let size = self.size { return "pattern-wallpaper-mask-\(Int(size.width))x\(Int(size.height))" } else { @@ -124,11 +130,11 @@ final class CachedPatternWallpaperMaskRepresentation: CachedMediaResourceReprese } } - init(size: CGSize?) { + public init(size: CGSize?) { self.size = size } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedPatternWallpaperMaskRepresentation { return self.size == to.size } else { @@ -138,22 +144,22 @@ final class CachedPatternWallpaperMaskRepresentation: CachedMediaResourceReprese } -final class CachedPatternWallpaperRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedPatternWallpaperRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - let color: Int32 - let intensity: Int32 + public let color: Int32 + public let intensity: Int32 - var uniqueId: String { + public var uniqueId: String { return "pattern-wallpaper-\(self.color)-\(self.intensity)" } - init(color: Int32, intensity: Int32) { + public init(color: Int32, intensity: Int32) { self.color = color self.intensity = intensity } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedPatternWallpaperRepresentation { return self.color == to.color && self.intensity == intensity } else { @@ -162,12 +168,12 @@ final class CachedPatternWallpaperRepresentation: CachedMediaResourceRepresentat } } -final class CachedAlbumArtworkRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedAlbumArtworkRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - let size: CGSize? + public let size: CGSize? - var uniqueId: String { + public var uniqueId: String { if let size = self.size { return "album-artwork-\(Int(size.width))x\(Int(size.height))" } else { @@ -175,11 +181,11 @@ final class CachedAlbumArtworkRepresentation: CachedMediaResourceRepresentation } } - init(size: CGSize) { + public init(size: CGSize) { self.size = size } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedAlbumArtworkRepresentation { return self.size == to.size } else { @@ -188,20 +194,20 @@ final class CachedAlbumArtworkRepresentation: CachedMediaResourceRepresentation } } -final class CachedEmojiThumbnailRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedEmojiThumbnailRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - let outline: Bool + public let outline: Bool - var uniqueId: String { + public var uniqueId: String { return "emoji-thumb-\(self.outline ? 1 : 0)" } - init(outline: Bool) { + public init(outline: Bool) { self.outline = outline } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedEmojiThumbnailRepresentation { return self.outline == to.outline } else { @@ -210,22 +216,22 @@ final class CachedEmojiThumbnailRepresentation: CachedMediaResourceRepresentatio } } -final class CachedEmojiRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedEmojiRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - let tile: UInt8 - let outline: Bool + public let tile: UInt8 + public let outline: Bool - var uniqueId: String { + public var uniqueId: String { return "emoji-\(Int(self.tile))-\(self.outline ? 1 : 0)" } - init(tile: UInt8, outline: Bool) { + public init(tile: UInt8, outline: Bool) { self.tile = tile self.outline = outline } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedEmojiRepresentation { return self.tile == to.tile && self.outline == to.outline } else { @@ -234,22 +240,22 @@ final class CachedEmojiRepresentation: CachedMediaResourceRepresentation { } } -final class CachedAnimatedStickerFirstFrameRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedAnimatedStickerFirstFrameRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .general - let width: Int32 - let height: Int32 + public let width: Int32 + public let height: Int32 - init(width: Int32, height: Int32) { + public init(width: Int32, height: Int32) { self.width = width self.height = height } - var uniqueId: String { + public var uniqueId: String { return "animated-sticker-first-frame-\(self.width)x\(self.height)-v1" } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let other = to as? CachedAnimatedStickerFirstFrameRepresentation { if other.width != self.width { return false @@ -264,22 +270,22 @@ final class CachedAnimatedStickerFirstFrameRepresentation: CachedMediaResourceRe } } -final class CachedAnimatedStickerRepresentation: CachedMediaResourceRepresentation { - let keepDuration: CachedMediaRepresentationKeepDuration = .shortLived +public final class CachedAnimatedStickerRepresentation: CachedMediaResourceRepresentation { + public let keepDuration: CachedMediaRepresentationKeepDuration = .shortLived - let width: Int32 - let height: Int32 + public let width: Int32 + public let height: Int32 - var uniqueId: String { + public var uniqueId: String { return "animated-sticker-\(self.width)x\(self.height)-v8" } - init(width: Int32, height: Int32) { + public init(width: Int32, height: Int32) { self.width = width self.height = height } - func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { if let other = to as? CachedAnimatedStickerRepresentation { if other.width != self.width { return false diff --git a/submodules/MediaResources/Sources/MediaResources.h b/submodules/MediaResources/Sources/MediaResources.h new file mode 100644 index 0000000000..4b7c6c71d2 --- /dev/null +++ b/submodules/MediaResources/Sources/MediaResources.h @@ -0,0 +1,19 @@ +// +// MediaResources.h +// MediaResources +// +// Created by Peter on 8/2/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for MediaResources. +FOUNDATION_EXPORT double MediaResourcesVersionNumber; + +//! Project version string for MediaResources. +FOUNDATION_EXPORT const unsigned char MediaResourcesVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/TelegramUI/TelegramUI/ChatControllerBackgroundNode.swift b/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift similarity index 83% rename from submodules/TelegramUI/TelegramUI/ChatControllerBackgroundNode.swift rename to submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift index a177fafcac..7177414d56 100644 --- a/submodules/TelegramUI/TelegramUI/ChatControllerBackgroundNode.swift +++ b/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift @@ -5,11 +5,26 @@ import TelegramCore import Display import SwiftSignalKit import Postbox - +import MediaResources private var backgroundImageForWallpaper: (TelegramWallpaper, Bool, UIImage)? -func chatControllerBackgroundImage(wallpaper: TelegramWallpaper, mediaBox: MediaBox, composed: Bool = true) -> UIImage? { +public func chatControllerBackgroundImage(theme: PresentationTheme, wallpaper initialWallpaper: TelegramWallpaper, mediaBox: MediaBox, composed: Bool = true, knockoutMode: Bool) -> UIImage? { + var wallpaper = initialWallpaper + if knockoutMode { + switch theme.name { + case let .builtin(name): + switch name { + case .day, .night, .nightAccent: + wallpaper = theme.chat.defaultWallpaper + case .dayClassic: + break + } + case .custom: + break + } + } + var backgroundImage: UIImage? if composed && wallpaper == backgroundImageForWallpaper?.0, (wallpaper.settings?.blur ?? false) == backgroundImageForWallpaper?.1 { backgroundImage = backgroundImageForWallpaper?.2 @@ -53,12 +68,14 @@ func chatControllerBackgroundImage(wallpaper: TelegramWallpaper, mediaBox: Media var image: UIImage? let _ = mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true, attemptSynchronously: true).start(next: { data in if data.complete { + print("background image: \(data.path)") image = UIImage(contentsOfFile: data.path)?.precomposed() } }) backgroundImage = image } if backgroundImage == nil, let path = mediaBox.completedResourcePath(file.file.resource) { + print("background image: \(path)") backgroundImage = UIImage(contentsOfFile: path)?.precomposed() } } diff --git a/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift b/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift index deb72cd8ab..e3cab97063 100644 --- a/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift +++ b/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift @@ -1,6 +1,8 @@ import Foundation import UIKit import Display +import TelegramPresentationData +import TelegramCore public enum MessageBubbleImageNeighbors { case none @@ -24,11 +26,19 @@ public func messageSingleBubbleLikeImage(fillColor: UIColor, strokeColor: UIColo })!.stretchableImage(withLeftCapWidth: Int(diameter / 2.0), topCapHeight: Int(diameter / 2.0)) } -public func messageBubbleImage(incoming: Bool, fillColor: UIColor, strokeColor: UIColor, neighbors: MessageBubbleImageNeighbors) -> UIImage { +public func messageBubbleImage(incoming: Bool, fillColor: UIColor, strokeColor: UIColor, neighbors: MessageBubbleImageNeighbors, theme: PresentationThemeChat, wallpaper: TelegramWallpaper, knockout: Bool) -> UIImage { let diameter: CGFloat = 36.0 let corner: CGFloat = 7.0 return generateImage(CGSize(width: 42.0, height: diameter), contextGenerator: { size, context in - context.clear(CGRect(origin: CGPoint(), size: size)) + var drawWithClearColor = false + + if knockout, case let .color(color) = wallpaper { + drawWithClearColor = true + context.setFillColor(UIColor(rgb: UInt32(color)).cgColor) + context.fill(CGRect(origin: CGPoint(), size: size)) + } else { + context.clear(CGRect(origin: CGPoint(), size: size)) + } let additionalOffset: CGFloat switch neighbors { @@ -44,40 +54,57 @@ public func messageBubbleImage(incoming: Bool, fillColor: UIColor, strokeColor: let lineWidth: CGFloat = 1.0 - context.setFillColor(fillColor.cgColor) - context.setLineWidth(lineWidth) - context.setStrokeColor(strokeColor.cgColor) + if drawWithClearColor { + context.setBlendMode(.copy) + context.setFillColor(UIColor.clear.cgColor) + } else { + context.setFillColor(fillColor.cgColor) + context.setLineWidth(lineWidth) + context.setStrokeColor(strokeColor.cgColor) + } switch neighbors { case .none: - let _ = try? drawSvgPath(context, path: "M6,17.5 C6,7.83289181 13.8350169,0 23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41102995e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") - context.strokePath() + if !drawWithClearColor { + let _ = try? drawSvgPath(context, path: "M6,17.5 C6,7.83289181 13.8350169,0 23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41102995e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") + context.strokePath() + } let _ = try? drawSvgPath(context, path: "M6,17.5 C6,7.83289181 13.8350169,0 23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41102995e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") context.fillPath() case .side: - context.strokeEllipse(in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 35.0, height: 35.0))) - context.strokePath() + if !drawWithClearColor { + context.strokeEllipse(in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 35.0, height: 35.0))) + context.strokePath() + } context.fillEllipse(in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 35.0, height: 35.0))) case let .top(side): if side { - let _ = try? drawSvgPath(context, path: "M17.5,0 L17.5,0 C27.1649831,-1.7754286e-15 35,7.83501688 35,17.5 L35,29 C35,32.3137085 32.3137085,35 29,35 L6,35 C2.6862915,35 4.05812251e-16,32.3137085 0,29 L0,17.5 C-1.18361906e-15,7.83501688 7.83501688,1.7754286e-15 17.5,0 ") - context.strokePath() + if !drawWithClearColor { + let _ = try? drawSvgPath(context, path: "M17.5,0 L17.5,0 C27.1649831,-1.7754286e-15 35,7.83501688 35,17.5 L35,29 C35,32.3137085 32.3137085,35 29,35 L6,35 C2.6862915,35 4.05812251e-16,32.3137085 0,29 L0,17.5 C-1.18361906e-15,7.83501688 7.83501688,1.7754286e-15 17.5,0 ") + context.strokePath() + } let _ = try? drawSvgPath(context, path: "M17.5,0 L17.5,0 C27.1649831,-1.7754286e-15 35,7.83501688 35,17.5 L35,29 C35,32.3137085 32.3137085,35 29,35 L6,35 C2.6862915,35 4.05812251e-16,32.3137085 0,29 L0,17.5 C-1.18361906e-15,7.83501688 7.83501688,1.7754286e-15 17.5,0 ") context.fillPath() } else { - let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L17.5,0 C7.83501688,0 0,7.83289181 0,17.5 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") - context.strokePath() + if !drawWithClearColor { + let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L17.5,0 C7.83501688,0 0,7.83289181 0,17.5 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") + context.strokePath() + } let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L17.5,0 C7.83501688,0 0,7.83289181 0,17.5 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") context.fillPath() } case .bottom: - let _ = try? drawSvgPath(context, path: "M6,17.5 L6,5.99681848 C6,2.6882755 8.68486709,0 11.9968185,0 L23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41103066e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") - context.strokePath() + if !drawWithClearColor { + let _ = try? drawSvgPath(context, path: "M6,17.5 L6,5.99681848 C6,2.6882755 8.68486709,0 11.9968185,0 L23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41103066e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") + context.strokePath() + } let _ = try? drawSvgPath(context, path: "M6,17.5 L6,5.99681848 C6,2.6882755 8.68486709,0 11.9968185,0 L23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41103066e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") context.fillPath() case .both: - let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L5.99681848,0 C2.68486709,0 0,2.6882755 0,5.99681848 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") - context.strokePath() + if !drawWithClearColor { + let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L5.99681848,0 C2.68486709,0 0,2.6882755 0,5.99681848 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") + context.strokePath() + } let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L5.99681848,0 C2.68486709,0 0,2.6882755 0,5.99681848 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") context.fillPath() } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift index aa7ca199b8..aa5ef6772b 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift @@ -1,7 +1,8 @@ import Foundation import UIKit +import TelegramUIPreferences -private func makeDarkPresentationTheme(accentColor: UIColor, preview: Bool) -> PresentationTheme { +private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: PresentationThemeBaseColor?, preview: Bool) -> PresentationTheme { let destructiveColor: UIColor = UIColor(rgb: 0xeb5545) let constructiveColor: UIColor = UIColor(rgb: 0x08a723) let secretColor: UIColor = UIColor(rgb: 0x00b12c) @@ -309,6 +310,7 @@ private func makeDarkPresentationTheme(accentColor: UIColor, preview: Bool) -> P name: .builtin(.night), author: "Telegram", overallDarkAppearance: true, + baseColor: baseColor, intro: intro, passcode: passcode, rootController: rootController, @@ -321,9 +323,9 @@ private func makeDarkPresentationTheme(accentColor: UIColor, preview: Bool) -> P ) } -public let defaultDarkPresentationTheme = makeDarkPresentationTheme(accentColor: .white, preview: false) +public let defaultDarkPresentationTheme = makeDarkPresentationTheme(accentColor: .white, baseColor: .white, preview: false) -public func makeDarkPresentationTheme(accentColor: UIColor?, preview: Bool) -> PresentationTheme { +public func makeDarkPresentationTheme(accentColor: UIColor?, baseColor: PresentationThemeBaseColor?, preview: Bool) -> PresentationTheme { let accentColor = accentColor ?? .white - return makeDarkPresentationTheme(accentColor: accentColor, preview: preview) + return makeDarkPresentationTheme(accentColor: accentColor, baseColor: baseColor, preview: preview) } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift index 9488b7a095..65a446dc86 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift @@ -1,7 +1,8 @@ import Foundation import UIKit +import TelegramUIPreferences -private func makeDarkPresentationTheme(accentColor: UIColor, preview: Bool) -> PresentationTheme { +private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: PresentationThemeBaseColor?, preview: Bool) -> PresentationTheme { let destructiveColor: UIColor = UIColor(rgb: 0xff6767) let constructiveColor: UIColor = UIColor(rgb: 0x08a723) let secretColor: UIColor = UIColor(rgb: 0x89df9e) @@ -310,6 +311,7 @@ private func makeDarkPresentationTheme(accentColor: UIColor, preview: Bool) -> P name: .builtin(.nightAccent), author: "Telegram", overallDarkAppearance: true, + baseColor: baseColor, intro: intro, passcode: passcode, rootController: rootController, @@ -322,9 +324,9 @@ private func makeDarkPresentationTheme(accentColor: UIColor, preview: Bool) -> P ) } -public let defaultDarkAccentPresentationTheme = makeDarkAccentPresentationTheme(accentColor: UIColor(rgb: 0x2ea6ff), preview: false) +public let defaultDarkAccentPresentationTheme = makeDarkAccentPresentationTheme(accentColor: UIColor(rgb: 0x2ea6ff), baseColor: .blue, preview: false) -public func makeDarkAccentPresentationTheme(accentColor: UIColor?, preview: Bool) -> PresentationTheme { +public func makeDarkAccentPresentationTheme(accentColor: UIColor?, baseColor: PresentationThemeBaseColor?, preview: Bool) -> PresentationTheme { let accentColor = accentColor ?? defaultDayAccentColor - return makeDarkPresentationTheme(accentColor: accentColor, preview: preview) + return makeDarkPresentationTheme(accentColor: accentColor, baseColor: baseColor, preview: preview) } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index 80590385c3..83ad127d50 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -1,8 +1,9 @@ import Foundation import UIKit import TelegramCore +import TelegramUIPreferences -private func makeDefaultDayPresentationTheme(accentColor: UIColor, serviceBackgroundColor: UIColor, day: Bool, preview: Bool) -> PresentationTheme { +private func makeDefaultDayPresentationTheme(accentColor: UIColor, serviceBackgroundColor: UIColor, baseColor: PresentationThemeBaseColor?, day: Bool, preview: Bool) -> PresentationTheme { let destructiveColor: UIColor = UIColor(rgb: 0xff3b30) let constructiveColor: UIColor = UIColor(rgb: 0x00c900) let secretColor: UIColor = UIColor(rgb: 0x00b12c) @@ -316,6 +317,7 @@ private func makeDefaultDayPresentationTheme(accentColor: UIColor, serviceBackgr name: .builtin(day ? .day : .dayClassic), author: "Telegram", overallDarkAppearance: false, + baseColor: baseColor, intro: intro, passcode: passcode, rootController: rootController, @@ -328,12 +330,12 @@ private func makeDefaultDayPresentationTheme(accentColor: UIColor, serviceBackgr ) } -public let defaultPresentationTheme = makeDefaultDayPresentationTheme(accentColor: UIColor(rgb: 0x007ee5), serviceBackgroundColor: defaultServiceBackgroundColor, day: false, preview: false) +public let defaultPresentationTheme = makeDefaultDayPresentationTheme(accentColor: UIColor(rgb: 0x007ee5), serviceBackgroundColor: defaultServiceBackgroundColor, baseColor: nil, day: false, preview: false) public let defaultDayAccentColor = UIColor(rgb: 0x007ee5) public let defaultServiceBackgroundColor = UIColor(rgb: 0x000000, alpha: 0.3) -public func makeDefaultDayPresentationTheme(accentColor: UIColor? = nil, serviceBackgroundColor: UIColor, day: Bool, preview: Bool) -> PresentationTheme { +public func makeDefaultDayPresentationTheme(accentColor: UIColor? = nil, serviceBackgroundColor: UIColor, baseColor: PresentationThemeBaseColor?, day: Bool, preview: Bool) -> PresentationTheme { let accentColor = accentColor ?? defaultDayAccentColor - return makeDefaultDayPresentationTheme(accentColor: accentColor, serviceBackgroundColor: serviceBackgroundColor, day: day, preview: preview) + return makeDefaultDayPresentationTheme(accentColor: accentColor, serviceBackgroundColor: serviceBackgroundColor, baseColor: baseColor, day: day, preview: preview) } diff --git a/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift b/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift index b272f8a9c2..b1d7061085 100644 --- a/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift @@ -2,19 +2,19 @@ import Foundation import UIKit import TelegramUIPreferences -public func makePresentationTheme(themeReference: PresentationThemeReference, accentColor: UIColor?, serviceBackgroundColor: UIColor, preview: Bool = false) -> PresentationTheme { +public func makePresentationTheme(themeReference: PresentationThemeReference, accentColor: UIColor?, serviceBackgroundColor: UIColor, baseColor: PresentationThemeBaseColor?, preview: Bool = false) -> PresentationTheme { let theme: PresentationTheme switch themeReference { case let .builtin(reference): switch reference { case .dayClassic: - theme = makeDefaultDayPresentationTheme(serviceBackgroundColor: serviceBackgroundColor, day: false, preview: preview) + theme = makeDefaultDayPresentationTheme(serviceBackgroundColor: serviceBackgroundColor, baseColor: baseColor, day: false, preview: preview) case .night: - theme = makeDarkPresentationTheme(accentColor: accentColor, preview: preview) + theme = makeDarkPresentationTheme(accentColor: accentColor, baseColor: baseColor, preview: preview) case .nightAccent: - theme = makeDarkAccentPresentationTheme(accentColor: accentColor, preview: preview) + theme = makeDarkAccentPresentationTheme(accentColor: accentColor, baseColor: baseColor, preview: preview) case .day: - theme = makeDefaultDayPresentationTheme(accentColor: accentColor, serviceBackgroundColor: serviceBackgroundColor, day: true, preview: preview) + theme = makeDefaultDayPresentationTheme(accentColor: accentColor, serviceBackgroundColor: serviceBackgroundColor, baseColor: baseColor, day: true, preview: preview) } } return theme diff --git a/submodules/TelegramPresentationData/Sources/PresentationData.swift b/submodules/TelegramPresentationData/Sources/PresentationData.swift index 91eedc9b8c..3e24bd2edf 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationData.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationData.swift @@ -259,7 +259,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager) - } let effectiveAccentColor = themeSettings.themeSpecificAccentColors[effectiveTheme.index]?.color - themeValue = makePresentationTheme(themeReference: effectiveTheme, accentColor: effectiveAccentColor, serviceBackgroundColor: defaultServiceBackgroundColor) + themeValue = makePresentationTheme(themeReference: effectiveTheme, accentColor: effectiveAccentColor, serviceBackgroundColor: defaultServiceBackgroundColor, baseColor: themeSettings.themeSpecificAccentColors[effectiveTheme.index]?.baseColor ?? .blue) if effectiveTheme != themeSettings.theme { switch effectiveChatWallpaper { @@ -523,7 +523,7 @@ public func updatedPresentationData(accountManager: AccountManager, applicationI } let effectiveAccentColor = themeSettings.themeSpecificAccentColors[effectiveTheme.index]?.color - let themeValue = makePresentationTheme(themeReference: effectiveTheme, accentColor: effectiveAccentColor, serviceBackgroundColor: serviceBackgroundColor) + let themeValue = makePresentationTheme(themeReference: effectiveTheme, accentColor: effectiveAccentColor, serviceBackgroundColor: serviceBackgroundColor, baseColor: themeSettings.themeSpecificAccentColors[effectiveTheme.index]?.baseColor ?? .blue) if effectiveTheme != themeSettings.theme && themeSettings.themeSpecificChatWallpapers[effectiveTheme.index] == nil { switch effectiveChatWallpaper { diff --git a/submodules/TelegramPresentationData/Sources/PresentationStrings.swift b/submodules/TelegramPresentationData/Sources/PresentationStrings.swift index 9cc0e389f6..67eaf8ce9e 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationStrings.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationStrings.swift @@ -4075,546 +4075,546 @@ public final class PresentationStrings { public var Channel_Setup_TypePublicHelp: String { return self._s[3582]! } public var Passport_Identity_EditInternalPassport: String { return self._s[3583]! } public var PhotoEditor_Skip: String { return self._s[3584]! } - public func Notifications_Exceptions(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteFor_Hours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedFiles(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[2 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_Link(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[3 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Map_ETAHours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[4 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Call_Minutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[5 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notification_GameScoreExtended(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[6 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Call_ShortMinutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[7 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedStickers(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_StickerCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, stringValue) - } - public func CreatePoll_AddMoreOptions(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Chat_DeleteMessagesConfirmation(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGE_VIDEOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + public func PUSH_CHANNEL_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func ForwardedAuthorsOthers(_ selector: Int32, _ _0: String, _ _1: String) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, _0, _1) - } - public func StickerPack_RemoveStickerCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func PUSH_CHAT_MESSAGE_ROUNDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func Watch_UserInfo_Mute(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_StatusOnline(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, stringValue) - } - public func GroupInfo_ParticipantCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func MuteExpires_Minutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGE_PHOTOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func LiveLocation_MenuChatsCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Weeks(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Years(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func MuteExpires_Hours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue) - } - public func LastSeen_MinutesAgo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedPhotos(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, _1, _2) } public func AttachmentMenu_SendPhoto(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortDays(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortMinutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ChatList_SelectedChats(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortWeeks(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedPolls(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, stringValue) - } - public func QuickSend_Photos(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Seconds(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedMessages(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Wallpaper_DeleteConfirmation(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, stringValue) - } - public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortSeconds(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_File(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Minutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notification_GameScoreSelfSimple(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func Media_SharePhoto(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_Generic(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Contacts_ImportersCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedContacts(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGE_FWDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func ForwardedVideos(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue) - } - public func UserCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func ChatList_DeleteConfirmation(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedLocations(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_ContactEmailCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessagePoll_VotedCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notification_GameScoreSelfExtended(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_Video(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Hours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_StatusMembers(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Call_Seconds(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_PollVotes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_AddMaskCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, stringValue) - } - public func AttachmentMenu_SendGif(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_StatusSubscribers(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Days(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_PollOptionCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_AddStickerCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func PUSH_CHANNEL_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func Passport_Scans(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue) } public func Invitation_Members(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[2 * 6 + Int(form.rawValue)]!, stringValue) } - public func MessageTimer_Months(_ value: Int32) -> String { + public func MessageTimer_Seconds(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteExpires_Days(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedAudios(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notification_GameScoreSimple(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_RemoveMaskCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedGifs(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Map_ETAMinutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue) - } - public func AttachmentMenu_SendVideo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedVideoMessages(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, stringValue) - } - public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_Photo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue) - } - public func LastSeen_HoursAgo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Media_ShareItem(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func Call_ShortSeconds(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Media_ShareVideo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_ContactPhoneNumberCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[3 * 6 + Int(form.rawValue)]!, stringValue) } public func MuteFor_Days(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[106 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[4 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Conversation_StatusSubscribers(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[5 * 6 + Int(form.rawValue)]!, stringValue) + } + public func VoiceOver_Chat_PollVotes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[6 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Chat_DeleteMessagesConfirmation(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[7 * 6 + Int(form.rawValue)]!, stringValue) + } + public func UserCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedPhotos(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_Exceptions(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Watch_UserInfo_Mute(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Contacts_ImportersCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Map_ETAMinutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_ShortSeconds(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue) + } + public func VoiceOver_Chat_ContactPhoneNumberCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_Generic(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ChatList_SelectedChats(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_File(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteExpires_Days(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortMinutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Conversation_StatusOnline(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortSeconds(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Passport_Scans(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Years(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_Video(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_AddStickerCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteExpires_Hours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Hours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, stringValue) } public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[107 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteExpires_Minutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_ShortMinutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedLocations(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreSelfSimple(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_Seconds(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, stringValue) + } + public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedFiles(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedAudios(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Minutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Wallpaper_DeleteConfirmation(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedAuthorsOthers(_ selector: Int32, _ _0: String, _ _1: String) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, _0, _1) + } + public func Conversation_StatusMembers(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Media_ShareVideo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreSimple(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedVideoMessages(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, stringValue) + } + public func AttachmentMenu_SendGif(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Map_ETAHours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, stringValue) } public func InviteText_ContactsCountText(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[108 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, stringValue) } - public func MessageTimer_ShortHours(_ value: Int32) -> String { + public func ForwardedGifs(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[109 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, stringValue) + } + public func LastSeen_HoursAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_Photo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGE_PHOTOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func ForwardedMessages(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, stringValue) + } + public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedContacts(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreSelfExtended(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Months(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue) + } + public func CreatePoll_AddMoreOptions(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue) + } + public func GroupInfo_ParticipantCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGE_FWDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func StickerPack_StickerCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Media_SharePhoto(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue) + } + public func AttachmentMenu_SendVideo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func LastSeen_MinutesAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Days(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, stringValue) } public func AttachmentMenu_SendItem(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[110 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGE_ROUNDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func QuickSend_Photos(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreExtended(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, stringValue) + } + public func VoiceOver_Chat_ContactEmailCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_RemoveStickerCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func ForwardedVideos(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_AddMaskCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Media_ShareItem(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortDays(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessagePoll_VotedCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue) + } + public func LiveLocation_MenuChatsCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortHours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_Minutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func ForwardedStickers(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue) + } + public func VoiceOver_Chat_PollOptionCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ChatList_DeleteConfirmation(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, _1, _2) } public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Weeks(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_RemoveMaskCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[106 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedPolls(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[107 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteFor_Hours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[108 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortWeeks(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[109 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGE_VIDEOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[110 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func SharedMedia_Link(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[111 * 6 + Int(form.rawValue)]!, stringValue) diff --git a/submodules/TelegramPresentationData/Sources/PresentationTheme.swift b/submodules/TelegramPresentationData/Sources/PresentationTheme.swift index 63bcb7557c..513bb96c03 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationTheme.swift @@ -906,6 +906,7 @@ public final class PresentationTheme: Equatable { public let name: PresentationThemeName public let author: String? public let overallDarkAppearance: Bool + public let baseColor: PresentationThemeBaseColor? public let intro: PresentationThemeIntro public let passcode: PresentationThemePasscode public let rootController: PresentationThemeRootController @@ -918,10 +919,11 @@ public final class PresentationTheme: Equatable { public let resourceCache: PresentationsResourceCache = PresentationsResourceCache() - public init(name: PresentationThemeName, author: String?, overallDarkAppearance: Bool, intro: PresentationThemeIntro, passcode: PresentationThemePasscode, rootController: PresentationThemeRootController, list: PresentationThemeList, chatList: PresentationThemeChatList, chat: PresentationThemeChat, actionSheet: PresentationThemeActionSheet, inAppNotification: PresentationThemeInAppNotification, preview: Bool = false) { + public init(name: PresentationThemeName, author: String?, overallDarkAppearance: Bool, baseColor: PresentationThemeBaseColor?, intro: PresentationThemeIntro, passcode: PresentationThemePasscode, rootController: PresentationThemeRootController, list: PresentationThemeList, chatList: PresentationThemeChatList, chat: PresentationThemeChat, actionSheet: PresentationThemeActionSheet, inAppNotification: PresentationThemeInAppNotification, preview: Bool = false) { self.name = name self.author = author self.overallDarkAppearance = overallDarkAppearance + self.baseColor = baseColor self.intro = intro self.passcode = passcode self.rootController = rootController diff --git a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift index 90e07d2ccc..4f7dca040a 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift @@ -1428,17 +1428,20 @@ extension PresentationTheme: Codable { public convenience init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - self.init(name: try values.decode(PresentationThemeName.self, forKey: .name), - author: (try? values.decode(String.self, forKey: .author)) ?? nil, - overallDarkAppearance: (try? values.decode(Bool.self, forKey: .dark)) ?? false, - intro: try values.decode(PresentationThemeIntro.self, forKey: .intro), - passcode: try values.decode(PresentationThemePasscode.self, forKey: .passcode), - rootController: try values.decode(PresentationThemeRootController.self, forKey: .root), - list: try values.decode(PresentationThemeList.self, forKey: .list), - chatList: try values.decode(PresentationThemeChatList.self, forKey: .chatList), - chat: try values.decode(PresentationThemeChat.self, forKey: .chat), - actionSheet: try values.decode(PresentationThemeActionSheet.self, forKey: .actionSheet), - inAppNotification: try values.decode(PresentationThemeInAppNotification.self, forKey: .notification)) + self.init( + name: try values.decode(PresentationThemeName.self, forKey: .name), + author: (try? values.decode(String.self, forKey: .author)) ?? nil, + overallDarkAppearance: (try? values.decode(Bool.self, forKey: .dark)) ?? false, + baseColor: nil, + intro: try values.decode(PresentationThemeIntro.self, forKey: .intro), + passcode: try values.decode(PresentationThemePasscode.self, forKey: .passcode), + rootController: try values.decode(PresentationThemeRootController.self, forKey: .root), + list: try values.decode(PresentationThemeList.self, forKey: .list), + chatList: try values.decode(PresentationThemeChatList.self, forKey: .chatList), + chat: try values.decode(PresentationThemeChat.self, forKey: .chat), + actionSheet: try values.decode(PresentationThemeActionSheet.self, forKey: .actionSheet), + inAppNotification: try values.decode(PresentationThemeInAppNotification.self, forKey: .notification) + ) } public func encode(to encoder: Encoder) throws { diff --git a/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift b/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift index ae6edcffc1..083b4c66a5 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift @@ -1,7 +1,9 @@ import Foundation import UIKit import Display +import Postbox import TelegramCore +import TelegramUIPreferences private func generateCheckImage(partial: Bool, color: UIColor) -> UIImage? { return generateImage(CGSize(width: 11.0, height: 9.0), rotatedContext: { size, context in @@ -126,13 +128,80 @@ public final class PrincipalThemeEssentialGraphics { public let radialIndicatorFileIconIncoming: UIImage public let radialIndicatorFileIconOutgoing: UIImage - init(_ theme: PresentationThemeChat, wallpaper: TelegramWallpaper, preview: Bool = false) { + public let incomingBubbleGradientImage: UIImage? + public let outgoingBubbleGradientImage: UIImage? + + init(mediaBox: MediaBox, presentationTheme: PresentationTheme, wallpaper initialWallpaper: TelegramWallpaper, preview: Bool = false, knockoutMode: Bool) { + let theme = presentationTheme.chat + var wallpaper = initialWallpaper + + if knockoutMode { + let wallpaperImage = chatControllerBackgroundImage(theme: presentationTheme, wallpaper: wallpaper, mediaBox: mediaBox, knockoutMode: false) + self.incomingBubbleGradientImage = wallpaperImage + self.outgoingBubbleGradientImage = wallpaperImage + wallpaper = presentationTheme.chat.defaultWallpaper + } else if case .color = wallpaper { + switch presentationTheme.name { + case let .builtin(name): + switch name { + case .day, .night, .nightAccent: + var incomingGradientColors: (UIColor, UIColor)? + if let incomingGradientColors = incomingGradientColors { + self.incomingBubbleGradientImage = generateImage(CGSize(width: 1.0, height: 512.0), opaque: true, scale: 1.0, rotatedContext: { size, context in + var locations: [CGFloat] = [0.0, 1.0] + let colors = [incomingGradientColors.0.cgColor, incomingGradientColors.1.cgColor] as NSArray + + let colorSpace = deviceColorSpace + let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: &locations)! + + context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) + }) + } else { + self.incomingBubbleGradientImage = nil + } + + var outgoingGradientColors: (UIColor, UIColor)? + if let baseColor = presentationTheme.baseColor { + let colors = baseColor.outgoingGradientColors + if !colors.0.isEqual(colors.1) { + outgoingGradientColors = colors + } + } + if let outgoingGradientColors = outgoingGradientColors { + self.outgoingBubbleGradientImage = generateImage(CGSize(width: 1.0, height: 512.0), opaque: true, scale: 1.0, rotatedContext: { size, context in + var locations: [CGFloat] = [0.0, 1.0] + let colors = [outgoingGradientColors.0.cgColor, outgoingGradientColors.1.cgColor] as NSArray + + let colorSpace = deviceColorSpace + let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: &locations)! + + context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) + }) + } else { + self.outgoingBubbleGradientImage = nil + } + case .dayClassic: + self.incomingBubbleGradientImage = nil + self.outgoingBubbleGradientImage = nil + } + case .custom: + self.incomingBubbleGradientImage = nil + self.outgoingBubbleGradientImage = nil + } + } else { + self.incomingBubbleGradientImage = nil + self.outgoingBubbleGradientImage = nil + } + let incoming: PresentationThemeBubbleColorComponents = wallpaper.isEmpty ? theme.message.incoming.bubble.withoutWallpaper : theme.message.incoming.bubble.withWallpaper let outgoing: PresentationThemeBubbleColorComponents = wallpaper.isEmpty ? theme.message.outgoing.bubble.withoutWallpaper : theme.message.outgoing.bubble.withWallpaper + let incomingKnockout = self.incomingBubbleGradientImage != nil + let outgoingKnockout = self.outgoingBubbleGradientImage != nil + let emptyImage = UIImage() if preview { - self.chatMessageBackgroundIncomingImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none) + self.chatMessageBackgroundIncomingImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) self.chatMessageBackgroundIncomingHighlightedImage = emptyImage self.chatMessageBackgroundIncomingMergedTopImage = emptyImage self.chatMessageBackgroundIncomingMergedTopHighlightedImage = emptyImage @@ -144,7 +213,7 @@ public final class PrincipalThemeEssentialGraphics { self.chatMessageBackgroundIncomingMergedBothHighlightedImage = emptyImage self.chatMessageBackgroundIncomingMergedSideImage = emptyImage self.chatMessageBackgroundIncomingMergedSideHighlightedImage = emptyImage - self.chatMessageBackgroundOutgoingImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none) + self.chatMessageBackgroundOutgoingImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) self.chatMessageBackgroundOutgoingHighlightedImage = emptyImage self.chatMessageBackgroundOutgoingMergedTopImage = emptyImage self.chatMessageBackgroundOutgoingMergedTopHighlightedImage = emptyImage @@ -181,32 +250,32 @@ public final class PrincipalThemeEssentialGraphics { self.radialIndicatorFileIconIncoming = emptyImage self.radialIndicatorFileIconOutgoing = emptyImage } else { - self.chatMessageBackgroundIncomingImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none) - self.chatMessageBackgroundIncomingHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .none) - self.chatMessageBackgroundIncomingMergedTopImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: false)) - self.chatMessageBackgroundIncomingMergedTopHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .top(side: false)) - self.chatMessageBackgroundIncomingMergedTopSideImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: true)) - self.chatMessageBackgroundIncomingMergedTopSideHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .top(side: true)) - self.chatMessageBackgroundIncomingMergedBottomImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .bottom) - self.chatMessageBackgroundIncomingMergedBottomHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .bottom) - self.chatMessageBackgroundIncomingMergedBothImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .both) - self.chatMessageBackgroundIncomingMergedBothHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .both) + self.chatMessageBackgroundIncomingImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) + self.chatMessageBackgroundIncomingHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) + self.chatMessageBackgroundIncomingMergedTopImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) + self.chatMessageBackgroundIncomingMergedTopHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) + self.chatMessageBackgroundIncomingMergedTopSideImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) + self.chatMessageBackgroundIncomingMergedTopSideHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) + self.chatMessageBackgroundIncomingMergedBottomImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) + self.chatMessageBackgroundIncomingMergedBottomHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) + self.chatMessageBackgroundIncomingMergedBothImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) + self.chatMessageBackgroundIncomingMergedBothHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: incomingKnockout) - self.chatMessageBackgroundOutgoingImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none) - self.chatMessageBackgroundOutgoingHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .none) - self.chatMessageBackgroundOutgoingMergedTopImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: false)) - self.chatMessageBackgroundOutgoingMergedTopHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .top(side: false)) - self.chatMessageBackgroundOutgoingMergedTopSideImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: true)) - self.chatMessageBackgroundOutgoingMergedTopSideHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .top(side: true)) - self.chatMessageBackgroundOutgoingMergedBottomImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .bottom) - self.chatMessageBackgroundOutgoingMergedBottomHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .bottom) - self.chatMessageBackgroundOutgoingMergedBothImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .both) - self.chatMessageBackgroundOutgoingMergedBothHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .both) + self.chatMessageBackgroundOutgoingImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .none, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedTopImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedTopHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .top(side: false), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedTopSideImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedTopSideHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .top(side: true), theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedBottomImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedBottomHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .bottom, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedBothImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedBothHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .both, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) - self.chatMessageBackgroundIncomingMergedSideImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .side) - self.chatMessageBackgroundOutgoingMergedSideImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .side) - self.chatMessageBackgroundIncomingMergedSideHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .side) - self.chatMessageBackgroundOutgoingMergedSideHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .side) + self.chatMessageBackgroundIncomingMergedSideImage = messageBubbleImage(incoming: true, fillColor: incoming.fill, strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedSideImage = messageBubbleImage(incoming: false, fillColor: outgoing.fill, strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundIncomingMergedSideHighlightedImage = messageBubbleImage(incoming: true, fillColor: incoming.highlightedFill, strokeColor: incoming.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) + self.chatMessageBackgroundOutgoingMergedSideHighlightedImage = messageBubbleImage(incoming: false, fillColor: outgoing.highlightedFill, strokeColor: outgoing.stroke, neighbors: .side, theme: theme, wallpaper: wallpaper, knockout: outgoingKnockout) self.checkBubbleFullImage = generateCheckImage(partial: false, color: theme.message.outgoingCheckColor)! self.checkBubblePartialImage = generateCheckImage(partial: true, color: theme.message.outgoingCheckColor)! diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift index 6766585161..d325381591 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift @@ -1,8 +1,8 @@ import Foundation import UIKit import Display +import Postbox import TelegramCore -import TelegramPresentationData private func generateLineImage(color: UIColor) -> UIImage? { return generateImage(CGSize(width: 2.0, height: 3.0), contextGenerator: { size, context in @@ -67,11 +67,11 @@ public struct PresentationResourcesChat { }) } - public static func principalGraphics(_ theme: PresentationTheme, wallpaper: TelegramWallpaper) -> PrincipalThemeEssentialGraphics { + public static func principalGraphics(mediaBox: MediaBox, knockoutWallpaper: Bool, theme: PresentationTheme, wallpaper: TelegramWallpaper) -> PrincipalThemeEssentialGraphics { let hasWallpaper = !wallpaper.isEmpty let key: PresentationResourceKey = !hasWallpaper ? PresentationResourceKey.chatPrincipalThemeEssentialGraphicsWithoutWallpaper : PresentationResourceKey.chatPrincipalThemeEssentialGraphicsWithWallpaper return theme.object(key.rawValue, { theme in - return PrincipalThemeEssentialGraphics(theme.chat, wallpaper: wallpaper, preview: theme.preview) + return PrincipalThemeEssentialGraphics(mediaBox: mediaBox, presentationTheme: theme, wallpaper: wallpaper, preview: theme.preview, knockoutMode: knockoutWallpaper) }) as! PrincipalThemeEssentialGraphics } diff --git a/submodules/TelegramPresentationData/TelegramPresentationData_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramPresentationData/TelegramPresentationData_Xcode.xcodeproj/project.pbxproj index dc736b81b1..815c2bd81c 100644 --- a/submodules/TelegramPresentationData/TelegramPresentationData_Xcode.xcodeproj/project.pbxproj +++ b/submodules/TelegramPresentationData/TelegramPresentationData_Xcode.xcodeproj/project.pbxproj @@ -22,6 +22,8 @@ D06017F522F35A4000796784 /* PresentationThemeEssentialGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017F422F35A4000796784 /* PresentationThemeEssentialGraphics.swift */; }; D06017F722F35A9200796784 /* ChatMessageBubbleImages.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017F622F35A9200796784 /* ChatMessageBubbleImages.swift */; }; D06017F922F35ACF00796784 /* WallpaperUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017F822F35ACF00796784 /* WallpaperUtils.swift */; }; + D068EE9022F4A9B60064E921 /* MediaResources.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D068EE8F22F4A9B60064E921 /* MediaResources.framework */; }; + D084F9F022F3AEFD004874CE /* ChatControllerBackgroundNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D084F9EF22F3AEFD004874CE /* ChatControllerBackgroundNode.swift */; }; D0AE31AB22B273F20058D3BC /* TelegramPresentationData.h in Headers */ = {isa = PBXBuildFile; fileRef = D0AE31A922B273F20058D3BC /* TelegramPresentationData.h */; settings = {ATTRIBUTES = (Public, ); }; }; D0AE31B422B2746B0058D3BC /* PresentationStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AE31B122B2746B0058D3BC /* PresentationStrings.swift */; }; D0AE31B522B2746B0058D3BC /* PresentationData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AE31B222B2746B0058D3BC /* PresentationData.swift */; }; @@ -61,6 +63,9 @@ D06017F422F35A4000796784 /* PresentationThemeEssentialGraphics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationThemeEssentialGraphics.swift; sourceTree = ""; }; D06017F622F35A9200796784 /* ChatMessageBubbleImages.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageBubbleImages.swift; sourceTree = ""; }; D06017F822F35ACF00796784 /* WallpaperUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WallpaperUtils.swift; sourceTree = ""; }; + D068EE8F22F4A9B60064E921 /* MediaResources.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MediaResources.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D084F9EF22F3AEFD004874CE /* ChatControllerBackgroundNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatControllerBackgroundNode.swift; sourceTree = ""; }; + D084F9F122F3AFEA004874CE /* AccountContext.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AccountContext.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0AE31A622B273F20058D3BC /* TelegramPresentationData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TelegramPresentationData.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0AE31A922B273F20058D3BC /* TelegramPresentationData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TelegramPresentationData.h; sourceTree = ""; }; D0AE31AA22B273F20058D3BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -91,6 +96,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D068EE9022F4A9B60064E921 /* MediaResources.framework in Frameworks */, D0AE31C322B274E90058D3BC /* TelegramUIPreferences.framework in Frameworks */, D0AE31BF22B274950058D3BC /* Display.framework in Frameworks */, D0AE31BD22B274830058D3BC /* TelegramCore.framework in Frameworks */, @@ -160,6 +166,7 @@ D06017F422F35A4000796784 /* PresentationThemeEssentialGraphics.swift */, D06017F622F35A9200796784 /* ChatMessageBubbleImages.swift */, D06017F822F35ACF00796784 /* WallpaperUtils.swift */, + D084F9EF22F3AEFD004874CE /* ChatControllerBackgroundNode.swift */, D06017F222F3583200796784 /* FrameworkSpecific.swift */, D0AE31A922B273F20058D3BC /* TelegramPresentationData.h */, ); @@ -169,6 +176,8 @@ D0AE31B722B2747A0058D3BC /* Frameworks */ = { isa = PBXGroup; children = ( + D068EE8F22F4A9B60064E921 /* MediaResources.framework */, + D084F9F122F3AFEA004874CE /* AccountContext.framework */, D0AE31C222B274E90058D3BC /* TelegramUIPreferences.framework */, D0AE31BE22B274950058D3BC /* Display.framework */, D0AE31BC22B274830058D3BC /* TelegramCore.framework */, @@ -274,6 +283,7 @@ 0957DE1922D95E0F001B4D57 /* PresentationThemeDecoder.swift in Sources */, D0AE31B422B2746B0058D3BC /* PresentationStrings.swift in Sources */, D0AE321422B2826A0058D3BC /* ComponentsThemes.swift in Sources */, + D084F9F022F3AEFD004874CE /* ChatControllerBackgroundNode.swift in Sources */, D0AE31C522B279720058D3BC /* StringPluralization.swift in Sources */, D0AE31CD22B279FD0058D3BC /* PresentationsResourceCache.swift in Sources */, D0AE31C922B2799B0058D3BC /* NumberPluralizationForm.m in Sources */, diff --git a/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift index bc829d1c80..41b451a70d 100644 --- a/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift @@ -255,7 +255,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } } - self.backgroundNode.image = chatControllerBackgroundImage(wallpaper: chatPresentationInterfaceState.chatWallpaper, mediaBox: context.sharedContext.accountManager.mediaBox) + self.backgroundNode.image = chatControllerBackgroundImage(theme: chatPresentationInterfaceState.theme, wallpaper: chatPresentationInterfaceState.chatWallpaper, mediaBox: context.sharedContext.accountManager.mediaBox, knockoutMode: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper) self.backgroundNode.motionEnabled = chatPresentationInterfaceState.chatWallpaper.settings?.motion ?? false self.historyNode.verticalScrollIndicatorColor = UIColor(white: 0.5, alpha: 0.8) @@ -1292,7 +1292,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { let themeUpdated = self.chatPresentationInterfaceState.theme !== chatPresentationInterfaceState.theme if self.chatPresentationInterfaceState.chatWallpaper != chatPresentationInterfaceState.chatWallpaper { - self.backgroundNode.image = chatControllerBackgroundImage(wallpaper: chatPresentationInterfaceState.chatWallpaper, mediaBox: context.sharedContext.accountManager.mediaBox) + self.backgroundNode.image = chatControllerBackgroundImage(theme: chatPresentationInterfaceState.theme, wallpaper: chatPresentationInterfaceState.chatWallpaper, mediaBox: context.sharedContext.accountManager.mediaBox, knockoutMode: self.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper) self.backgroundNode.motionEnabled = chatPresentationInterfaceState.chatWallpaper.settings?.motion ?? false } diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift index 4c409c7488..f9679681d3 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift @@ -7,6 +7,7 @@ import AsyncDisplayKit import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import MediaResources private let historyMessageCount: Int = 100 @@ -196,7 +197,7 @@ private func mappedInsertEntries(context: AccountContextImpl, chatLocation: Chat } return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) case let .UnreadEntry(_, presentationData): - return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatUnreadItem(index: entry.entry.index, presentationData: presentationData), directionHint: entry.directionHint) + return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatUnreadItem(index: entry.entry.index, presentationData: presentationData, context: context), directionHint: entry.directionHint) case let .ChatInfoEntry(text, presentationData): return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(text: text, controllerInteraction: controllerInteraction, presentationData: presentationData), directionHint: entry.directionHint) case let .SearchEntry(theme, strings): @@ -230,7 +231,7 @@ private func mappedUpdateEntries(context: AccountContextImpl, chatLocation: Chat } return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) case let .UnreadEntry(_, presentationData): - return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatUnreadItem(index: entry.entry.index, presentationData: presentationData), directionHint: entry.directionHint) + return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatUnreadItem(index: entry.entry.index, presentationData: presentationData, context: context), directionHint: entry.directionHint) case let .ChatInfoEntry(text, presentationData): return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(text: text, controllerInteraction: controllerInteraction, presentationData: presentationData), directionHint: entry.directionHint) case let .SearchEntry(theme, strings): @@ -782,7 +783,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { strongSelf.forEachItemHeaderNode { itemHeaderNode in if let dateNode = itemHeaderNode as? ChatMessageDateHeaderNode { - dateNode.updatePresentationData(chatPresentationData) + dateNode.updatePresentationData(chatPresentationData, context: context) } else if let dateNode = itemHeaderNode as? ListMessageDateHeaderNode { dateNode.updateThemeAndStrings(theme: presentationData.theme, strings: presentationData.strings) } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index e3c591ed09..727f4f45d4 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -445,7 +445,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .minimal) - let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.presentationData, false, viewCount, dateText, statusType, CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude)) + let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.context, item.presentationData, false, viewCount, dateText, statusType, CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude)) var viaBotApply: (TextNodeLayout, () -> TextNode)? var replyInfoApply: (CGSize, () -> ChatMessageReplyInfoNode)? diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift index 478d2a7af8..1d11c9589d 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift @@ -537,7 +537,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { } } - statusSizeAndApply = statusLayout(presentationData, edited && !sentViaBot, viewCount, dateText, statusType, textConstrainedSize) + statusSizeAndApply = statusLayout(context, presentationData, edited && !sentViaBot, viewCount, dateText, statusType, textConstrainedSize) } default: break diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleBackdrop.swift b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleBackdrop.swift new file mode 100644 index 0000000000..204c9fe4c5 --- /dev/null +++ b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleBackdrop.swift @@ -0,0 +1,47 @@ +import Foundation +import AsyncDisplayKit +import Display +import Postbox +import TelegramPresentationData + +final class ChatMessageBubbleBackdrop: ASDisplayNode { + private let backgroundContent: ASDisplayNode + + private var currentType: ChatMessageBackgroundType? + private var theme: ChatPresentationThemeData? + + override init() { + self.backgroundContent = ASDisplayNode() + + super.init() + + self.clipsToBounds = true + + self.addSubnode(self.backgroundContent) + } + + func setType(type: ChatMessageBackgroundType, theme: ChatPresentationThemeData, mediaBox: MediaBox, essentialGraphics: PrincipalThemeEssentialGraphics) { + if self.currentType != type || self.theme != theme { + self.currentType = type + self.theme = theme + + switch type { + case .none: + self.backgroundContent.contents = nil + case .incoming: + self.backgroundContent.contents = essentialGraphics.incomingBubbleGradientImage?.cgImage + case .outgoing: + self.backgroundContent.contents = essentialGraphics.outgoingBubbleGradientImage?.cgImage + } + } + } + + func update(rect: CGRect, within containerSize: CGSize) { + self.backgroundContent.frame = CGRect(origin: CGPoint(x: -rect.minX, y: -rect.minY), size: containerSize) + } + + func offset(value: CGFloat, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + let transition: ContainedViewLayoutTransition = .animated(duration: duration, curve: animationCurve) + transition.animatePositionAdditive(node: self.backgroundContent, offset: CGPoint(x: 0.0, y: -value)) + } +} diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift index 7b86819d8a..fa9438ff29 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift @@ -129,6 +129,7 @@ private enum ContentNodeOperation { } class ChatMessageBubbleItemNode: ChatMessageItemView { + private let backgroundWallpaperNode: ChatMessageBubbleBackdrop private let backgroundNode: ChatMessageBackground private var transitionClippingNode: ASDisplayNode? @@ -172,11 +173,14 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { } required init() { + self.backgroundWallpaperNode = ChatMessageBubbleBackdrop() + self.backgroundNode = ChatMessageBackground() self.messageAccessibilityArea = AccessibilityAreaNode() super.init(layerBacked: false) + self.addSubnode(self.backgroundWallpaperNode) self.addSubnode(self.backgroundNode) self.addSubnode(self.messageAccessibilityArea) @@ -214,23 +218,21 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { override func animateRemoved(_ currentTimestamp: Double, duration: Double) { super.animateRemoved(currentTimestamp, duration: duration) - self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false) + self.allowsGroupOpacity = true + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak self] _ in + self?.allowsGroupOpacity = false + }) + self.layer.animateScale(from: 1.0, to: 0.1, duration: 0.15, removeOnCompletion: false) + self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: self.bounds.width / 2.0 - self.backgroundNode.frame.midX, y: self.backgroundNode.frame.midY), duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true) } override func animateAdded(_ currentTimestamp: Double, duration: Double) { super.animateAdded(currentTimestamp, duration: duration) - self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - - self.nameNode?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - self.adminBadgeNode?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - self.credibilityIconNode?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - self.forwardInfoNode?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - self.replyInfoNode?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - - for contentNode in self.contentNodes { - contentNode.animateAdded(currentTimestamp, duration: duration) - } + self.allowsGroupOpacity = true + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, completion: { [weak self] _ in + self?.allowsGroupOpacity = false + }) } override func didLoad() { @@ -372,7 +374,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { forwardInfoLayout: (ChatPresentationData, PresentationStrings, ChatMessageForwardInfoType, Peer?, String?, CGSize) -> (CGSize, () -> ChatMessageForwardInfoNode), replyInfoLayout: (ChatPresentationData, PresentationStrings, AccountContextImpl, ChatMessageReplyInfoType, Message, CGSize) -> (CGSize, () -> ChatMessageReplyInfoNode), actionButtonsLayout: (AccountContextImpl, ChatPresentationThemeData, PresentationStrings, ReplyMarkupMessageAttribute, Message, CGFloat) -> (minWidth: CGFloat, layout: (CGFloat) -> (CGSize, (Bool) -> ChatMessageActionButtonsNode)), - mosaicStatusLayout: (ChatPresentationData, Bool, Int?, String, ChatMessageDateAndStatusType, CGSize) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode), + mosaicStatusLayout: (AccountContextImpl, ChatPresentationData, Bool, Int?, String, ChatMessageDateAndStatusType, CGSize) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode), currentShareButtonNode: HighlightableButtonNode?, layoutConstants: ChatMessageItemLayoutConstants, currentItem: ChatMessageItem?, @@ -837,7 +839,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { } } - mosaicStatusSizeAndApply = mosaicStatusLayout(item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: 200.0, height: CGFloat.greatestFiniteMagnitude)) + mosaicStatusSizeAndApply = mosaicStatusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: 200.0, height: CGFloat.greatestFiniteMagnitude)) } } @@ -1257,7 +1259,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { let layout = ListViewItemNodeLayout(contentSize: layoutSize, insets: layoutInsets) - let graphics = PresentationResourcesChat.principalGraphics(item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper) + let graphics = PresentationResourcesChat.principalGraphics(mediaBox: item.context.account.postbox.mediaBox, knockoutWallpaper: item.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper) var updatedMergedTop = mergedBottom var updatedMergedBottom = mergedTop @@ -1375,6 +1377,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { backgroundType = .incoming(mergeType) } strongSelf.backgroundNode.setType(type: backgroundType, highlighted: strongSelf.highlightedState, graphics: graphics, transition: transition) + strongSelf.backgroundWallpaperNode.setType(type: backgroundType, theme: item.presentationData.theme, mediaBox: item.context.account.postbox.mediaBox, essentialGraphics: graphics) strongSelf.backgroundType = backgroundType @@ -1633,6 +1636,10 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { strongSelf.backgroundFrameTransition = nil } strongSelf.backgroundNode.frame = backgroundFrame + strongSelf.backgroundWallpaperNode.frame = backgroundFrame + if let (rect, size) = strongSelf.absoluteRect { + strongSelf.updateAbsoluteRect(rect, within: size) + } strongSelf.messageAccessibilityArea.frame = backgroundFrame if let shareButtonNode = strongSelf.shareButtonNode { shareButtonNode.frame = CGRect(origin: CGPoint(x: backgroundFrame.maxX + 8.0, y: backgroundFrame.maxY - 30.0), size: CGSize(width: 29.0, height: 29.0)) @@ -1779,6 +1786,10 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { if let backgroundFrameTransition = self.backgroundFrameTransition { let backgroundFrame = CGRect.interpolator()(backgroundFrameTransition.0, backgroundFrameTransition.1, progress) as! CGRect self.backgroundNode.frame = backgroundFrame + self.backgroundWallpaperNode.frame = backgroundFrame + if let (rect, size) = self.absoluteRect { + self.updateAbsoluteRect(rect, within: size) + } self.messageAccessibilityArea.frame = backgroundFrame if let shareButtonNode = self.shareButtonNode { @@ -2120,7 +2131,6 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { if !self.backgroundNode.frame.contains(point) { if self.actionButtonsNode == nil || !self.actionButtonsNode!.frame.contains(point) { - //return nil } } @@ -2194,6 +2204,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { } self.backgroundNode.isHidden = hasHiddenBackground + self.backgroundWallpaperNode.isHidden = hasHiddenBackground } override func updateAutomaticMediaDownloadSettings() { @@ -2346,7 +2357,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { if self.highlightedState != highlighted { self.highlightedState = highlighted if let backgroundType = self.backgroundType { - let graphics = PresentationResourcesChat.principalGraphics(item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper) + let graphics = PresentationResourcesChat.principalGraphics(mediaBox: item.context.account.postbox.mediaBox, knockoutWallpaper: item.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper) if highlighted { self.backgroundNode.setType(type: backgroundType, highlighted: true, graphics: graphics, transition: .immediate) @@ -2442,4 +2453,16 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { break } } + + private var absoluteRect: (CGRect, CGSize)? + + override func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { + self.absoluteRect = (rect, containerSize) + let mappedRect = CGRect(origin: CGPoint(x: rect.minX + self.backgroundWallpaperNode.frame.minX, y: containerSize.height - rect.maxY + self.backgroundWallpaperNode.frame.minY), size: rect.size) + self.backgroundWallpaperNode.update(rect: mappedRect, within: containerSize) + } + + override func applyAbsoluteOffset(value: CGFloat, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + self.backgroundWallpaperNode.offset(value: -value, animationCurve: animationCurve, duration: duration) + } } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageContactBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageContactBubbleContentNode.swift index 5cef4e0201..eea254f241 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageContactBubbleContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageContactBubbleContentNode.swift @@ -177,7 +177,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode { var statusApply: ((Bool) -> Void)? if let statusType = statusType { - let (size, apply) = statusLayout(item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude)) + let (size, apply) = statusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude)) statusSize = size statusApply = apply } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageDateAndStatusNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageDateAndStatusNode.swift index 1a812564b3..4266ffcdc1 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageDateAndStatusNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageDateAndStatusNode.swift @@ -127,7 +127,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { self.addSubnode(self.dateNode) } - func asyncLayout() -> (_ presentationData: ChatPresentationData, _ edited: Bool, _ impressionCount: Int?, _ dateText: String, _ type: ChatMessageDateAndStatusType, _ constrainedSize: CGSize) -> (CGSize, (Bool) -> Void) { + func asyncLayout() -> (_ context: AccountContextImpl, _ presentationData: ChatPresentationData, _ edited: Bool, _ impressionCount: Int?, _ dateText: String, _ type: ChatMessageDateAndStatusType, _ constrainedSize: CGSize) -> (CGSize, (Bool) -> Void) { let dateLayout = TextNode.asyncLayout(self.dateNode) var checkReadNode = self.checkReadNode @@ -141,7 +141,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { let currentType = self.type let currentTheme = self.theme - return { presentationData, edited, impressionCount, dateText, type, constrainedSize in + return { context, presentationData, edited, impressionCount, dateText, type, constrainedSize in let dateColor: UIColor var backgroundImage: UIImage? var outgoingStatus: ChatMessageDateAndStatusOutgoingType? @@ -155,7 +155,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { let themeUpdated = presentationData.theme != currentTheme || type != currentType - let graphics = PresentationResourcesChat.principalGraphics(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) + let graphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) let offset: CGFloat = -UIScreenPixel switch type { @@ -506,17 +506,17 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { } } - static func asyncLayout(_ node: ChatMessageDateAndStatusNode?) -> (_ presentationData: ChatPresentationData, _ edited: Bool, _ impressionCount: Int?, _ dateText: String, _ type: ChatMessageDateAndStatusType, _ constrainedSize: CGSize) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode) { + static func asyncLayout(_ node: ChatMessageDateAndStatusNode?) -> (_ context: AccountContextImpl, _ presentationData: ChatPresentationData, _ edited: Bool, _ impressionCount: Int?, _ dateText: String, _ type: ChatMessageDateAndStatusType, _ constrainedSize: CGSize) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode) { let currentLayout = node?.asyncLayout() - return { presentationData, edited, impressionCount, dateText, type, constrainedSize in + return { context, presentationData, edited, impressionCount, dateText, type, constrainedSize in let resultNode: ChatMessageDateAndStatusNode let resultSizeAndApply: (CGSize, (Bool) -> Void) if let node = node, let currentLayout = currentLayout { resultNode = node - resultSizeAndApply = currentLayout(presentationData, edited, impressionCount, dateText, type, constrainedSize) + resultSizeAndApply = currentLayout(context, presentationData, edited, impressionCount, dateText, type, constrainedSize) } else { resultNode = ChatMessageDateAndStatusNode() - resultSizeAndApply = resultNode.asyncLayout()(presentationData, edited, impressionCount, dateText, type, constrainedSize) + resultSizeAndApply = resultNode.asyncLayout()(context, presentationData, edited, impressionCount, dateText, type, constrainedSize) } return (resultSizeAndApply.0, { animated in diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageDateHeader.swift b/submodules/TelegramUI/TelegramUI/ChatMessageDateHeader.swift index f4a9f54141..ff80ca22b1 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageDateHeader.swift @@ -3,6 +3,7 @@ import UIKit import Display import AsyncDisplayKit import TelegramPresentationData +import Postbox private let timezoneOffset: Int32 = { let nowTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) @@ -20,11 +21,13 @@ final class ChatMessageDateHeader: ListViewItemHeader { let id: Int64 let presentationData: ChatPresentationData + let context: AccountContextImpl let action: ((Int32) -> Void)? - init(timestamp: Int32, presentationData: ChatPresentationData, action:((Int32) -> Void)? = nil) { + init(timestamp: Int32, presentationData: ChatPresentationData, context: AccountContextImpl, action: ((Int32) -> Void)? = nil) { self.timestamp = timestamp self.presentationData = presentationData + self.context = context self.action = action if timestamp == Int32.max { self.roundedTimestamp = timestamp / (granularity) * (granularity) @@ -39,7 +42,7 @@ final class ChatMessageDateHeader: ListViewItemHeader { let height: CGFloat = 34.0 func node() -> ListViewItemHeaderNode { - return ChatMessageDateHeaderNode(localTimestamp: self.roundedTimestamp, presentationData: self.presentationData, action: self.action) + return ChatMessageDateHeaderNode(localTimestamp: self.roundedTimestamp, presentationData: self.presentationData, context: self.context, action: self.action) } } @@ -83,13 +86,15 @@ final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { private let localTimestamp: Int32 private var presentationData: ChatPresentationData + private let context: AccountContextImpl private var flashingOnScrolling = false private var stickDistanceFactor: CGFloat = 0.0 private var action: ((Int32) -> Void)? = nil - init(localTimestamp: Int32, presentationData: ChatPresentationData, action:((Int32) -> Void)? = nil) { + init(localTimestamp: Int32, presentationData: ChatPresentationData, context: AccountContextImpl, action: ((Int32) -> Void)? = nil) { self.presentationData = presentationData + self.context = context self.localTimestamp = localTimestamp self.action = action @@ -112,7 +117,7 @@ final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) - let graphics = PresentationResourcesChat.principalGraphics(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) + let graphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) self.backgroundNode.image = graphics.dateStaticBackground self.stickBackgroundNode.image = graphics.dateFloatingBackground @@ -156,8 +161,8 @@ final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { self.view.addGestureRecognizer(ListViewTapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) } - func updatePresentationData(_ presentationData: ChatPresentationData) { - let graphics = PresentationResourcesChat.principalGraphics(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) + func updatePresentationData(_ presentationData: ChatPresentationData, context: AccountContextImpl) { + let graphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) self.backgroundNode.image = graphics.dateStaticBackground self.stickBackgroundNode.image = graphics.dateFloatingBackground diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveFileNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveFileNode.swift index e84c21dc02..20a898be70 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveFileNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveFileNode.swift @@ -280,7 +280,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode { let dateText = stringForMessageTimestampStatus(accountPeerId: context.account.peerId, message: message, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, strings: presentationData.strings) - let (size, apply) = statusLayout(presentationData, edited && !sentViaBot, viewCount, dateText, statusType, constrainedSize) + let (size, apply) = statusLayout(context, presentationData, edited && !sentViaBot, viewCount, dateText, statusType, constrainedSize) statusSize = size statusApply = apply } @@ -423,7 +423,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode { if hasThumbnail { fileIconImage = nil } else { - let principalGraphics = PresentationResourcesChat.principalGraphics(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) + let principalGraphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) fileIconImage = incoming ? principalGraphics.radialIndicatorFileIconIncoming : principalGraphics.radialIndicatorFileIconOutgoing } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift index 3151b18fde..ab9c101940 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift @@ -266,7 +266,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { } else { maxDateAndStatusWidth = width - videoFrame.midX - 85.0 } - let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: max(1.0, maxDateAndStatusWidth), height: CGFloat.greatestFiniteMagnitude)) + let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: max(1.0, maxDateAndStatusWidth), height: CGFloat.greatestFiniteMagnitude)) var contentSize = imageSize var dateAndStatusOverflow = false diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift index 9c30a04bf9..56868c88df 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift @@ -319,7 +319,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { self.effectiveAuthorId = effectiveAuthor?.id - self.header = ChatMessageDateHeader(timestamp: content.index.timestamp, presentationData: presentationData, action: { timestamp in + self.header = ChatMessageDateHeader(timestamp: content.index.timestamp, presentationData: presentationData, context: context, action: { timestamp in var calendar = NSCalendar.current calendar.timeZone = TimeZone(abbreviation: "UTC")! let date = Date(timeIntervalSince1970: TimeInterval(timestamp)) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageMapBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageMapBubbleContentNode.swift index 151b6668b4..d6b9423015 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageMapBubbleContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageMapBubbleContentNode.swift @@ -227,7 +227,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode { var statusApply: ((Bool) -> Void)? if let statusType = statusType { - let (size, apply) = statusLayout(item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude)) + let (size, apply) = statusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude)) statusSize = size statusApply = apply } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageMediaBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageMediaBubbleContentNode.swift index 26e323799d..78ae58ebcf 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageMediaBubbleContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageMediaBubbleContentNode.swift @@ -197,7 +197,7 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { var statusApply: ((Bool) -> Void)? if let statusType = statusType { - let (size, apply) = statusLayout(item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: imageSize.width - 30.0, height: CGFloat.greatestFiniteMagnitude)) + let (size, apply) = statusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: imageSize.width - 30.0, height: CGFloat.greatestFiniteMagnitude)) statusSize = size statusApply = apply } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessagePhoneNumberRequestContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessagePhoneNumberRequestContentNode.swift index 14a5826ed4..3465a9b9c2 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessagePhoneNumberRequestContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessagePhoneNumberRequestContentNode.swift @@ -100,7 +100,7 @@ class ChatMessagePhoneNumberRequestContentNode: ChatMessageBubbleContentNode { var statusApply: ((Bool) -> Void)? if let statusType = statusType { - let (size, apply) = statusLayout(item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude)) + let (size, apply) = statusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude)) statusSize = size statusApply = apply } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessagePollBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessagePollBubbleContentNode.swift index 4b2661103b..fbe7b5b754 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessagePollBubbleContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessagePollBubbleContentNode.swift @@ -625,7 +625,7 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode { var statusApply: ((Bool) -> Void)? if let statusType = statusType { - let (size, apply) = statusLayout(item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, textConstrainedSize) + let (size, apply) = statusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, textConstrainedSize) statusSize = size statusApply = apply } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift index 7d44bf00cb..8a36354cfc 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift @@ -261,7 +261,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .regular) - let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude)) + let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude)) var viaBotApply: (TextNodeLayout, () -> TextNode)? var replyInfoApply: (CGSize, () -> ChatMessageReplyInfoNode)? diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift index ffdbcde6fe..92d7a8f88b 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift @@ -132,7 +132,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { var statusApply: ((Bool) -> Void)? if let statusType = statusType { - let (size, apply) = statusLayout(item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, textConstrainedSize) + let (size, apply) = statusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, textConstrainedSize) statusSize = size statusApply = apply } diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift index 7beadbaf53..beaa38c8d3 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift @@ -107,7 +107,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { super.init() - self.backgroundNode.contents = chatControllerBackgroundImage(wallpaper: self.state.chatWallpaper, mediaBox: context.sharedContext.accountManager.mediaBox)?.cgImage + self.backgroundNode.contents = chatControllerBackgroundImage(theme: self.state.theme, wallpaper: self.state.chatWallpaper, mediaBox: context.sharedContext.accountManager.mediaBox, knockoutMode: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper)?.cgImage self.addSubnode(self.backgroundNode) self.addSubnode(self.listNode) diff --git a/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift index 780fb1dd4f..74877cbe4f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift @@ -100,6 +100,7 @@ private final class ActionSheetItemNode: ASDisplayNode { } final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, UIScrollViewDelegate { + private let context: AccountContextImpl private var presentationData: PresentationData private let sendButtonFrame: CGRect private let textFieldFrame: CGRect @@ -129,6 +130,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, private var validLayout: ContainerViewLayout? init(context: AccountContextImpl, sendButtonFrame: CGRect, textInputNode: EditableTextNode, forwardedCount: Int?, send: (() -> Void)?, sendSilently: (() -> Void)?, cancel: (() -> Void)?) { + self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.sendButtonFrame = sendButtonFrame self.textFieldFrame = textInputNode.convert(textInputNode.bounds, to: nil) @@ -215,7 +217,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, } self.messageBackgroundNode.contentMode = .scaleToFill - let graphics = PresentationResourcesChat.principalGraphics(self.presentationData.theme, wallpaper: self.presentationData.chatWallpaper) + let graphics = PresentationResourcesChat.principalGraphics(mediaBox: self.context.account.postbox.mediaBox, knockoutWallpaper: self.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: self.presentationData.theme, wallpaper: self.presentationData.chatWallpaper) self.messageBackgroundNode.image = graphics.chatMessageBackgroundOutgoingImage self.view.addSubview(self.effectView) @@ -285,7 +287,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, self.toMessageTextNode.attributedText = toAttributedText } - let graphics = PresentationResourcesChat.principalGraphics(self.presentationData.theme, wallpaper: self.presentationData.chatWallpaper) + let graphics = PresentationResourcesChat.principalGraphics(mediaBox: self.context.account.postbox.mediaBox, knockoutWallpaper: self.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: self.presentationData.theme, wallpaper: self.presentationData.chatWallpaper) self.messageBackgroundNode.image = graphics.chatMessageBackgroundOutgoingImage for node in self.contentNodes { diff --git a/submodules/TelegramUI/TelegramUI/ChatUnreadItem.swift b/submodules/TelegramUI/TelegramUI/ChatUnreadItem.swift index b5006dd3d2..e73f376609 100644 --- a/submodules/TelegramUI/TelegramUI/ChatUnreadItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatUnreadItem.swift @@ -13,10 +13,10 @@ class ChatUnreadItem: ListViewItem { let presentationData: ChatPresentationData let header: ChatMessageDateHeader - init(index: MessageIndex, presentationData: ChatPresentationData) { + init(index: MessageIndex, presentationData: ChatPresentationData, context: AccountContextImpl) { self.index = index self.presentationData = presentationData - self.header = ChatMessageDateHeader(timestamp: index.timestamp, presentationData: presentationData) + self.header = ChatMessageDateHeader(timestamp: index.timestamp, presentationData: presentationData, context: context) } func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { diff --git a/submodules/TelegramUI/TelegramUI/ContactListNode.swift b/submodules/TelegramUI/TelegramUI/ContactListNode.swift index 35d0bf6e31..e642a48c1e 100644 --- a/submodules/TelegramUI/TelegramUI/ContactListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ContactListNode.swift @@ -10,6 +10,8 @@ import TelegramUIPreferences import DeviceAccess import MergeLists import ItemListUI +import MediaResources +import AccountContext private let dropDownIcon = { () -> UIImage in UIGraphicsBeginImageContextWithOptions(CGSize(width: 12.0, height: 12.0), false, 0.0) diff --git a/submodules/TelegramUI/TelegramUI/CustomWallpaperPicker.swift b/submodules/TelegramUI/TelegramUI/CustomWallpaperPicker.swift index 51893e342e..eeda8c94d5 100644 --- a/submodules/TelegramUI/TelegramUI/CustomWallpaperPicker.swift +++ b/submodules/TelegramUI/TelegramUI/CustomWallpaperPicker.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import LegacyComponents import TelegramUIPreferences +import MediaResources func presentCustomWallpaperPicker(context: AccountContextImpl, present: @escaping (ViewController) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/DebugController.swift b/submodules/TelegramUI/TelegramUI/DebugController.swift index f8e70606df..af6b45a7f1 100644 --- a/submodules/TelegramUI/TelegramUI/DebugController.swift +++ b/submodules/TelegramUI/TelegramUI/DebugController.swift @@ -58,6 +58,7 @@ private enum DebugControllerEntry: ItemListNodeEntry { case resetBiometricsData(PresentationTheme) case optimizeDatabase(PresentationTheme) case photoPreview(PresentationTheme, Bool) + case knockoutWallpaper(PresentationTheme, Bool) case exportTheme(PresentationTheme) case versionInfo(PresentationTheme) @@ -71,7 +72,7 @@ private enum DebugControllerEntry: ItemListNodeEntry { return DebugControllerSection.logging.rawValue case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries: return DebugControllerSection.experiments.rawValue - case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .exportTheme: + case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .exportTheme: return DebugControllerSection.experiments.rawValue case .versionInfo: return DebugControllerSection.info.rawValue @@ -120,10 +121,12 @@ private enum DebugControllerEntry: ItemListNodeEntry { return 18 case .photoPreview: return 19 - case .exportTheme: - return 20 - case .versionInfo: + case .knockoutWallpaper: return 21 + case .exportTheme: + return 22 + case .versionInfo: + return 23 } } @@ -470,6 +473,16 @@ private enum DebugControllerEntry: ItemListNodeEntry { }) }).start() }) + case let .knockoutWallpaper(theme, value): + return ItemListSwitchItem(theme: theme, title: "Knockout Wallpaper", value: value, sectionId: self.section, style: .blocks, updated: { value in + let _ = arguments.sharedContext.accountManager.transaction ({ transaction in + transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in + var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings + settings.knockoutWallpaper = value + return settings + }) + }).start() + }) case let .exportTheme(theme): return ItemListActionItem(theme: theme, title: "Export Theme", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { guard let context = arguments.context else { @@ -537,6 +550,7 @@ private func debugControllerEntries(presentationData: PresentationData, loggingS entries.append(.resetHoles(presentationData.theme)) entries.append(.optimizeDatabase(presentationData.theme)) entries.append(.photoPreview(presentationData.theme, experimentalSettings.chatListPhotos)) + entries.append(.knockoutWallpaper(presentationData.theme, experimentalSettings.knockoutWallpaper)) entries.append(.versionInfo(presentationData.theme)) diff --git a/submodules/TelegramUI/TelegramUI/EmojiResources.swift b/submodules/TelegramUI/TelegramUI/EmojiResources.swift index 6983e6aa7a..9c6c7ad3ac 100644 --- a/submodules/TelegramUI/TelegramUI/EmojiResources.swift +++ b/submodules/TelegramUI/TelegramUI/EmojiResources.swift @@ -9,6 +9,7 @@ import WebPImage #else import WebP #endif +import MediaResources public struct EmojiThumbnailResourceId: MediaResourceId { public let emoji: String diff --git a/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift b/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift index e7c29f278e..84ec4e6c29 100644 --- a/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift +++ b/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift @@ -14,6 +14,7 @@ import WebP #endif import Lottie import TelegramUIPrivateModule +import MediaResources public func fetchCachedResourceRepresentation(account: Account, resource: MediaResource, representation: CachedMediaResourceRepresentation) -> Signal { if let representation = representation as? CachedStickerAJpegRepresentation { diff --git a/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift b/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift index 12a7eea243..e86d01087d 100644 --- a/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift +++ b/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift @@ -134,7 +134,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode { return { item, params, neighbors in var updatedBackgroundImage: UIImage? if currentItem?.wallpaper != item.wallpaper { - updatedBackgroundImage = chatControllerBackgroundImage(wallpaper: item.wallpaper, mediaBox: item.context.sharedContext.accountManager.mediaBox) + updatedBackgroundImage = chatControllerBackgroundImage(theme: item.theme, wallpaper: item.wallpaper, mediaBox: item.context.sharedContext.accountManager.mediaBox, knockoutMode: item.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper) } let insets: UIEdgeInsets @@ -217,7 +217,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode { if node.supernode == nil { strongSelf.containerNode.addSubnode(node) } - node.frame = CGRect(origin: CGPoint(x: 0.0, y: topOffset), size: node.frame.size) + node.updateFrame(CGRect(origin: CGPoint(x: 0.0, y: topOffset), size: node.frame.size), within: layout.contentSize) topOffset += node.frame.size.height } diff --git a/submodules/TelegramUI/TelegramUI/LegacyInstantVideoController.swift b/submodules/TelegramUI/TelegramUI/LegacyInstantVideoController.swift index 48ad746ebf..1ae295a704 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyInstantVideoController.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyInstantVideoController.swift @@ -5,7 +5,7 @@ import TelegramCore import Postbox import SwiftSignalKit import TelegramPresentationData - +import MediaResources import LegacyComponents final class InstantVideoControllerRecordingStatus { diff --git a/submodules/TelegramUI/TelegramUI/NotificationsAndSounds.swift b/submodules/TelegramUI/TelegramUI/NotificationsAndSounds.swift index ad8d4d6f17..5317a0f0c3 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationsAndSounds.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationsAndSounds.swift @@ -8,6 +8,7 @@ import TelegramPresentationData import TelegramUIPreferences import DeviceAccess import ItemListUI +import AccountContext private final class NotificationsAndSoundsArguments { let context: AccountContextImpl diff --git a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift index 76302f996f..6693733f73 100644 --- a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift +++ b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift @@ -350,7 +350,7 @@ func openChatMessage(context: AccountContextImpl, message: Message, standalone: return nil })) case let .theme(media): - let controller = ThemePreviewController(context: context, previewTheme: makeDefaultDayPresentationTheme(accentColor: nil, serviceBackgroundColor: .black, day: true, preview: false), media: .message(message: MessageReference(message), media: media)) + let controller = ThemePreviewController(context: context, previewTheme: makeDefaultDayPresentationTheme(accentColor: nil, serviceBackgroundColor: .black, baseColor: nil, day: true, preview: false), media: .message(message: MessageReference(message), media: media)) present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) } } diff --git a/submodules/TelegramUI/TelegramUI/PasscodeEntryControllerNode.swift b/submodules/TelegramUI/TelegramUI/PasscodeEntryControllerNode.swift index e7ca7357cf..9450e0e924 100644 --- a/submodules/TelegramUI/TelegramUI/PasscodeEntryControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/PasscodeEntryControllerNode.swift @@ -173,7 +173,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode { switch self.wallpaper { case .image, .file: - if let image = chatControllerBackgroundImage(wallpaper: self.wallpaper, mediaBox: self.context.sharedContext.accountManager.mediaBox, composed: false) { + if let image = chatControllerBackgroundImage(theme: self.theme, wallpaper: self.wallpaper, mediaBox: self.context.sharedContext.accountManager.mediaBox, composed: false, knockoutMode: false) { self.background = ImageBasedPasscodeBackground(image: image, size: size) } else { self.background = GradientPasscodeBackground(size: size, backgroundColors: self.theme.passcode.backgroundColors.colors, buttonColor: self.theme.passcode.buttonColor) diff --git a/submodules/TelegramUI/TelegramUI/Permission.swift b/submodules/TelegramUI/TelegramUI/Permission.swift index 06247d162e..1b786fef04 100644 --- a/submodules/TelegramUI/TelegramUI/Permission.swift +++ b/submodules/TelegramUI/TelegramUI/Permission.swift @@ -3,6 +3,7 @@ import SwiftSignalKit import Postbox import TelegramCore import DeviceAccess +import AccountContext public enum PermissionKind: Int32 { case contacts diff --git a/submodules/TelegramUI/TelegramUI/PhotoResources.swift b/submodules/TelegramUI/TelegramUI/PhotoResources.swift index acc3ac7fb0..2dc7eb3957 100644 --- a/submodules/TelegramUI/TelegramUI/PhotoResources.swift +++ b/submodules/TelegramUI/TelegramUI/PhotoResources.swift @@ -13,6 +13,7 @@ import WebPImage import WebP #endif import TelegramUIPreferences +import MediaResources private enum ResourceFileData { case data(Data) diff --git a/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping b/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping index 766825850c..53117500dc 100644 Binary files a/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping and b/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping differ diff --git a/submodules/TelegramUI/TelegramUI/SettingsController.swift b/submodules/TelegramUI/TelegramUI/SettingsController.swift index 7f19bfffea..1d452e708f 100644 --- a/submodules/TelegramUI/TelegramUI/SettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/SettingsController.swift @@ -15,6 +15,7 @@ import TelegramPresentationData import TelegramUIPreferences import DeviceAccess import ItemListUI +import AccountContext private let maximumNumberOfAccounts = 3 diff --git a/submodules/TelegramUI/TelegramUI/StickerResources.swift b/submodules/TelegramUI/TelegramUI/StickerResources.swift index 772a8c99a2..f8239df0b8 100644 --- a/submodules/TelegramUI/TelegramUI/StickerResources.swift +++ b/submodules/TelegramUI/TelegramUI/StickerResources.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Display import TelegramUIPrivateModule import TelegramCore +import MediaResources private func imageFromAJpeg(data: Data) -> (UIImage, UIImage)? { if let (colorData, alphaData) = data.withUnsafeBytes({ (bytes: UnsafePointer) -> (Data, Data)? in diff --git a/submodules/TelegramUI/TelegramUI/TelegramRootController.swift b/submodules/TelegramUI/TelegramUI/TelegramRootController.swift index fb17fbe56c..0ce2bcb3b3 100644 --- a/submodules/TelegramUI/TelegramUI/TelegramRootController.swift +++ b/submodules/TelegramUI/TelegramUI/TelegramRootController.swift @@ -32,7 +32,7 @@ public final class TelegramRootController: NavigationController { let image = generateTintedImage(image: UIImage(bundleImageName: "Chat List/EmptyMasterDetailIcon"), color: presentationData.theme.chatList.messageTextColor.withAlphaComponent(0.2)) navigationDetailsBackgroundMode = image != nil ? .image(image!) : nil default: - let image = chatControllerBackgroundImage(wallpaper: presentationData.chatWallpaper, mediaBox: context.account.postbox.mediaBox) + let image = chatControllerBackgroundImage(theme: presentationData.theme, wallpaper: presentationData.chatWallpaper, mediaBox: context.account.postbox.mediaBox, knockoutMode: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper) navigationDetailsBackgroundMode = image != nil ? .wallpaper(image!) : nil } @@ -49,7 +49,7 @@ public final class TelegramRootController: NavigationController { let image = generateTintedImage(image: UIImage(bundleImageName: "Chat List/EmptyMasterDetailIcon"), color: presentationData.theme.chatList.messageTextColor.withAlphaComponent(0.2)) navigationDetailsBackgroundMode = image != nil ? .image(image!) : nil default: - let image = chatControllerBackgroundImage(wallpaper: presentationData.chatWallpaper, mediaBox: strongSelf.context.account.postbox.mediaBox) + let image = chatControllerBackgroundImage(theme: presentationData.theme, wallpaper: presentationData.chatWallpaper, mediaBox: strongSelf.context.account.postbox.mediaBox, knockoutMode: strongSelf.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper) navigationDetailsBackgroundMode = image != nil ? .wallpaper(image!) : nil } strongSelf.updateBackgroundDetailsMode(navigationDetailsBackgroundMode, transition: .immediate) diff --git a/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift b/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift index bd134dca16..2400f55441 100644 --- a/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift @@ -246,6 +246,7 @@ class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { for itemNode in messageNodes { transition.updateFrame(node: itemNode, frame: CGRect(origin: CGPoint(x: 0.0, y: bottomOffset - itemNode.frame.height), size: itemNode.frame.size)) bottomOffset -= itemNode.frame.height + itemNode.updateFrame(itemNode.frame, within: layout.size) } } } diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift index 2158476426..8a61652829 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift @@ -113,7 +113,7 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { return { item, params, neighbors in var updatedBackgroundImage: UIImage? if currentItem?.wallpaper != item.wallpaper { - updatedBackgroundImage = chatControllerBackgroundImage(wallpaper: item.wallpaper, mediaBox: item.context.sharedContext.accountManager.mediaBox) + updatedBackgroundImage = chatControllerBackgroundImage(theme: item.theme, wallpaper: item.wallpaper, mediaBox: item.context.sharedContext.accountManager.mediaBox, knockoutMode: item.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper) } let insets: UIEdgeInsets @@ -146,7 +146,7 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { apply(ListViewItemApply(isOnScreen: true)) }) } else { - item1.nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: false, previousItem: nil, nextItem: nil, completion: { node, apply in + item1.nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: true, previousItem: nil, nextItem: nil, completion: { node, apply in node1 = node apply().1(ListViewItemApply(isOnScreen: true)) }) @@ -165,7 +165,7 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { apply(ListViewItemApply(isOnScreen: true)) }) } else { - item2.nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: false, previousItem: nil, nextItem: nil, completion: { node, apply in + item2.nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: true, previousItem: nil, nextItem: nil, completion: { node, apply in node2 = node apply().1(ListViewItemApply(isOnScreen: true)) }) @@ -195,7 +195,7 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { if node1.supernode == nil { strongSelf.containerNode.addSubnode(node1) } - node1.frame = CGRect(origin: CGPoint(x: 0.0, y: topOffset), size: node1.frame.size) + node1.updateFrame(CGRect(origin: CGPoint(x: 0.0, y: topOffset), size: node1.frame.size), within: layoutSize) topOffset += node1.frame.size.height } @@ -204,7 +204,7 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { if node2.supernode == nil { strongSelf.containerNode.addSubnode(node2) } - node2.frame = CGRect(origin: CGPoint(x: 0.0, y: topOffset), size: node2.frame.size) + node2.updateFrame(CGRect(origin: CGPoint(x: 0.0, y: topOffset), size: node2.frame.size), within: layoutSize) topOffset += node2.frame.size.height } diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift index e6aa815880..ca975109b0 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift @@ -380,7 +380,7 @@ public func themeSettingsController(context: AccountContextImpl, focusOnItemTag: chatWallpaper = themeSpecificWallpaper } else { let accentColor = current.themeSpecificAccentColors[theme.index]?.color - let theme = makePresentationTheme(themeReference: theme, accentColor: accentColor, serviceBackgroundColor: defaultServiceBackgroundColor) + let theme = makePresentationTheme(themeReference: theme, accentColor: accentColor, serviceBackgroundColor: defaultServiceBackgroundColor, baseColor: current.themeSpecificAccentColors[theme.index]?.baseColor ?? .blue) chatWallpaper = theme.chat.defaultWallpaper } @@ -400,7 +400,7 @@ public func themeSettingsController(context: AccountContextImpl, focusOnItemTag: var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers - let theme = makePresentationTheme(themeReference: current.theme, accentColor: color.color, serviceBackgroundColor: defaultServiceBackgroundColor) + let theme = makePresentationTheme(themeReference: current.theme, accentColor: color.color, serviceBackgroundColor: defaultServiceBackgroundColor, baseColor: color.baseColor) var chatWallpaper = current.chatWallpaper if let wallpaper = current.themeSpecificChatWallpapers[current.theme.index], wallpaper.hasWallpaper { } else { @@ -432,7 +432,7 @@ public func themeSettingsController(context: AccountContextImpl, focusOnItemTag: }) }) - let signal = combineLatest(context.sharedContext.presentationData |> deliverOnMainQueue, context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings]) |> deliverOnMainQueue, availableAppIcons, currentAppIconName.get() |> deliverOnMainQueue, statePromise.get() |> deliverOnMainQueue) + let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings]), availableAppIcons, currentAppIconName.get(), statePromise.get()) |> map { presentationData, sharedData, availableAppIcons, currentAppIconName, state -> (ItemListControllerState, (ItemListNodeState, ThemeSettingsControllerEntry.ItemGenerationArguments)) in let settings = (sharedData.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings] as? PresentationThemeSettings) ?? PresentationThemeSettings.defaultSettings @@ -442,7 +442,7 @@ public func themeSettingsController(context: AccountContextImpl, focusOnItemTag: let disableAnimations = presentationData.disableAnimations let accentColor = settings.themeSpecificAccentColors[settings.theme.index]?.color - let theme = makePresentationTheme(themeReference: settings.theme, accentColor: accentColor, serviceBackgroundColor: defaultServiceBackgroundColor, preview: true) + let theme = makePresentationTheme(themeReference: settings.theme, accentColor: accentColor, serviceBackgroundColor: defaultServiceBackgroundColor, baseColor: settings.themeSpecificAccentColors[settings.theme.index]?.baseColor ?? .blue, preview: true) let wallpaper: TelegramWallpaper if let themeSpecificWallpaper = settings.themeSpecificChatWallpapers[settings.theme.index] { @@ -458,6 +458,7 @@ public func themeSettingsController(context: AccountContextImpl, focusOnItemTag: } let controller = ItemListController(context: context, state: signal) + controller.alwaysSynchronous = true pushControllerImpl = { [weak controller] c in (controller?.navigationController as? NavigationController)?.pushViewController(c) } diff --git a/submodules/TelegramUI/TelegramUI/UpgradedAccounts.swift b/submodules/TelegramUI/TelegramUI/UpgradedAccounts.swift index 956a8d2920..f70b37718e 100644 --- a/submodules/TelegramUI/TelegramUI/UpgradedAccounts.swift +++ b/submodules/TelegramUI/TelegramUI/UpgradedAccounts.swift @@ -4,6 +4,7 @@ import TelegramCore import Postbox import SwiftSignalKit import TelegramUIPreferences +import MediaResources private enum LegacyPreferencesKeyValues: Int32 { case cacheStorageSettings = 1 diff --git a/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift b/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift index 14b4ddf812..f0941fca9f 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift @@ -9,6 +9,7 @@ import TelegramCore import Photos import TelegramPresentationData import TelegramUIPreferences +import MediaResources enum WallpaperListType { case wallpapers(WallpaperPresentationOptions?) @@ -655,6 +656,7 @@ class WallpaperGalleryController: ViewController { for itemNode in messageNodes { transition.updateFrame(node: itemNode, frame: CGRect(origin: CGPoint(x: 0.0, y: bottomOffset - itemNode.frame.height), size: itemNode.frame.size)) bottomOffset -= itemNode.frame.height + itemNode.updateFrame(itemNode.frame, within: layout.size) } } } diff --git a/submodules/TelegramUI/TelegramUI/WallpaperGalleryItem.swift b/submodules/TelegramUI/TelegramUI/WallpaperGalleryItem.swift index 7565377a21..8232abaa2b 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperGalleryItem.swift @@ -9,6 +9,7 @@ import LegacyComponents import TelegramPresentationData import TelegramUIPreferences import ProgressNavigationButtonNode +import MediaResources struct WallpaperGalleryItemArguments { let colorPreview: Bool diff --git a/submodules/TelegramUI/TelegramUI/WallpaperResources.swift b/submodules/TelegramUI/TelegramUI/WallpaperResources.swift index 1f530a7216..29c35e580a 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperResources.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperResources.swift @@ -5,6 +5,7 @@ import Display import Postbox import TelegramCore import TelegramUIPrivateModule +import MediaResources private func wallpaperDatas(account: Account, accountManager: AccountManager, fileReference: FileMediaReference? = nil, representations: [ImageRepresentationWithReference], alwaysShowThumbnailFirst: Bool = false, thumbnail: Bool = false, autoFetchFullSize: Bool = false, synchronousLoad: Bool = false) -> Signal<(Data?, Data?, Bool), NoError> { if let smallestRepresentation = smallestImageRepresentation(representations.map({ $0.representation })), let largestRepresentation = largestImageRepresentation(representations.map({ $0.representation })), let smallestIndex = representations.index(where: { $0.representation == smallestRepresentation }), let largestIndex = representations.index(where: { $0.representation == largestRepresentation }) { diff --git a/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift b/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift index 390e4badb7..f4421aeb02 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift @@ -5,6 +5,7 @@ import TelegramCore import SwiftSignalKit import TelegramPresentationData import TelegramUIPreferences +import MediaResources private extension TelegramWallpaper { var mainResource: MediaResource? { diff --git a/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj index 1b1e4795e1..b627d18e37 100644 --- a/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj +++ b/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj @@ -359,7 +359,6 @@ D04281F1200E4084009DDE36 /* GroupInfoSearchNavigationContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281F0200E4084009DDE36 /* GroupInfoSearchNavigationContentNode.swift */; }; D04281F4200E5AB0009DDE36 /* ChatRecentActionsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281F3200E5AB0009DDE36 /* ChatRecentActionsController.swift */; }; D04281F6200E5AC2009DDE36 /* ChatRecentActionsControllerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281F5200E5AC2009DDE36 /* ChatRecentActionsControllerNode.swift */; }; - D04281F8200E5C17009DDE36 /* ChatControllerBackgroundNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281F7200E5C17009DDE36 /* ChatControllerBackgroundNode.swift */; }; D04281FA200E5CDC009DDE36 /* ChatRecentActionsControllerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281F9200E5CDC009DDE36 /* ChatRecentActionsControllerState.swift */; }; D04281FC200E61BC009DDE36 /* ChatRecentActionsInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281FB200E61BC009DDE36 /* ChatRecentActionsInteraction.swift */; }; D04281FE200E639A009DDE36 /* ChatRecentActionsTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281FD200E639A009DDE36 /* ChatRecentActionsTitleView.swift */; }; @@ -857,7 +856,6 @@ D0EC6D201EB9F58800EBF1C3 /* PeerAvatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F69CDE1D6B87D30046BCD6 /* PeerAvatar.swift */; }; D0EC6D221EB9F58800EBF1C3 /* PhotoResources.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F69E9F1D6B8E380046BCD6 /* PhotoResources.swift */; }; D0EC6D231EB9F58800EBF1C3 /* StickerResources.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F69EA01D6B8E380046BCD6 /* StickerResources.swift */; }; - D0EC6D241EB9F58800EBF1C3 /* CachedResourceRepresentations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06879541DB8F1FC00424BBD /* CachedResourceRepresentations.swift */; }; D0EC6D251EB9F58800EBF1C3 /* FetchCachedRepresentations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06879561DB8F22200424BBD /* FetchCachedRepresentations.swift */; }; D0EC6D261EB9F58800EBF1C3 /* TransformOutgoingMessageMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04662801E68BA64006FAFC4 /* TransformOutgoingMessageMedia.swift */; }; D0EC6D271EB9F58800EBF1C3 /* FetchResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3A8B51E83120A00B4C64C /* FetchResource.swift */; }; @@ -1190,6 +1188,7 @@ D0FA08C020483F9600DD23FC /* ExtractVideoData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA08BF20483F9600DD23FC /* ExtractVideoData.swift */; }; D0FA08C8204982DC00DD23FC /* ChatTextInputActionButtonsNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA08C7204982DC00DD23FC /* ChatTextInputActionButtonsNode.swift */; }; D0FA08CA2049BEAC00DD23FC /* ChatEmptyNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA08C92049BEAC00DD23FC /* ChatEmptyNode.swift */; }; + D0FAB13E22EBC25300D8BED2 /* ChatMessageBubbleBackdrop.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FAB13D22EBC25300D8BED2 /* ChatMessageBubbleBackdrop.swift */; }; D0FB87B21F7C4C19004DE005 /* FetchMediaUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FB87B11F7C4C19004DE005 /* FetchMediaUtils.swift */; }; D0FBE84F2273395C00B33B52 /* ChatListArchiveInfoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FBE84E2273395C00B33B52 /* ChatListArchiveInfoItem.swift */; }; D0FC194D201F82A000FEDBB2 /* OpenResolvedUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FC194C201F82A000FEDBB2 /* OpenResolvedUrl.swift */; }; @@ -1642,7 +1641,6 @@ D04281F0200E4084009DDE36 /* GroupInfoSearchNavigationContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupInfoSearchNavigationContentNode.swift; sourceTree = ""; }; D04281F3200E5AB0009DDE36 /* ChatRecentActionsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsController.swift; sourceTree = ""; }; D04281F5200E5AC2009DDE36 /* ChatRecentActionsControllerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsControllerNode.swift; sourceTree = ""; }; - D04281F7200E5C17009DDE36 /* ChatControllerBackgroundNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatControllerBackgroundNode.swift; sourceTree = ""; }; D04281F9200E5CDC009DDE36 /* ChatRecentActionsControllerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsControllerState.swift; sourceTree = ""; }; D04281FB200E61BC009DDE36 /* ChatRecentActionsInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsInteraction.swift; sourceTree = ""; }; D04281FD200E639A009DDE36 /* ChatRecentActionsTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsTitleView.swift; sourceTree = ""; }; @@ -1762,7 +1760,6 @@ D064EF861F69A06F00AC0398 /* MessageContentKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageContentKind.swift; sourceTree = ""; }; D0671F2C2145AB28000A8AE7 /* LegacyAvatarPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyAvatarPicker.swift; sourceTree = ""; }; D0684A031F6C3AD50059F570 /* ChatListTypingNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListTypingNode.swift; sourceTree = ""; }; - D06879541DB8F1FC00424BBD /* CachedResourceRepresentations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedResourceRepresentations.swift; sourceTree = ""; }; D06879561DB8F22200424BBD /* FetchCachedRepresentations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchCachedRepresentations.swift; sourceTree = ""; }; D06887EF1F72DEE6000AB936 /* ShareInputFieldNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareInputFieldNode.swift; sourceTree = ""; }; D069F5CF212700B90000565A /* StickerPanePeerSpecificSetupGridItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerPanePeerSpecificSetupGridItem.swift; sourceTree = ""; }; @@ -2418,6 +2415,7 @@ D0FA0AC01E7725AA005BB9B7 /* TwoStepVerificationResetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoStepVerificationResetController.swift; sourceTree = ""; }; D0FA0AC41E77431A005BB9B7 /* InstalledStickerPacksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstalledStickerPacksController.swift; sourceTree = ""; }; D0FA35001EA6127000E56FFA /* StorageUsageController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageUsageController.swift; sourceTree = ""; }; + D0FAB13D22EBC25300D8BED2 /* ChatMessageBubbleBackdrop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageBubbleBackdrop.swift; sourceTree = ""; }; D0FB87B11F7C4C19004DE005 /* FetchMediaUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchMediaUtils.swift; sourceTree = ""; }; D0FBE84E2273395C00B33B52 /* ChatListArchiveInfoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListArchiveInfoItem.swift; sourceTree = ""; }; D0FC194C201F82A000FEDBB2 /* OpenResolvedUrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenResolvedUrl.swift; sourceTree = ""; }; @@ -4569,7 +4567,6 @@ D0F69E0E1D6B8ACF0046BCD6 /* ChatController.swift */, D0F69E0F1D6B8ACF0046BCD6 /* ChatControllerInteraction.swift */, D0F69E101D6B8ACF0046BCD6 /* ChatControllerNode.swift */, - D04281F7200E5C17009DDE36 /* ChatControllerBackgroundNode.swift */, D0F69E111D6B8ACF0046BCD6 /* ChatHistoryEntry.swift */, D0F69E121D6B8ACF0046BCD6 /* ChatHistoryLocation.swift */, D0D268681D78865300C422DA /* ChatAvatarNavigationNode.swift */, @@ -4662,6 +4659,7 @@ D0AB262821C307D7008F6685 /* ChatMessagePollBubbleContentNode.swift */, 099529AF21D2123E00805E13 /* ChatMessageUnsupportedBubbleContentNode.swift */, D0439B5A228EC4A00067E026 /* ChatMessagePhoneNumberRequestContentNode.swift */, + D0FAB13D22EBC25300D8BED2 /* ChatMessageBubbleBackdrop.swift */, ); name = Items; sourceTree = ""; @@ -4847,7 +4845,6 @@ children = ( D0F69E9F1D6B8E380046BCD6 /* PhotoResources.swift */, D0F69EA01D6B8E380046BCD6 /* StickerResources.swift */, - D06879541DB8F1FC00424BBD /* CachedResourceRepresentations.swift */, D06879561DB8F22200424BBD /* FetchCachedRepresentations.swift */, D04662801E68BA64006FAFC4 /* TransformOutgoingMessageMedia.swift */, D0F3A8B51E83120A00B4C64C /* FetchResource.swift */, @@ -5459,7 +5456,6 @@ D0F760DD222034980074F7E5 /* ChannelStatsControllerNode.swift in Sources */, D0EC6D231EB9F58800EBF1C3 /* StickerResources.swift in Sources */, 09C9EA3821A044B500E90146 /* StringForDuration.swift in Sources */, - D0EC6D241EB9F58800EBF1C3 /* CachedResourceRepresentations.swift in Sources */, 09619B8E21A34C0100493558 /* InstantPageScrollableNode.swift in Sources */, D01590A622BD460C0017C33E /* MetalAnimationRenderer.swift in Sources */, D01BAA201ECC9A2500295217 /* CallListNodeLocation.swift in Sources */, @@ -6131,7 +6127,6 @@ D0EC6E5C1EB9F58900EBF1C3 /* CallControllerNode.swift in Sources */, D0F4B0222110972300912B92 /* ContactInfoStrings.swift in Sources */, D0EC6E5D1EB9F58900EBF1C3 /* PrivacyAndSecurityController.swift in Sources */, - D04281F8200E5C17009DDE36 /* ChatControllerBackgroundNode.swift in Sources */, D0EC6E5E1EB9F58900EBF1C3 /* ItemListRecentSessionItem.swift in Sources */, D00ADFDD1EBB73C200873D2E /* OverlayMediaManager.swift in Sources */, D056CD7C1FF3E92C00880D28 /* DirectionalPanGestureRecognizer.swift in Sources */, @@ -6170,6 +6165,7 @@ D0EC6E741EB9F58900EBF1C3 /* ThemeGridController.swift in Sources */, D0EC6E751EB9F58900EBF1C3 /* ThemeGridControllerNode.swift in Sources */, D0EC6E761EB9F58900EBF1C3 /* SettingsController.swift in Sources */, + D0FAB13E22EBC25300D8BED2 /* ChatMessageBubbleBackdrop.swift in Sources */, D0EC6E771EB9F58900EBF1C3 /* NotificationsAndSounds.swift in Sources */, D0EC6E781EB9F58900EBF1C3 /* NotificationSoundSelection.swift in Sources */, D056CD741FF2996B00880D28 /* ExternalMusicAlbumArtResources.swift in Sources */, diff --git a/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift b/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift index 37d8e96724..749762a50a 100644 --- a/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift +++ b/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift @@ -7,16 +7,18 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry { public var skipReadHistory: Bool public var crashOnLongQueries: Bool public var chatListPhotos: Bool + public var knockoutWallpaper: Bool public static var defaultSettings: ExperimentalUISettings { - return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false) + return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false, knockoutWallpaper: false) } - public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool) { + public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool, knockoutWallpaper: Bool) { self.keepChatNavigationStack = keepChatNavigationStack self.skipReadHistory = skipReadHistory self.crashOnLongQueries = crashOnLongQueries self.chatListPhotos = chatListPhotos + self.knockoutWallpaper = knockoutWallpaper } public init(decoder: PostboxDecoder) { @@ -24,6 +26,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry { self.skipReadHistory = decoder.decodeInt32ForKey("skipReadHistory", orElse: 0) != 0 self.crashOnLongQueries = decoder.decodeInt32ForKey("crashOnLongQueries", orElse: 0) != 0 self.chatListPhotos = decoder.decodeInt32ForKey("chatListPhotos", orElse: 0) != 0 + self.knockoutWallpaper = decoder.decodeInt32ForKey("knockoutWallpaper", orElse: 0) != 0 } public func encode(_ encoder: PostboxEncoder) { @@ -31,6 +34,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry { encoder.encodeInt32(self.skipReadHistory ? 1 : 0, forKey: "skipReadHistory") encoder.encodeInt32(self.crashOnLongQueries ? 1 : 0, forKey: "crashOnLongQueries") encoder.encodeInt32(self.chatListPhotos ? 1 : 0, forKey: "chatListPhotos") + encoder.encodeInt32(self.knockoutWallpaper ? 1 : 0, forKey: "knockoutWallpaper") } public func isEqual(to: PreferencesEntry) -> Bool { diff --git a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift index 1d63717c6e..920fe9abf5 100644 --- a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift @@ -207,6 +207,33 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable { return UIColor(rgb: value) } + public var outgoingGradientColors: (UIColor, UIColor) { + switch self { + case .blue: + return (UIColor(rgb: 0x63BFFB), UIColor(rgb: 0x007AFF)) + case .cyan: + return (UIColor(rgb: 0x5CE0E9), UIColor(rgb: 0x00C2ED)) + case .green: + return (UIColor(rgb: 0x93D374), UIColor(rgb: 0x29B327)) + case .pink: + return (UIColor(rgb: 0xE296C1), UIColor(rgb: 0xEB6CA4)) + case .orange: + return (UIColor(rgb: 0xF2A451), UIColor(rgb: 0xF08200)) + case .purple: + return (UIColor(rgb: 0xAC98E6), UIColor(rgb: 0x9472EE)) + case .red: + return (UIColor(rgb: 0xE06D54), UIColor(rgb: 0xD33213)) + case .yellow: + return (UIColor(rgb: 0xF7DA6B), UIColor(rgb: 0xEDB400)) + case .gray: + return (UIColor(rgb: 0x7D8E9A), UIColor(rgb: 0x6D839E)) + case .black: + return (UIColor(rgb: 0x000000), UIColor(rgb: 0x000000)) + case .white: + return (UIColor(rgb: 0xffffff), UIColor(rgb: 0xffffff)) + } + } + public var edgeColors: (UIColor, UIColor) { let values: (UIColor, UIColor) switch self {