mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Added WebP decoding to notification service
This commit is contained in:
parent
9802f70a80
commit
10c86a102e
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -34,3 +34,6 @@ url=../ffmpeg.git
|
|||||||
[submodule "submodules/LegacyComponents"]
|
[submodule "submodules/LegacyComponents"]
|
||||||
path = submodules/LegacyComponents
|
path = submodules/LegacyComponents
|
||||||
url=../legacycomponents.git
|
url=../legacycomponents.git
|
||||||
|
[submodule "submodules/webp"]
|
||||||
|
path = submodules/webp
|
||||||
|
url=../webp.git
|
||||||
|
@ -44,7 +44,7 @@ private func parseFileLocationResource(_ dict: [AnyHashable: Any]) -> TelegramMe
|
|||||||
|
|
||||||
class NotificationViewController: UIViewController, UNNotificationContentExtension {
|
class NotificationViewController: UIViewController, UNNotificationContentExtension {
|
||||||
private let imageNode = TransformImageNode()
|
private let imageNode = TransformImageNode()
|
||||||
private var imageDimensions: CGSize?
|
private var imageInfo: (isSticker: Bool, dimensions: CGSize)?
|
||||||
|
|
||||||
private let applyDisposable = MetaDisposable()
|
private let applyDisposable = MetaDisposable()
|
||||||
private let fetchedDisposable = MetaDisposable()
|
private let fetchedDisposable = MetaDisposable()
|
||||||
@ -147,7 +147,7 @@ class NotificationViewController: UIViewController, UNNotificationContentExtensi
|
|||||||
self.view.frame = CGRect(origin: self.view.frame.origin, size: fittedSize)
|
self.view.frame = CGRect(origin: self.view.frame.origin, size: fittedSize)
|
||||||
self.preferredContentSize = fittedSize
|
self.preferredContentSize = fittedSize
|
||||||
|
|
||||||
self.imageDimensions = dimensions
|
self.imageInfo = (false, dimensions)
|
||||||
self.updateImageLayout(boundingSize: self.view.bounds.size)
|
self.updateImageLayout(boundingSize: self.view.bounds.size)
|
||||||
|
|
||||||
let mediaBoxPath = accountsPath + "/" + accountRecordIdPathName(AccountRecordId(rawValue: accountIdValue)) + "/postbox/media"
|
let mediaBoxPath = accountsPath + "/" + accountRecordIdPathName(AccountRecordId(rawValue: accountIdValue)) + "/postbox/media"
|
||||||
@ -211,10 +211,13 @@ class NotificationViewController: UIViewController, UNNotificationContentExtensi
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let fittedSize = dimensions.fitted(CGSize(width: min(300.0, self.view.bounds.width), height: 300.0))
|
let fittedSize = dimensions.fitted(CGSize(width: min(256.0, self.view.bounds.width), height: 256.0))
|
||||||
self.view.frame = CGRect(origin: self.view.frame.origin, size: fittedSize)
|
self.view.frame = CGRect(origin: self.view.frame.origin, size: fittedSize)
|
||||||
self.preferredContentSize = fittedSize
|
self.preferredContentSize = fittedSize
|
||||||
|
|
||||||
|
self.imageInfo = (true, dimensions)
|
||||||
|
self.updateImageLayout(boundingSize: self.view.bounds.size)
|
||||||
|
|
||||||
self.applyDisposable.set((sharedAccountContext.activeAccounts
|
self.applyDisposable.set((sharedAccountContext.activeAccounts
|
||||||
|> map { _, accounts, _ -> Account? in
|
|> map { _, accounts, _ -> Account? in
|
||||||
return accounts.first(where: { $0.0 == AccountRecordId(rawValue: accountIdValue) })?.1
|
return accounts.first(where: { $0.0 == AccountRecordId(rawValue: accountIdValue) })?.1
|
||||||
@ -267,12 +270,18 @@ class NotificationViewController: UIViewController, UNNotificationContentExtensi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func updateImageLayout(boundingSize: CGSize) {
|
private func updateImageLayout(boundingSize: CGSize) {
|
||||||
if let imageDimensions = self.imageDimensions {
|
if let (isSticker, dimensions) = self.imageInfo {
|
||||||
let makeLayout = self.imageNode.asyncLayout()
|
let makeLayout = self.imageNode.asyncLayout()
|
||||||
let fittedSize = imageDimensions.fitted(CGSize(width: boundingSize.width, height: 1000.0))
|
let fittedSize: CGSize
|
||||||
|
if isSticker {
|
||||||
|
fittedSize = dimensions.fitted(CGSize(width: min(256.0, boundingSize.width), height: 256.0))
|
||||||
|
} else {
|
||||||
|
fittedSize = dimensions.fitted(CGSize(width: boundingSize.width, height: 1000.0))
|
||||||
|
}
|
||||||
let apply = makeLayout(TransformImageArguments(corners: ImageCorners(radius: 0.0), imageSize: fittedSize, boundingSize: fittedSize, intrinsicInsets: UIEdgeInsets()))
|
let apply = makeLayout(TransformImageArguments(corners: ImageCorners(radius: 0.0), imageSize: fittedSize, boundingSize: fittedSize, intrinsicInsets: UIEdgeInsets()))
|
||||||
apply()
|
apply()
|
||||||
self.imageNode.frame = CGRect(origin: CGPoint(), size: boundingSize)
|
let displaySize = isSticker ? fittedSize : boundingSize
|
||||||
|
self.imageNode.frame = CGRect(origin: CGPoint(x: floor((boundingSize.width - displaySize.width) / 2.0), y: 0.0), size: displaySize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import UserNotifications
|
import UserNotifications
|
||||||
import MtProtoKitDynamic
|
import MtProtoKitDynamic
|
||||||
|
import WebP
|
||||||
|
|
||||||
private var sharedLogger: Logger?
|
private var sharedLogger: Logger?
|
||||||
|
|
||||||
@ -324,7 +325,7 @@ class NotificationService: UNNotificationServiceExtension {
|
|||||||
let imagesPath = NSTemporaryDirectory() + "aps-data"
|
let imagesPath = NSTemporaryDirectory() + "aps-data"
|
||||||
let _ = try? FileManager.default.createDirectory(atPath: imagesPath, withIntermediateDirectories: true, attributes: nil)
|
let _ = try? FileManager.default.createDirectory(atPath: imagesPath, withIntermediateDirectories: true, attributes: nil)
|
||||||
|
|
||||||
let accountBasePath = rootPath + "account-\(UInt64(bitPattern: account.id))"
|
let accountBasePath = rootPath + "/account-\(UInt64(bitPattern: account.id))"
|
||||||
|
|
||||||
let mediaBoxPath = accountBasePath + "/postbox/media"
|
let mediaBoxPath = accountBasePath + "/postbox/media"
|
||||||
|
|
||||||
@ -333,6 +334,7 @@ class NotificationService: UNNotificationServiceExtension {
|
|||||||
|
|
||||||
var inputFileLocation: (Int32, Api.InputFileLocation)?
|
var inputFileLocation: (Int32, Api.InputFileLocation)?
|
||||||
var fetchResourceId: String?
|
var fetchResourceId: String?
|
||||||
|
var isPng = false
|
||||||
|
|
||||||
if let attachment = attachment {
|
if let attachment = attachment {
|
||||||
switch attachment {
|
switch attachment {
|
||||||
@ -356,14 +358,26 @@ class NotificationService: UNNotificationServiceExtension {
|
|||||||
}
|
}
|
||||||
case let .document(document):
|
case let .document(document):
|
||||||
switch document {
|
switch document {
|
||||||
case let .document(_, id, accessHash, fileReference, _, _, _, thumbs, dcId, _):
|
case let .document(_, id, accessHash, fileReference, _, _, _, thumbs, dcId, attributes):
|
||||||
|
var isSticker = false
|
||||||
|
for attribute in attributes {
|
||||||
|
switch attribute {
|
||||||
|
case .documentAttributeSticker:
|
||||||
|
isSticker = true
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
if let thumbs = thumbs {
|
if let thumbs = thumbs {
|
||||||
loop: for size in thumbs {
|
loop: for size in thumbs {
|
||||||
switch size {
|
switch size {
|
||||||
case let .photoSize(type, _, _, _, _):
|
case let .photoSize(type, _, _, _, _):
|
||||||
if type == "m" {
|
if (isSticker && type == "s") || type == "m" {
|
||||||
|
if isSticker {
|
||||||
|
isPng = true
|
||||||
|
}
|
||||||
inputFileLocation = (dcId, .inputDocumentFileLocation(id: id, accessHash: accessHash, fileReference: fileReference, thumbSize: type))
|
inputFileLocation = (dcId, .inputDocumentFileLocation(id: id, accessHash: accessHash, fileReference: fileReference, thumbSize: type))
|
||||||
fetchResourceId = "telegram-cloud-photo-size-\(dcId)-\(id)-\(type)"
|
fetchResourceId = "telegram-cloud-document-size-\(dcId)-\(id)-\(type)"
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -376,8 +390,8 @@ class NotificationService: UNNotificationServiceExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let fetchResourceId = fetchResourceId {
|
if let fetchResourceId = fetchResourceId {
|
||||||
tempImagePath = imagesPath + "/\(fetchResourceId).jpg"
|
tempImagePath = imagesPath + "/\(fetchResourceId).\(isPng ? "png" : "jpg")"
|
||||||
mediaBoxThumbnailImagePath = mediaBoxPath + "/\(fetchResourceId).jpg"
|
mediaBoxThumbnailImagePath = mediaBoxPath + "/\(fetchResourceId)"
|
||||||
}
|
}
|
||||||
|
|
||||||
if let aps = dict["aps"] as? [AnyHashable: Any] {
|
if let aps = dict["aps"] as? [AnyHashable: Any] {
|
||||||
@ -424,26 +438,49 @@ class NotificationService: UNNotificationServiceExtension {
|
|||||||
|
|
||||||
self.cancelFetch?()
|
self.cancelFetch?()
|
||||||
if let mediaBoxThumbnailImagePath = mediaBoxThumbnailImagePath, let tempImagePath = tempImagePath, let (datacenterId, inputFileLocation) = inputFileLocation {
|
if let mediaBoxThumbnailImagePath = mediaBoxThumbnailImagePath, let tempImagePath = tempImagePath, let (datacenterId, inputFileLocation) = inputFileLocation {
|
||||||
self.cancelFetch = fetchImageWithAccount(proxyConnection: accountInfos.proxy, account: account, inputFileLocation: inputFileLocation, datacenterId: datacenterId, completion: { [weak self] data in
|
if let data = try? Data(contentsOf: URL(fileURLWithPath: mediaBoxThumbnailImagePath)) {
|
||||||
DispatchQueue.main.async {
|
var tempData = data
|
||||||
guard let strongSelf = self else {
|
if isPng {
|
||||||
return
|
if let image = WebP.convert(fromWebP: data), let imageData = image.pngData() {
|
||||||
}
|
tempData = imageData
|
||||||
strongSelf.cancelFetch?()
|
|
||||||
strongSelf.cancelFetch = nil
|
|
||||||
if let data = data {
|
|
||||||
let _ = try? data.write(to: URL(fileURLWithPath: mediaBoxThumbnailImagePath))
|
|
||||||
if let _ = try? data.write(to: URL(fileURLWithPath: tempImagePath)) {
|
|
||||||
if let attachment = try? UNNotificationAttachment(identifier: "image", url: URL(fileURLWithPath: tempImagePath)) {
|
|
||||||
strongSelf.bestAttemptContent?.attachments = [attachment]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let bestAttemptContent = strongSelf.bestAttemptContent {
|
|
||||||
contentHandler(bestAttemptContent)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
if let _ = try? tempData.write(to: URL(fileURLWithPath: tempImagePath)) {
|
||||||
|
if let attachment = try? UNNotificationAttachment(identifier: "image", url: URL(fileURLWithPath: tempImagePath)) {
|
||||||
|
self.bestAttemptContent?.attachments = [attachment]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let bestAttemptContent = self.bestAttemptContent {
|
||||||
|
contentHandler(bestAttemptContent)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.cancelFetch = fetchImageWithAccount(proxyConnection: accountInfos.proxy, account: account, inputFileLocation: inputFileLocation, datacenterId: datacenterId, completion: { [weak self] data in
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.cancelFetch?()
|
||||||
|
strongSelf.cancelFetch = nil
|
||||||
|
if let data = data {
|
||||||
|
let _ = try? data.write(to: URL(fileURLWithPath: mediaBoxThumbnailImagePath))
|
||||||
|
var tempData = data
|
||||||
|
if isPng {
|
||||||
|
if let image = WebP.convert(fromWebP: data), let imageData = image.pngData() {
|
||||||
|
tempData = imageData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let _ = try? tempData.write(to: URL(fileURLWithPath: tempImagePath)) {
|
||||||
|
if let attachment = try? UNNotificationAttachment(identifier: "image", url: URL(fileURLWithPath: tempImagePath)) {
|
||||||
|
strongSelf.bestAttemptContent?.attachments = [attachment]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let bestAttemptContent = strongSelf.bestAttemptContent {
|
||||||
|
contentHandler(bestAttemptContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let bestAttemptContent = self.bestAttemptContent {
|
if let bestAttemptContent = self.bestAttemptContent {
|
||||||
contentHandler(bestAttemptContent)
|
contentHandler(bestAttemptContent)
|
||||||
|
@ -225,6 +225,9 @@
|
|||||||
D00ED75D1FE95287001F38BD /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D00ED75B1FE95287001F38BD /* InfoPlist.strings */; };
|
D00ED75D1FE95287001F38BD /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D00ED75B1FE95287001F38BD /* InfoPlist.strings */; };
|
||||||
D015E011225CCEB300CB9E8A /* ReadBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015E010225CCEB300CB9E8A /* ReadBuffer.swift */; };
|
D015E011225CCEB300CB9E8A /* ReadBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015E010225CCEB300CB9E8A /* ReadBuffer.swift */; };
|
||||||
D015E01F225CDF5100CB9E8A /* Api0.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015E01E225CDF5000CB9E8A /* Api0.swift */; };
|
D015E01F225CDF5100CB9E8A /* Api0.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015E01E225CDF5000CB9E8A /* Api0.swift */; };
|
||||||
|
D015E04D225D2D8F00CB9E8A /* WebP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D015E04C225D2D8F00CB9E8A /* WebP.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||||
|
D015E050225D303F00CB9E8A /* WebP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D015E04C225D2D8F00CB9E8A /* WebP.framework */; };
|
||||||
|
D015E051225D303F00CB9E8A /* WebP.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D015E04C225D2D8F00CB9E8A /* WebP.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
D01A47551F4DBED700383CC1 /* HockeySDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D01A47541F4DBED700383CC1 /* HockeySDK.framework */; };
|
D01A47551F4DBED700383CC1 /* HockeySDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D01A47541F4DBED700383CC1 /* HockeySDK.framework */; };
|
||||||
D021D4D9219CAEDD0064BEBA /* Config-Fork.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = D021D4D8219CAEDD0064BEBA /* Config-Fork.xcconfig */; };
|
D021D4D9219CAEDD0064BEBA /* Config-Fork.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = D021D4D8219CAEDD0064BEBA /* Config-Fork.xcconfig */; };
|
||||||
D02CF5FD215D9ABF00E0F56A /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0AA1A671D568BA400152314 /* UserNotifications.framework */; };
|
D02CF5FD215D9ABF00E0F56A /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0AA1A671D568BA400152314 /* UserNotifications.framework */; };
|
||||||
@ -545,6 +548,7 @@
|
|||||||
D096C2C21CC3C104006D814E /* Postbox.framework in Embed Frameworks */,
|
D096C2C21CC3C104006D814E /* Postbox.framework in Embed Frameworks */,
|
||||||
D096C2C51CC3C11A006D814E /* SwiftSignalKit.framework in Embed Frameworks */,
|
D096C2C51CC3C11A006D814E /* SwiftSignalKit.framework in Embed Frameworks */,
|
||||||
D006CFA021A8D11B00FDCD32 /* ModernProto.framework in Embed Frameworks */,
|
D006CFA021A8D11B00FDCD32 /* ModernProto.framework in Embed Frameworks */,
|
||||||
|
D015E051225D303F00CB9E8A /* WebP.framework in Embed Frameworks */,
|
||||||
D0CAF3191D763B230011F558 /* MtProtoKitDynamic.framework in Embed Frameworks */,
|
D0CAF3191D763B230011F558 /* MtProtoKitDynamic.framework in Embed Frameworks */,
|
||||||
);
|
);
|
||||||
name = "Embed Frameworks";
|
name = "Embed Frameworks";
|
||||||
@ -932,6 +936,7 @@
|
|||||||
D00ED75C1FE95287001F38BD /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
D00ED75C1FE95287001F38BD /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
D015E010225CCEB300CB9E8A /* ReadBuffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadBuffer.swift; sourceTree = "<group>"; };
|
D015E010225CCEB300CB9E8A /* ReadBuffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadBuffer.swift; sourceTree = "<group>"; };
|
||||||
D015E01E225CDF5000CB9E8A /* Api0.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Api0.swift; sourceTree = "<group>"; };
|
D015E01E225CDF5000CB9E8A /* Api0.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Api0.swift; sourceTree = "<group>"; };
|
||||||
|
D015E04C225D2D8F00CB9E8A /* WebP.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WebP.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D01A47521F4DBEB100383CC1 /* libHockeySDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libHockeySDK.a; path = "../../build/HockeySDK-iOS/Support/build/Debug-iphoneos/libHockeySDK.a"; sourceTree = "<group>"; };
|
D01A47521F4DBEB100383CC1 /* libHockeySDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libHockeySDK.a; path = "../../build/HockeySDK-iOS/Support/build/Debug-iphoneos/libHockeySDK.a"; sourceTree = "<group>"; };
|
||||||
D01A47541F4DBED700383CC1 /* HockeySDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = HockeySDK.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
D01A47541F4DBED700383CC1 /* HockeySDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = HockeySDK.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D021D4D7219CAEDD0064BEBA /* Telegram-iOS-Fork.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Telegram-iOS-Fork.entitlements"; sourceTree = "<group>"; };
|
D021D4D7219CAEDD0064BEBA /* Telegram-iOS-Fork.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Telegram-iOS-Fork.entitlements"; sourceTree = "<group>"; };
|
||||||
@ -1214,6 +1219,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
D015E04D225D2D8F00CB9E8A /* WebP.framework in Frameworks */,
|
||||||
D0CCD61D222EFFB000EE1E08 /* MtProtoKitDynamic.framework in Frameworks */,
|
D0CCD61D222EFFB000EE1E08 /* MtProtoKitDynamic.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -1233,6 +1239,7 @@
|
|||||||
D0CD17B51CC3AE14007C5650 /* AsyncDisplayKit.framework in Frameworks */,
|
D0CD17B51CC3AE14007C5650 /* AsyncDisplayKit.framework in Frameworks */,
|
||||||
D0D17E8A1CAAD66600C4750B /* Accelerate.framework in Frameworks */,
|
D0D17E8A1CAAD66600C4750B /* Accelerate.framework in Frameworks */,
|
||||||
D0F575132083B96B00F1C1E1 /* CloudKit.framework in Frameworks */,
|
D0F575132083B96B00F1C1E1 /* CloudKit.framework in Frameworks */,
|
||||||
|
D015E050225D303F00CB9E8A /* WebP.framework in Frameworks */,
|
||||||
D006CF9F21A8D11B00FDCD32 /* ModernProto.framework in Frameworks */,
|
D006CF9F21A8D11B00FDCD32 /* ModernProto.framework in Frameworks */,
|
||||||
D0B4AF8F1EC122A700D51FF6 /* TelegramUI.framework in Frameworks */,
|
D0B4AF8F1EC122A700D51FF6 /* TelegramUI.framework in Frameworks */,
|
||||||
D096C2BE1CC3C021006D814E /* Display.framework in Frameworks */,
|
D096C2BE1CC3C021006D814E /* Display.framework in Frameworks */,
|
||||||
@ -2042,6 +2049,7 @@
|
|||||||
D00859C21B281E0000EAF753 /* Frameworks */ = {
|
D00859C21B281E0000EAF753 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
D015E04C225D2D8F00CB9E8A /* WebP.framework */,
|
||||||
D0CCD61C222EFFB000EE1E08 /* MtProtoKitDynamic.framework */,
|
D0CCD61C222EFFB000EE1E08 /* MtProtoKitDynamic.framework */,
|
||||||
D0CAD6A121C03BE2001E3055 /* FFMpeg.framework */,
|
D0CAD6A121C03BE2001E3055 /* FFMpeg.framework */,
|
||||||
D006CFA121A8D12600FDCD32 /* ModernProto.framework */,
|
D006CFA121A8D12600FDCD32 /* ModernProto.framework */,
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
<FileRef
|
<FileRef
|
||||||
location = "group:submodules/ffmpeg/FFMpeg.xcodeproj">
|
location = "group:submodules/ffmpeg/FFMpeg.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:submodules/webp/WebP.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:submodules/libtgvoip/libtgvoip.xcodeproj">
|
location = "group:submodules/libtgvoip/libtgvoip.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 73d45d3c87aa5837189521f41e4709a5d3780825
|
Subproject commit 97a3a77dff3b49d3cb0ec6603b6dba4723f06674
|
@ -1 +1 @@
|
|||||||
Subproject commit 35b9b925fe4f97c735bf8952362b2da42dfdedc8
|
Subproject commit 03f72c3abd02dbe2fbd6586c880d4ca8f7070c17
|
@ -1 +1 @@
|
|||||||
Subproject commit b4c851cecdad300d2bdd672138345b06785f8e95
|
Subproject commit a91c3edd4910ff08dbf3b2c8041c171503c47867
|
1
submodules/webp
Submodule
1
submodules/webp
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 11b3a56ae271a55931ae0bccb8b3cf2b8f3ae191
|
Loading…
x
Reference in New Issue
Block a user