mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-31 07:30:40 +00:00
Merge branch 'gradient-messages'
This commit is contained in:
commit
90dc0cf373
@ -75,6 +75,9 @@
|
||||
<Group
|
||||
location = "container:"
|
||||
name = "UI Components">
|
||||
<FileRef
|
||||
location = "group:/Users/peter/build/telegram-temp/telegram-ios/submodules/MediaResources/MediaResources_Xcode.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:submodules/CheckNode/CheckNode_Xcode.xcodeproj">
|
||||
</FileRef>
|
||||
|
@ -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)"
|
||||
|
||||
|
@ -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 */,
|
||||
|
@ -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
|
||||
|
@ -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 = "<group>"; };
|
||||
D0AE31FD22B281300058D3BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@ -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 */,
|
||||
|
@ -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<Bool?>(value: nil)
|
||||
|
||||
public func shouldDisplayNotificationsPermissionWarning(status: AccessType, suppressed: Bool) -> Bool {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
@ -147,6 +147,14 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
|
||||
}
|
||||
}
|
||||
|
||||
public var alwaysSynchronous = false {
|
||||
didSet {
|
||||
if self.isNodeLoaded {
|
||||
(self.displayNode as! ItemListControllerNode<Entry>).alwaysSynchronous = self.alwaysSynchronous
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries<Entry>) -> Void)? {
|
||||
didSet {
|
||||
if self.isNodeLoaded {
|
||||
@ -413,6 +421,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: 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
|
||||
|
@ -196,6 +196,8 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
|
||||
didSet {
|
||||
}
|
||||
}
|
||||
|
||||
var alwaysSynchronous = false
|
||||
|
||||
public init(controller: ItemListController<Entry>?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, state: Signal<(PresentationTheme, (ItemListNodeState<Entry>, Entry.ItemGenerationArguments)), NoError>) {
|
||||
self.navigationBar = navigationBar
|
||||
@ -439,6 +441,10 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: 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?
|
||||
|
22
submodules/MediaResources/Info.plist
Normal file
22
submodules/MediaResources/Info.plist
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
</dict>
|
||||
</plist>
|
@ -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 = "<group>"; };
|
||||
D084FA0122F435FD004874CE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
D084FA0C22F436C9004874CE /* CachedResourceRepresentations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedResourceRepresentations.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>";
|
||||
};
|
||||
D084F9FE22F435FD004874CE /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D084F9FD22F435FD004874CE /* MediaResources.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D084F9FF22F435FD004874CE /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D084FA0C22F436C9004874CE /* CachedResourceRepresentations.swift */,
|
||||
D084FA0022F435FD004874CE /* MediaResources.h */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D084FA0E22F436D2004874CE /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D084FA1522F436DE004874CE /* SwiftSignalKit.framework */,
|
||||
D084FA1322F436DA004874CE /* Postbox.framework */,
|
||||
D084FA1122F436D6004874CE /* Foundation.framework */,
|
||||
D084FA0F22F436D3004874CE /* UIKit.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* 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 */;
|
||||
}
|
@ -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
|
19
submodules/MediaResources/Sources/MediaResources.h
Normal file
19
submodules/MediaResources/Sources/MediaResources.h
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// MediaResources.h
|
||||
// MediaResources
|
||||
//
|
||||
// Created by Peter on 8/2/19.
|
||||
// Copyright © 2019 Telegram Messenger LLP. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
//! 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 <MediaResources/PublicHeader.h>
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)!
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 = "<group>"; };
|
||||
D06017F622F35A9200796784 /* ChatMessageBubbleImages.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageBubbleImages.swift; sourceTree = "<group>"; };
|
||||
D06017F822F35ACF00796784 /* WallpaperUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WallpaperUtils.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
D0AE31AA22B273F20058D3BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@ -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 */,
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)?
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)?
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||
|
@ -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)
|
||||
|
@ -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 }
|
||||
|
@ -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))
|
||||
|
||||
|
@ -9,6 +9,7 @@ import WebPImage
|
||||
#else
|
||||
import WebP
|
||||
#endif
|
||||
import MediaResources
|
||||
|
||||
public struct EmojiThumbnailResourceId: MediaResourceId {
|
||||
public let emoji: String
|
||||
|
@ -14,6 +14,7 @@ import WebP
|
||||
#endif
|
||||
import Lottie
|
||||
import TelegramUIPrivateModule
|
||||
import MediaResources
|
||||
|
||||
public func fetchCachedResourceRepresentation(account: Account, resource: MediaResource, representation: CachedMediaResourceRepresentation) -> Signal<CachedMediaResourceRepresentationResult, NoError> {
|
||||
if let representation = representation as? CachedStickerAJpegRepresentation {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ import TelegramCore
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
|
||||
import MediaResources
|
||||
import LegacyComponents
|
||||
|
||||
final class InstantVideoControllerRecordingStatus {
|
||||
|
@ -8,6 +8,7 @@ import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import DeviceAccess
|
||||
import ItemListUI
|
||||
import AccountContext
|
||||
|
||||
private final class NotificationsAndSoundsArguments {
|
||||
let context: AccountContextImpl
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -3,6 +3,7 @@ import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import DeviceAccess
|
||||
import AccountContext
|
||||
|
||||
public enum PermissionKind: Int32 {
|
||||
case contacts
|
||||
|
@ -13,6 +13,7 @@ import WebPImage
|
||||
import WebP
|
||||
#endif
|
||||
import TelegramUIPreferences
|
||||
import MediaResources
|
||||
|
||||
private enum ResourceFileData {
|
||||
case data(Data)
|
||||
|
Binary file not shown.
@ -15,6 +15,7 @@ import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import DeviceAccess
|
||||
import ItemListUI
|
||||
import AccountContext
|
||||
|
||||
private let maximumNumberOfAccounts = 3
|
||||
|
||||
|
@ -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<UInt8>) -> (Data, Data)? in
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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>, 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)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import TelegramCore
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramUIPreferences
|
||||
import MediaResources
|
||||
|
||||
private enum LegacyPreferencesKeyValues: Int32 {
|
||||
case cacheStorageSettings = 1
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import LegacyComponents
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import ProgressNavigationButtonNode
|
||||
import MediaResources
|
||||
|
||||
struct WallpaperGalleryItemArguments {
|
||||
let colorPreview: Bool
|
||||
|
@ -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 }) {
|
||||
|
@ -5,6 +5,7 @@ import TelegramCore
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import MediaResources
|
||||
|
||||
private extension TelegramWallpaper {
|
||||
var mainResource: MediaResource? {
|
||||
|
@ -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 = "<group>"; };
|
||||
D04281F3200E5AB0009DDE36 /* ChatRecentActionsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsController.swift; sourceTree = "<group>"; };
|
||||
D04281F5200E5AC2009DDE36 /* ChatRecentActionsControllerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsControllerNode.swift; sourceTree = "<group>"; };
|
||||
D04281F7200E5C17009DDE36 /* ChatControllerBackgroundNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatControllerBackgroundNode.swift; sourceTree = "<group>"; };
|
||||
D04281F9200E5CDC009DDE36 /* ChatRecentActionsControllerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsControllerState.swift; sourceTree = "<group>"; };
|
||||
D04281FB200E61BC009DDE36 /* ChatRecentActionsInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsInteraction.swift; sourceTree = "<group>"; };
|
||||
D04281FD200E639A009DDE36 /* ChatRecentActionsTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsTitleView.swift; sourceTree = "<group>"; };
|
||||
@ -1762,7 +1760,6 @@
|
||||
D064EF861F69A06F00AC0398 /* MessageContentKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageContentKind.swift; sourceTree = "<group>"; };
|
||||
D0671F2C2145AB28000A8AE7 /* LegacyAvatarPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyAvatarPicker.swift; sourceTree = "<group>"; };
|
||||
D0684A031F6C3AD50059F570 /* ChatListTypingNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListTypingNode.swift; sourceTree = "<group>"; };
|
||||
D06879541DB8F1FC00424BBD /* CachedResourceRepresentations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedResourceRepresentations.swift; sourceTree = "<group>"; };
|
||||
D06879561DB8F22200424BBD /* FetchCachedRepresentations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchCachedRepresentations.swift; sourceTree = "<group>"; };
|
||||
D06887EF1F72DEE6000AB936 /* ShareInputFieldNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareInputFieldNode.swift; sourceTree = "<group>"; };
|
||||
D069F5CF212700B90000565A /* StickerPanePeerSpecificSetupGridItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerPanePeerSpecificSetupGridItem.swift; sourceTree = "<group>"; };
|
||||
@ -2418,6 +2415,7 @@
|
||||
D0FA0AC01E7725AA005BB9B7 /* TwoStepVerificationResetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoStepVerificationResetController.swift; sourceTree = "<group>"; };
|
||||
D0FA0AC41E77431A005BB9B7 /* InstalledStickerPacksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstalledStickerPacksController.swift; sourceTree = "<group>"; };
|
||||
D0FA35001EA6127000E56FFA /* StorageUsageController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageUsageController.swift; sourceTree = "<group>"; };
|
||||
D0FAB13D22EBC25300D8BED2 /* ChatMessageBubbleBackdrop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageBubbleBackdrop.swift; sourceTree = "<group>"; };
|
||||
D0FB87B11F7C4C19004DE005 /* FetchMediaUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchMediaUtils.swift; sourceTree = "<group>"; };
|
||||
D0FBE84E2273395C00B33B52 /* ChatListArchiveInfoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListArchiveInfoItem.swift; sourceTree = "<group>"; };
|
||||
D0FC194C201F82A000FEDBB2 /* OpenResolvedUrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenResolvedUrl.swift; sourceTree = "<group>"; };
|
||||
@ -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 = "<group>";
|
||||
@ -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 */,
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user