Merge branch 'gradient-messages'

This commit is contained in:
Peter 2019-08-03 01:45:55 +03:00
commit 90dc0cf373
76 changed files with 1707 additions and 783 deletions

View File

@ -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>

View File

@ -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)"

View File

@ -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 */,

View File

@ -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

View File

@ -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 */,

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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) {
}
}

View File

@ -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

View File

@ -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?

View 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>

View File

@ -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 */;
}

View File

@ -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

View 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>

View File

@ -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()
}
}

View File

@ -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()
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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)!

View File

@ -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
}

View File

@ -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 */,

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)?

View File

@ -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

View File

@ -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))
}
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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))

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)?

View File

@ -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
}

View File

@ -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)

View File

@ -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 {

View File

@ -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) {

View File

@ -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)

View File

@ -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 }

View File

@ -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))

View File

@ -9,6 +9,7 @@ import WebPImage
#else
import WebP
#endif
import MediaResources
public struct EmojiThumbnailResourceId: MediaResourceId {
public let emoji: String

View File

@ -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 {

View File

@ -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
}

View File

@ -5,7 +5,7 @@ import TelegramCore
import Postbox
import SwiftSignalKit
import TelegramPresentationData
import MediaResources
import LegacyComponents
final class InstantVideoControllerRecordingStatus {

View File

@ -8,6 +8,7 @@ import TelegramPresentationData
import TelegramUIPreferences
import DeviceAccess
import ItemListUI
import AccountContext
private final class NotificationsAndSoundsArguments {
let context: AccountContextImpl

View File

@ -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))
}
}

View File

@ -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)

View File

@ -3,6 +3,7 @@ import SwiftSignalKit
import Postbox
import TelegramCore
import DeviceAccess
import AccountContext
public enum PermissionKind: Int32 {
case contacts

View File

@ -13,6 +13,7 @@ import WebPImage
import WebP
#endif
import TelegramUIPreferences
import MediaResources
private enum ResourceFileData {
case data(Data)

View File

@ -15,6 +15,7 @@ import TelegramPresentationData
import TelegramUIPreferences
import DeviceAccess
import ItemListUI
import AccountContext
private let maximumNumberOfAccounts = 3

View File

@ -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

View File

@ -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)

View File

@ -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)
}
}
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -4,6 +4,7 @@ import TelegramCore
import Postbox
import SwiftSignalKit
import TelegramUIPreferences
import MediaResources
private enum LegacyPreferencesKeyValues: Int32 {
case cacheStorageSettings = 1

View File

@ -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)
}
}
}

View File

@ -9,6 +9,7 @@ import LegacyComponents
import TelegramPresentationData
import TelegramUIPreferences
import ProgressNavigationButtonNode
import MediaResources
struct WallpaperGalleryItemArguments {
let colorPreview: Bool

View File

@ -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 }) {

View File

@ -5,6 +5,7 @@ import TelegramCore
import SwiftSignalKit
import TelegramPresentationData
import TelegramUIPreferences
import MediaResources
private extension TelegramWallpaper {
var mainResource: MediaResource? {

View File

@ -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 */,

View File

@ -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 {

View File

@ -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 {