diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift index 65841ad319..b186f309fd 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift @@ -21,7 +21,7 @@ protocol LegacyPaintEntity { func image(for time: CMTime, fps: Int, completion: @escaping (CIImage?) -> Void) } -private func render(width: Int, height: Int, bytesPerRow: Int, data: Data, type: AnimationRendererFrameType) -> CIImage? { +private func render(width: Int, height: Int, bytesPerRow: Int, data: Data, type: AnimationRendererFrameType, tintColor: UIColor?) -> CIImage? { let calculatedBytesPerRow = (4 * Int(width) + 31) & (~31) assert(bytesPerRow == calculatedBytesPerRow) @@ -46,7 +46,10 @@ private func render(width: Int, height: Int, bytesPerRow: Int, data: Data, type: } }) - if let image = image { + if var image = image { + if let tintColor, let tintedImage = generateTintedImage(image: image, color: tintColor) { + image = tintedImage + } return CIImage(image: image) } else { return nil @@ -160,6 +163,11 @@ private class LegacyPaintStickerEntity: LegacyPaintEntity { if self.animated { let currentTime = CMTimeGetSeconds(time) + var tintColor: UIColor? + if let _ = self.file?.isCustomTemplateEmoji { + tintColor = .white + } + self.disposables.add((self.frameQueue.get() |> take(1) |> deliverOn(self.queue)).start(next: { [weak self] frameQueue in @@ -204,7 +212,7 @@ private class LegacyPaintStickerEntity: LegacyPaintEntity { return frame } if let frame = maybeFrame { - let image = render(width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type) + let image = render(width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type, tintColor: tintColor) completion(image) strongSelf.cachedCIImage = image } else { @@ -258,6 +266,18 @@ private class LegacyPaintTextEntity: LegacyPaintEntity { var mirrored: Bool { return false } + + var animated: Bool { + return self.entity.renderAnimationFrames != nil + } + + var duration: Double { + if let lastFrame = self.entity.renderAnimationFrames?.last { + return lastFrame.timestamp + lastFrame.duration + } else { + return 0.0 + } + } let entity: DrawingTextEntity @@ -266,13 +286,42 @@ private class LegacyPaintTextEntity: LegacyPaintEntity { } var cachedCIImage: CIImage? + var cachedFrameCIImage: (Double, CIImage)? + func image(for time: CMTime, fps: Int, completion: @escaping (CIImage?) -> Void) { var image: CIImage? - if let cachedImage = self.cachedCIImage { - image = cachedImage - } else if let renderImage = entity.renderImage { - image = CIImage(image: renderImage) - self.cachedCIImage = image + if let frames = self.entity.renderAnimationFrames { + var currentTime = CMTimeGetSeconds(time) + let duration = self.duration + while currentTime > duration { + currentTime -= duration + } + + for frame in frames { + if currentTime >= frame.timestamp && currentTime < frame.timestamp + frame.duration { + if let (timestamp, cachedImage) = self.cachedFrameCIImage, timestamp == frame.timestamp { + image = cachedImage + } else if let renderImage = CIImage(image: frame.image) { + self.cachedFrameCIImage = (frame.timestamp, renderImage) + image = renderImage + } + break + } + } + if image == nil { + if let (_, cachedImage) = self.cachedFrameCIImage { + image = cachedImage + } else if let firstFrame = frames.first { + image = CIImage(image: firstFrame.image) + } + } + } else { + if let cachedImage = self.cachedCIImage { + image = cachedImage + } else if let renderImage = entity.renderImage { + image = CIImage(image: renderImage) + self.cachedCIImage = image + } } completion(image) } @@ -450,6 +499,8 @@ public final class LegacyPaintEntityRenderer: NSObject, TGPhotoPaintEntityRender for entity in self.entities { if let sticker = entity as? LegacyPaintStickerEntity, sticker.animated { durations.append(sticker.duration) + } else if let text = entity as? LegacyPaintTextEntity, text.animated { + durations.append(.single(text.duration)) } } diff --git a/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift b/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift index 9f6225e203..37b3a9b719 100644 --- a/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift +++ b/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift @@ -1278,6 +1278,9 @@ final class AvatarEditorScreenComponent: Component { } image = context.generateImage() + if file.isCustomTemplateEmoji { + image = generateTintedImage(image: image, color: .white) + } default: return } diff --git a/submodules/TranslateUI/Sources/ChatTranslation.swift b/submodules/TranslateUI/Sources/ChatTranslation.swift index 9136a63b55..03d491bbdd 100644 --- a/submodules/TranslateUI/Sources/ChatTranslation.swift +++ b/submodules/TranslateUI/Sources/ChatTranslation.swift @@ -195,8 +195,26 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id) if let _ = URL(string: message.text) { continue } - if message.text.count > 10 { - let text = String(message.text.prefix(100)) + if message.text.count >= 10 { + var text = String(message.text.prefix(256)) + if var entities = message.textEntitiesAttribute?.entities.filter({ $0.type == .Pre || $0.type == .Code }) { + entities = entities.sorted(by: { $0.range.lowerBound > $1.range.lowerBound }) + var ranges: [Range] = [] + for entity in entities { + if entity.range.lowerBound > text.count || entity.range.upperBound > text.count { + continue + } + ranges.append(text.index(text.startIndex, offsetBy: entity.range.lowerBound) ..< text.index(text.startIndex, offsetBy: entity.range.upperBound)) + } + for range in ranges { + text.removeSubrange(range) + } + } + + if message.text.count < 10 { + continue + } + languageRecognizer.processString(text) let hypotheses = languageRecognizer.languageHypotheses(withMaximum: 4) languageRecognizer.reset() @@ -205,19 +223,14 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id) if let language = filteredLanguages.first(where: { supportedTranslationLanguages.contains($0.key.rawValue) }) { let fromLang = language.key.rawValue fromLangs[fromLang] = (fromLangs[fromLang] ?? 0) + message.text.count + count += 1 } - count += 1 } if count >= 10 { break } } - - if let _ = fromLangs["ru"] { - fromLangs["bg"] = nil - fromLangs["kk"] = nil - } - + var mostFrequent: (String, Int)? for (lang, count) in fromLangs { if let current = mostFrequent { diff --git a/submodules/TranslateUI/Sources/Translate.swift b/submodules/TranslateUI/Sources/Translate.swift index a7ba897139..80bdd32879 100644 --- a/submodules/TranslateUI/Sources/Translate.swift +++ b/submodules/TranslateUI/Sources/Translate.swift @@ -185,5 +185,8 @@ public func systemLanguageCodes() -> [String] { let language = language.components(separatedBy: "-").first ?? language languages.append(language) } + if languages.count == 2 && languages != ["en", "ru"] { + languages = Array(languages.prefix(1)) + } return languages }