Skip to content

Commit 8b6389e

Browse files
author
Isaac
committed
Merge branch 'master' into beta
# Conflicts: # Telegram/Telegram-iOS/en.lproj/Localizable.strings # submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift # versions.json
2 parents 0073506 + 685ed2c commit 8b6389e

File tree

11,086 files changed

+1296302
-825941
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

11,086 files changed

+1296302
-825941
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ url=../tgcalls.git
2929
[submodule "submodules/LottieCpp/lottiecpp"]
3030
path = submodules/LottieCpp/lottiecpp
3131
url = https://github.com/ali-fareed/lottiecpp.git
32+
[submodule "third-party/dav1d/dav1d"]
33+
path = third-party/dav1d/dav1d
34+
url = https://github.com/ali-fareed/dav1d.git

Telegram/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,6 +1746,7 @@ ios_extension(
17461746
":SwiftSignalKitFramework",
17471747
":PostboxFramework",
17481748
":TelegramCoreFramework",
1749+
":TelegramUIFramework",
17491750
],
17501751
)
17511752

Telegram/NotificationService/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ swift_library(
2222
"//submodules/GZip:GZip",
2323
"//submodules/PersistentStringHash:PersistentStringHash",
2424
"//submodules/Utils/RangeSet",
25+
"//submodules/Media/ConvertOpusToAAC",
2526

2627
],
2728
visibility = [

Telegram/NotificationService/Sources/NotificationService.swift

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import CallKit
1616
import AppLockState
1717
import NotificationsPresentationData
1818
import RangeSet
19+
import ConvertOpusToAAC
1920

2021
private let queue = Queue()
2122

@@ -440,11 +441,11 @@ private func avatarImage(path: String?, peerId: PeerId, letters: [String], size:
440441
}
441442
}
442443

443-
private func storeTemporaryImage(path: String) -> String {
444+
private func storeTemporaryImage(path: String, fileExtension: String) -> String {
444445
let imagesPath = NSTemporaryDirectory() + "/aps-data"
445446
let _ = try? FileManager.default.createDirectory(at: URL(fileURLWithPath: imagesPath), withIntermediateDirectories: true, attributes: nil)
446447

447-
let tempPath = imagesPath + "\(path.persistentHashValue)"
448+
let tempPath = imagesPath + "\(path.persistentHashValue).\(fileExtension)"
448449
if FileManager.default.fileExists(atPath: tempPath) {
449450
return tempPath
450451
}
@@ -459,27 +460,27 @@ private func peerAvatar(mediaBox: MediaBox, accountPeerId: PeerId, peer: Peer, i
459460
if let resource = smallestImageRepresentation(peer.profileImageRepresentations)?.resource, let path = mediaBox.completedResourcePath(resource) {
460461
let cachedPath = mediaBox.cachedRepresentationPathForId(resource.id.stringRepresentation, representationId: "intents\(isStory ? "-story2" : "").png", keepDuration: .shortLived)
461462
if let _ = fileSize(cachedPath), !"".isEmpty {
462-
return INImage(url: URL(fileURLWithPath: storeTemporaryImage(path: cachedPath)))
463+
return INImage(url: URL(fileURLWithPath: storeTemporaryImage(path: cachedPath, fileExtension: "jpg")))
463464
} else {
464465
let image = avatarImage(path: path, peerId: peer.id, letters: peer.displayLetters, size: CGSize(width: 50.0, height: 50.0), isStory: isStory)
465466
if let data = image.pngData() {
466467
let _ = try? FileManager.default.removeItem(atPath: cachedPath)
467468
let _ = try? data.write(to: URL(fileURLWithPath: cachedPath), options: .atomic)
468469
}
469470

470-
return INImage(url: URL(fileURLWithPath: storeTemporaryImage(path: cachedPath)))
471+
return INImage(url: URL(fileURLWithPath: storeTemporaryImage(path: cachedPath, fileExtension: "jpg")))
471472
}
472473
}
473474

474475
let cachedPath = mediaBox.cachedRepresentationPathForId("lettersAvatar2-\(peer.displayLetters.joined(separator: ","))\(isStory ? "-story" : "")", representationId: "intents.png", keepDuration: .shortLived)
475476
if let _ = fileSize(cachedPath) {
476-
return INImage(url: URL(fileURLWithPath: storeTemporaryImage(path: cachedPath)))
477+
return INImage(url: URL(fileURLWithPath: storeTemporaryImage(path: cachedPath, fileExtension: "jpg")))
477478
} else {
478479
let image = avatarImage(path: nil, peerId: peer.id, letters: peer.displayLetters, size: CGSize(width: 50.0, height: 50.0), isStory: isStory)
479480
if let data = image.pngData() {
480481
let _ = try? data.write(to: URL(fileURLWithPath: cachedPath), options: .atomic)
481482
}
482-
return INImage(url: URL(fileURLWithPath: storeTemporaryImage(path: cachedPath)))
483+
return INImage(url: URL(fileURLWithPath: storeTemporaryImage(path: cachedPath, fileExtension: "jpg")))
483484
}
484485
}
485486

@@ -1247,7 +1248,9 @@ private final class NotificationServiceHandler {
12471248
case let .poll(peerId, initialContent, messageId):
12481249
Logger.shared.log("NotificationService \(episode)", "Will poll")
12491250
if let stateManager = strongSelf.stateManager {
1250-
let pollCompletion: (NotificationContent) -> Void = { content in
1251+
let shouldKeepConnection = stateManager.network.shouldKeepConnection
1252+
1253+
let pollCompletion: (NotificationContent, Media?) -> Void = { content, customMedia in
12511254
var content = content
12521255

12531256
queue.async {
@@ -1257,6 +1260,8 @@ private final class NotificationServiceHandler {
12571260
completed()
12581261
return
12591262
}
1263+
1264+
let mediaAttachment = mediaAttachment ?? customMedia
12601265

12611266
var fetchMediaSignal: Signal<Data?, NoError> = .single(nil)
12621267
if let mediaAttachment = mediaAttachment {
@@ -1272,6 +1277,9 @@ private final class NotificationServiceHandler {
12721277
} else if file.isVideo {
12731278
fetchResource = file.previewRepresentations.first?.resource as? TelegramMultipartFetchableResource
12741279
contentType = .video
1280+
} else if file.isVoice {
1281+
fetchResource = file.resource as? TelegramMultipartFetchableResource
1282+
contentType = .audio
12751283
} else {
12761284
contentType = .file
12771285
}
@@ -1443,8 +1451,10 @@ private final class NotificationServiceHandler {
14431451
completed()
14441452
return
14451453
}
1454+
1455+
shouldKeepConnection.set(.single(false))
14461456

1447-
Logger.shared.log("NotificationService \(episode)", "Did fetch media \(mediaData == nil ? "Non-empty" : "Empty")")
1457+
Logger.shared.log("NotificationService \(episode)", "Did fetch media \(mediaData == nil ? "Empty" : "Non-empty")")
14481458

14491459
if let notificationSoundData = notificationSoundData {
14501460
Logger.shared.log("NotificationService \(episode)", "Did fetch notificationSoundData")
@@ -1527,6 +1537,24 @@ private final class NotificationServiceHandler {
15271537
content.attachments.append(attachment)
15281538
}
15291539
}
1540+
} else if file.isVoice {
1541+
if let mediaData = mediaData {
1542+
stateManager.postbox.mediaBox.storeResourceData(file.resource.id, data: mediaData, synchronous: true)
1543+
}
1544+
if let storedPath = stateManager.postbox.mediaBox.completedResourcePath(file.resource, pathExtension: nil) {
1545+
let semaphore = DispatchSemaphore(value: 0)
1546+
let tempFile = TempBox.shared.tempFile(fileName: "audio.m4a")
1547+
let _ = (convertOpusToAAC(sourcePath: storedPath, allocateTempFile: {
1548+
return tempFile.path
1549+
})
1550+
|> timeout(5.0, queue: .concurrentDefaultQueue(), alternate: .single(nil))).startStandalone(next: { _ in
1551+
semaphore.signal()
1552+
})
1553+
semaphore.wait()
1554+
if let attachment = try? UNNotificationAttachment(identifier: "audio", url: URL(fileURLWithPath: tempFile.path), options: nil) {
1555+
content.attachments.append(attachment)
1556+
}
1557+
}
15301558
}
15311559
}
15321560

@@ -1550,11 +1578,10 @@ private final class NotificationServiceHandler {
15501578
}
15511579

15521580
let pollSignal: Signal<Never, NoError>
1553-
1581+
15541582
if !shouldSynchronizeState {
15551583
pollSignal = .complete()
15561584
} else {
1557-
let shouldKeepConnection = stateManager.network.shouldKeepConnection
15581585
shouldKeepConnection.set(.single(true))
15591586
if peerId.namespace == Namespaces.Peer.CloudChannel {
15601587
Logger.shared.log("NotificationService \(episode)", "Will poll channel \(peerId)")
@@ -1566,9 +1593,6 @@ private final class NotificationServiceHandler {
15661593
peerId: peerId,
15671594
stateManager: stateManager
15681595
)
1569-
|> afterDisposed { [weak shouldKeepConnection] in
1570-
shouldKeepConnection?.set(.single(false))
1571-
}
15721596
} else {
15731597
Logger.shared.log("NotificationService \(episode)", "Will perform non-specific getDifference")
15741598
enum ControlError {
@@ -1584,17 +1608,14 @@ private final class NotificationServiceHandler {
15841608
}
15851609
}
15861610
|> restartIfError
1587-
|> afterDisposed { [weak shouldKeepConnection] in
1588-
shouldKeepConnection?.set(.single(false))
1589-
}
15901611

15911612
pollSignal = signal
15921613
}
15931614
}
15941615

1595-
let pollWithUpdatedContent: Signal<NotificationContent, NoError>
1616+
let pollWithUpdatedContent: Signal<(NotificationContent, Media?), NoError>
15961617
if interactionAuthorId != nil || messageId != nil {
1597-
pollWithUpdatedContent = stateManager.postbox.transaction { transaction -> NotificationContent in
1618+
pollWithUpdatedContent = stateManager.postbox.transaction { transaction -> (NotificationContent, Media?) in
15981619
var content = initialContent
15991620

16001621
if let interactionAuthorId = interactionAuthorId {
@@ -1639,22 +1660,37 @@ private final class NotificationServiceHandler {
16391660
}
16401661
}
16411662

1642-
return content
1663+
return (content, nil)
16431664
}
16441665
|> then(
16451666
pollSignal
1646-
|> map { _ -> NotificationContent in }
1667+
|> map { _ -> (NotificationContent, Media?) in }
16471668
)
1669+
|> takeLast
1670+
|> mapToSignal { content, _ -> Signal<(NotificationContent, Media?), NoError> in
1671+
return stateManager.postbox.transaction { transaction -> (NotificationContent, Media?) in
1672+
var parsedMedia: Media?
1673+
if let messageId, let message = transaction.getMessage(messageId) {
1674+
if let media = message.media.first {
1675+
parsedMedia = media
1676+
}
1677+
}
1678+
1679+
return (content, parsedMedia)
1680+
}
1681+
}
16481682
} else {
16491683
pollWithUpdatedContent = pollSignal
1650-
|> map { _ -> NotificationContent in }
1684+
|> map { _ -> (NotificationContent, Media?) in }
16511685
}
16521686

16531687
var updatedContent = initialContent
1654-
strongSelf.pollDisposable.set(pollWithUpdatedContent.start(next: { content in
1688+
var updatedMedia: Media?
1689+
strongSelf.pollDisposable.set(pollWithUpdatedContent.start(next: { content, media in
16551690
updatedContent = content
1691+
updatedMedia = media
16561692
}, completed: {
1657-
pollCompletion(updatedContent)
1693+
pollCompletion(updatedContent, updatedMedia)
16581694
}))
16591695
} else {
16601696
completed()

0 commit comments

Comments
 (0)