diff --git a/submodules/FFMpegBinding/Sources/FFMpegAVCodec.m b/submodules/FFMpegBinding/Sources/FFMpegAVCodec.m index 739ab5efb3..f50633c2a8 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegAVCodec.m +++ b/submodules/FFMpegBinding/Sources/FFMpegAVCodec.m @@ -1,6 +1,6 @@ #import -#import +#import "libavcodec/avcodec.h" @interface FFMpegAVCodec () { AVCodec const *_impl; diff --git a/submodules/FFMpegBinding/Sources/FFMpegAVCodecContext.m b/submodules/FFMpegBinding/Sources/FFMpegAVCodecContext.m index 0fae131670..ee2cde92c0 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegAVCodecContext.m +++ b/submodules/FFMpegBinding/Sources/FFMpegAVCodecContext.m @@ -3,8 +3,8 @@ #import #import -#import -#import +#import "libavformat/avformat.h" +#import "libavcodec/avcodec.h" static enum AVPixelFormat getPreferredPixelFormat(__unused AVCodecContext *ctx, __unused const enum AVPixelFormat *pix_fmts) { return AV_PIX_FMT_VIDEOTOOLBOX; diff --git a/submodules/FFMpegBinding/Sources/FFMpegAVFormatContext.m b/submodules/FFMpegBinding/Sources/FFMpegAVFormatContext.m index a98c295d6d..ebc0d4f963 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegAVFormatContext.m +++ b/submodules/FFMpegBinding/Sources/FFMpegAVFormatContext.m @@ -4,8 +4,8 @@ #import #import -#import -#import +#import "libavcodec/avcodec.h" +#import "libavformat/avformat.h" int FFMpegCodecIdH264 = AV_CODEC_ID_H264; int FFMpegCodecIdHEVC = AV_CODEC_ID_HEVC; diff --git a/submodules/FFMpegBinding/Sources/FFMpegAVFrame.m b/submodules/FFMpegBinding/Sources/FFMpegAVFrame.m index 9c17b53c09..fda8224dc7 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegAVFrame.m +++ b/submodules/FFMpegBinding/Sources/FFMpegAVFrame.m @@ -1,6 +1,6 @@ #import -#import +#import "libavformat/avformat.h" @interface FFMpegAVFrame () { AVFrame *_impl; diff --git a/submodules/FFMpegBinding/Sources/FFMpegAVIOContext.m b/submodules/FFMpegBinding/Sources/FFMpegAVIOContext.m index ebad7d28c9..be3cecf4bd 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegAVIOContext.m +++ b/submodules/FFMpegBinding/Sources/FFMpegAVIOContext.m @@ -1,6 +1,6 @@ #import -#import +#import "libavformat/avformat.h" int FFMPEG_CONSTANT_AVERROR_EOF = AVERROR_EOF; diff --git a/submodules/FFMpegBinding/Sources/FFMpegGlobals.m b/submodules/FFMpegBinding/Sources/FFMpegGlobals.m index 459725e5ab..f0ff9091bb 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegGlobals.m +++ b/submodules/FFMpegBinding/Sources/FFMpegGlobals.m @@ -1,6 +1,6 @@ #import -#import +#import "libavformat/avformat.h" @implementation FFMpegGlobals diff --git a/submodules/FFMpegBinding/Sources/FFMpegLiveMuxer.m b/submodules/FFMpegBinding/Sources/FFMpegLiveMuxer.m index 22531987c8..85ddce8a9e 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegLiveMuxer.m +++ b/submodules/FFMpegBinding/Sources/FFMpegLiveMuxer.m @@ -1,10 +1,10 @@ #import #import -#include -#include -#include -#include +#include "libavutil/timestamp.h" +#include "libavformat/avformat.h" +#include "libavcodec/avcodec.h" +#include "libswresample/swresample.h" #define MOV_TIMESCALE 1000 diff --git a/submodules/FFMpegBinding/Sources/FFMpegPacket.m b/submodules/FFMpegBinding/Sources/FFMpegPacket.m index 4ef8b24dbe..7da5655c96 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegPacket.m +++ b/submodules/FFMpegBinding/Sources/FFMpegPacket.m @@ -2,8 +2,8 @@ #import -#import -#import +#import "libavcodec/avcodec.h" +#import "libavformat/avformat.h" @interface FFMpegPacket () { AVPacket *_impl; diff --git a/submodules/FFMpegBinding/Sources/FFMpegRemuxer.m b/submodules/FFMpegBinding/Sources/FFMpegRemuxer.m index 722a21f4fe..df3c1adfb8 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegRemuxer.m +++ b/submodules/FFMpegBinding/Sources/FFMpegRemuxer.m @@ -2,9 +2,9 @@ #import -#include -#include -#include +#include "libavutil/timestamp.h" +#include "libavformat/avformat.h" +#include "libavcodec/avcodec.h" #define MOV_TIMESCALE 1000 diff --git a/submodules/FFMpegBinding/Sources/FFMpegSWResample.m b/submodules/FFMpegBinding/Sources/FFMpegSWResample.m index de38cab260..c6771b6db3 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegSWResample.m +++ b/submodules/FFMpegBinding/Sources/FFMpegSWResample.m @@ -2,9 +2,9 @@ #import -#import -#import -#import +#import "libavformat/avformat.h" +#import "libavcodec/avcodec.h" +#import "libswresample/swresample.h" @interface FFMpegSWResample () { int _sourceSampleRate; diff --git a/submodules/FFMpegBinding/Sources/FFMpegVideoWriter.m b/submodules/FFMpegBinding/Sources/FFMpegVideoWriter.m index 4274fc6d6c..4746828e62 100755 --- a/submodules/FFMpegBinding/Sources/FFMpegVideoWriter.m +++ b/submodules/FFMpegBinding/Sources/FFMpegVideoWriter.m @@ -1,9 +1,9 @@ #import #import -#include -#include -#include +#include "libavformat/avformat.h" +#include "libavcodec/avcodec.h" +#include "libavutil/imgutils.h" @interface FFMpegVideoWriter () diff --git a/submodules/Pasteboard/Sources/Pasteboard.swift b/submodules/Pasteboard/Sources/Pasteboard.swift index bbd784a466..7ffa9fc9d4 100644 --- a/submodules/Pasteboard/Sources/Pasteboard.swift +++ b/submodules/Pasteboard/Sources/Pasteboard.swift @@ -53,15 +53,29 @@ private func chatInputStateString(attributedString: NSAttributedString) -> NSAtt } if let value = attributes[.font], let font = value as? UIFont { let fontName = font.fontName.lowercased() - if fontName.contains("bolditalic") { - string.addAttribute(ChatTextInputAttributes.bold, value: true as NSNumber, range: range) - string.addAttribute(ChatTextInputAttributes.italic, value: true as NSNumber, range: range) - } else if fontName.contains("bold") { - string.addAttribute(ChatTextInputAttributes.bold, value: true as NSNumber, range: range) - } else if fontName.contains("italic") { - string.addAttribute(ChatTextInputAttributes.italic, value: true as NSNumber, range: range) - } else if fontName.contains("menlo") || fontName.contains("courier") || fontName.contains("sfmono") { - string.addAttribute(ChatTextInputAttributes.monospace, value: true as NSNumber, range: range) + if fontName.hasPrefix(".sfui") { + let traits = font.fontDescriptor.symbolicTraits + if traits.contains(.traitMonoSpace) { + string.addAttribute(ChatTextInputAttributes.monospace, value: true as NSNumber, range: range) + } else { + if traits.contains(.traitBold) { + string.addAttribute(ChatTextInputAttributes.bold, value: true as NSNumber, range: range) + } + if traits.contains(.traitItalic) { + string.addAttribute(ChatTextInputAttributes.italic, value: true as NSNumber, range: range) + } + } + } else { + if fontName.contains("bolditalic") { + string.addAttribute(ChatTextInputAttributes.bold, value: true as NSNumber, range: range) + string.addAttribute(ChatTextInputAttributes.italic, value: true as NSNumber, range: range) + } else if fontName.contains("bold") { + string.addAttribute(ChatTextInputAttributes.bold, value: true as NSNumber, range: range) + } else if fontName.contains("italic") { + string.addAttribute(ChatTextInputAttributes.italic, value: true as NSNumber, range: range) + } else if fontName.contains("menlo") || fontName.contains("courier") || fontName.contains("sfmono") { + string.addAttribute(ChatTextInputAttributes.monospace, value: true as NSNumber, range: range) + } } } if let value = attributes[.backgroundColor] as? UIColor, value.rgb == UIColor.gray.rgb { diff --git a/submodules/TelegramUI/BUILD b/submodules/TelegramUI/BUILD index 3f0e1ae3d6..4c64d17ab7 100644 --- a/submodules/TelegramUI/BUILD +++ b/submodules/TelegramUI/BUILD @@ -70,6 +70,7 @@ swift_library( "//submodules/MediaPlayer:UniversalMediaPlayer", "//submodules/TelegramVoip:TelegramVoip", "//submodules/DeviceAccess:DeviceAccess", + "//submodules/Utils/DeviceModel", "//submodules/WatchCommon/Host:WatchCommon", "//submodules/BuildConfig:BuildConfig", "//submodules/BuildConfigExtra:BuildConfigExtra", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift index 38c0ff482f..f749c3c46a 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift @@ -295,10 +295,6 @@ public func canAddMessageReactions(message: Message) -> Bool { return true } } - } else if let story = media as? TelegramMediaStory { - if story.isMention { - return false - } } } return true diff --git a/submodules/TelegramUI/Components/Gifts/GiftItemComponent/Sources/GiftItemComponent.swift b/submodules/TelegramUI/Components/Gifts/GiftItemComponent/Sources/GiftItemComponent.swift index 001fa6f4fe..ae3d159ef2 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftItemComponent/Sources/GiftItemComponent.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftItemComponent/Sources/GiftItemComponent.swift @@ -559,7 +559,7 @@ public final class GiftItemComponent: Component { let price: String switch component.subject { case let .premium(_, priceValue), let .starGift(_, priceValue): - if priceValue.containsEmoji { + if priceValue.contains("#") { buttonColor = component.theme.overallDarkAppearance ? UIColor(rgb: 0xffc337) : UIColor(rgb: 0xd3720a) if !component.isSoldOut { starsColor = UIColor(rgb: 0xffbe27) @@ -867,10 +867,12 @@ public final class GiftItemComponent: Component { } ) let dateTimeFormat = component.context.sharedContext.currentPresentationData.with { $0 }.dateTimeFormat - let labelText = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString("#\(presentationStringsFormattedNumber(Int32(resellPrice), dateTimeFormat.groupingSeparator))", attributes: attributes)) - if let range = labelText.string.range(of: "#") { - labelText.addAttribute(NSAttributedString.Key.font, value: Font.semibold(10.0), range: NSRange(range, in: labelText.string)) - labelText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: true)), range: NSRange(range, in: labelText.string)) + let labelText = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString("# \(presentationStringsFormattedNumber(Int32(resellPrice), dateTimeFormat.groupingSeparator))", attributes: attributes)) + let range = (labelText.string as NSString).range(of: "#") + if range.location != NSNotFound { + labelText.addAttribute(NSAttributedString.Key.font, value: Font.semibold(10.0), range: range) + labelText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: true)), range: range) + labelText.addAttribute(.kern, value: -1.5, range: NSRange(location: range.upperBound, length: 1)) } let resellSize = self.reselLabel.update( @@ -1048,11 +1050,13 @@ private final class ButtonContentComponent: Component { self.componentState = state let attributedText = NSMutableAttributedString(string: component.text, font: Font.semibold(11.0), textColor: component.color) - let range = (attributedText.string as NSString).range(of: "⭐️") + let range = (attributedText.string as NSString).range(of: "#") if range.location != NSNotFound { attributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: component.tinted)), range: range) - attributedText.addAttribute(.font, value: Font.semibold(15.0), range: range) - attributedText.addAttribute(.baselineOffset, value: 2.0, range: NSRange(location: range.upperBound, length: attributedText.length - range.upperBound)) + attributedText.addAttribute(.font, value: Font.semibold(component.tinted ? 14.0 : 15.0), range: range) + attributedText.addAttribute(.baselineOffset, value: -3.0, range: range) + attributedText.addAttribute(.baselineOffset, value: 1.5, range: NSRange(location: range.upperBound + 1, length: attributedText.length - range.upperBound - 1)) + attributedText.addAttribute(.kern, value: -1.5, range: NSRange(location: range.upperBound, length: 1)) } let titleSize = self.title.update( diff --git a/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift index 5b79de4903..643d1f7131 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift @@ -412,12 +412,12 @@ final class GiftOptionsScreenComponent: Component { if let availability = gift.availability, availability.remains == 0, let minResaleStars = availability.minResaleStars { let priceString = presentationStringsFormattedNumber(Int32(minResaleStars), environment.dateTimeFormat.groupingSeparator) if let resaleConfiguration = self.resaleConfiguration, minResaleStars == resaleConfiguration.starGiftResaleMaxAmount || availability.resale == 1 { - subject = .starGift(gift: gift, price: "⭐️ \(priceString)") + subject = .starGift(gift: gift, price: "# \(priceString)") } else { - subject = .starGift(gift: gift, price: "⭐️ \(priceString)+") + subject = .starGift(gift: gift, price: "# \(priceString)+") } } else { - subject = .starGift(gift: gift, price: "⭐️ \(presentationStringsFormattedNumber(Int32(gift.price), environment.dateTimeFormat.groupingSeparator))") + subject = .starGift(gift: gift, price: "# \(presentationStringsFormattedNumber(Int32(gift.price), environment.dateTimeFormat.groupingSeparator))") } case let .unique(gift): subject = .uniqueGift(gift: gift, price: nil) @@ -1567,6 +1567,9 @@ final class GiftOptionsScreenComponent: Component { } } } + if disallowedGifts.contains(.unique) && gift.availability?.remains == 0 { + return false + } } return true } diff --git a/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/GiftStoreScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/GiftStoreScreen.swift index ae889947fc..6827a62fbf 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/GiftStoreScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/GiftStoreScreen.swift @@ -230,7 +230,7 @@ final class GiftStoreScreenComponent: Component { color: ribbonColor ) - let subject: GiftItemComponent.Subject = .uniqueGift(gift: uniqueGift, price: "⭐️\(presentationStringsFormattedNumber(Int32(uniqueGift.resellStars ?? 0), environment.dateTimeFormat.groupingSeparator))") + let subject: GiftItemComponent.Subject = .uniqueGift(gift: uniqueGift, price: "# \(presentationStringsFormattedNumber(Int32(uniqueGift.resellStars ?? 0), environment.dateTimeFormat.groupingSeparator))") let _ = visibleItem.update( transition: itemTransition, component: AnyComponent( diff --git a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift index 3d8134dfbc..5cc4395dcb 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift @@ -309,17 +309,29 @@ private final class GiftViewSheetContent: CombinedComponent { let context = self.context let action = { if gifts { - if let profileController = context.sharedContext.makePeerInfoController( - context: context, - updatedPresentationData: nil, - peer: peer._asPeer(), - mode: peer.id == context.account.peerId ? .myProfileGifts : .gifts, - avatarInitiallyExpanded: false, - fromChat: false, - requestsContext: nil - ) { - navigationController.pushViewController(profileController) + let profileGifts = ProfileGiftsContext(account: context.account, peerId: peer.id) + let _ = (profileGifts.state + |> filter { state in + if case .ready = state.dataState { + return true + } + return false } + |> take(1) + |> deliverOnMainQueue).start(next: { [weak navigationController] _ in + if let profileController = context.sharedContext.makePeerInfoController( + context: context, + updatedPresentationData: nil, + peer: peer._asPeer(), + mode: peer.id == context.account.peerId ? .myProfileGifts : .gifts, + avatarInitiallyExpanded: false, + fromChat: false, + requestsContext: nil + ) { + navigationController?.pushViewController(profileController) + } + let _ = profileGifts + }) } else { context.sharedContext.navigateToChatController(NavigateToChatControllerParams( navigationController: navigationController, diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorValues.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorValues.swift index 47b4d4c792..373483fe9b 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorValues.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorValues.swift @@ -230,7 +230,7 @@ public enum MediaCropOrientation: Int32 { } } -public final class MediaEditorValues: Codable, Equatable { +public final class MediaEditorValues: Codable, Equatable, CustomStringConvertible { public static func == (lhs: MediaEditorValues, rhs: MediaEditorValues) -> Bool { if lhs.peerId != rhs.peerId { return false @@ -1010,6 +1010,114 @@ public final class MediaEditorValues: Codable, Equatable { } return false } + + public var description: String { + var components: [String] = [] + + components.append("originalDimensions: \(self.originalDimensions.width)x\(self.originalDimensions.height)") + + if self.cropOffset != .zero { + components.append("cropOffset: \(cropOffset)") + } + + if let cropRect = self.cropRect { + components.append("cropRect: \(cropRect)") + } + + if self.cropScale != 1.0 { + components.append("cropScale: \(self.cropScale)") + } + + if self.cropRotation != 0.0 { + components.append("cropRotation: \(self.cropRotation)") + } + + if self.cropMirroring { + components.append("cropMirroring: true") + } + + if let cropOrientation = self.cropOrientation { + components.append("cropOrientation: \(cropOrientation)") + } + + if let gradientColors = self.gradientColors, !gradientColors.isEmpty { + components.append("gradientColors: \(gradientColors.count) colors") + } + + if let videoTrimRange = self.videoTrimRange { + components.append("videoTrimRange: \(videoTrimRange.lowerBound) - \(videoTrimRange.upperBound)") + } + + if self.videoIsMuted { + components.append("videoIsMuted: true") + } + + if self.videoIsFullHd { + components.append("videoIsFullHd: true") + } + + if self.videoIsMirrored { + components.append("videoIsMirrored: true") + } + + if let videoVolume = self.videoVolume, videoVolume != 1.0 { + components.append("videoVolume: \(videoVolume)") + } + + if let additionalVideoPath = self.additionalVideoPath { + components.append("additionalVideo: \(additionalVideoPath)") + } + + if let position = self.additionalVideoPosition { + components.append("additionalVideoPosition: \(position)") + } + + if let scale = self.additionalVideoScale { + components.append("additionalVideoScale: \(scale)") + } + + if let rotation = self.additionalVideoRotation { + components.append("additionalVideoRotation: \(rotation)") + } + + if !self.additionalVideoPositionChanges.isEmpty { + components.append("additionalVideoPositionChanges: \(additionalVideoPositionChanges.count) changes") + } + + if !self.collage.isEmpty { + components.append("collage: \(collage.count) items") + } + + if self.nightTheme { + components.append("nightTheme: true") + } + + if self.drawing != nil { + components.append("drawing: true") + } + + if self.maskDrawing != nil { + components.append("maskDrawing: true") + } + + if !self.entities.isEmpty { + components.append("entities: \(self.entities.count) items") + } + + if !self.toolValues.isEmpty { + components.append("toolValues: \(self.toolValues.count) tools") + } + + if let audioTrack = self.audioTrack { + components.append("audioTrack: \(audioTrack.path)") + } + + if let qualityPreset = self.qualityPreset { + components.append("qualityPreset: \(qualityPreset)") + } + + return "MediaEditorValues(\(components.joined(separator: ", ")))" + } } public struct TintValue: Equatable, Codable { diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorVideoExport.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorVideoExport.swift index 6061765718..89bfd124cc 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorVideoExport.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorVideoExport.swift @@ -264,6 +264,11 @@ public final class MediaEditorVideoExport { self.outputPath = outputPath self.textScale = textScale + Logger.shared.log("VideoExport", "Init") + Logger.shared.log("VideoExport", "Subject: \(subject)") + Logger.shared.log("VideoExport", "Output Path: \(outputPath)") + Logger.shared.log("VideoExport", "Configuration: \(configuration)") + if FileManager.default.fileExists(atPath: outputPath) { try? FileManager.default.removeItem(atPath: outputPath) } @@ -297,6 +302,9 @@ public final class MediaEditorVideoExport { } private func setup() { + Logger.shared.log("VideoExport", "Setting up") + + var mainAsset: AVAsset? var signals: [Signal] = [] @@ -948,11 +956,6 @@ public final class MediaEditorVideoExport { return false } } - } else { -// if !writer.appendVideoBuffer(sampleBuffer) { -// writer.markVideoAsFinished() -// return false -// } } } return true @@ -983,17 +986,21 @@ public final class MediaEditorVideoExport { } private func start() { + Logger.shared.log("VideoExport", "Start") guard self.internalStatus == .idle, let writer = self.writer else { + Logger.shared.log("VideoExport", "Failed with invalid state") self.statusValue = .failed(.invalid) return } guard writer.startWriting() else { + Logger.shared.log("VideoExport", "Failed on startWriting") self.statusValue = .failed(.writing(nil)) return } if let reader = self.reader, !reader.startReading() { + Logger.shared.log("VideoExport", "Failed on startReading") self.statusValue = .failed(.reading(nil)) return } @@ -1067,6 +1074,7 @@ public final class MediaEditorVideoExport { } if cancelled { + Logger.shared.log("VideoExport", "Cancelled") try? FileManager.default.removeItem(at: outputUrl) self.internalStatus = .finished self.statusValue = .failed(.cancelled) @@ -1108,6 +1116,7 @@ public final class MediaEditorVideoExport { let exportDuration = end - self.startTimestamp print("video processing took \(exportDuration)s") if duration.seconds > 0 { + Logger.shared.log("VideoExport", "Completed with path \(self.outputPath)") Logger.shared.log("VideoExport", "Video processing took \(exportDuration / duration.seconds)") } }) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoGiftsCoverComponent.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoGiftsCoverComponent.swift index 81ba25209d..4f32eca5a3 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoGiftsCoverComponent.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoGiftsCoverComponent.swift @@ -184,7 +184,9 @@ public final class PeerInfoGiftsCoverComponent: Component { } } + private var scheduledAnimateIn = false public func willAnimateIn() { + self.scheduledAnimateIn = true for (_, layer) in self.iconLayers { layer.opacity = 0.0 } @@ -194,6 +196,7 @@ public final class PeerInfoGiftsCoverComponent: Component { guard let _ = self.currentSize, let component = self.component else { return } + self.scheduledAnimateIn = false for (_, layer) in self.iconLayers { layer.opacity = 1.0 @@ -319,8 +322,12 @@ public final class PeerInfoGiftsCoverComponent: Component { self.iconLayers[id] = iconLayer self.layer.addSublayer(iconLayer) - iconLayer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - iconLayer.animateScale(from: 0.01, to: 1.0, duration: 0.2) + if self.scheduledAnimateIn { + iconLayer.opacity = 0.0 + } else { + iconLayer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + iconLayer.animateScale(from: 0.01, to: 1.0, duration: 0.2) + } iconLayer.startAnimations(index: index) } @@ -349,7 +356,10 @@ public final class PeerInfoGiftsCoverComponent: Component { iconTransition.setPosition(layer: iconLayer, position: absolutePosition) iconLayer.updateRotation(effectiveAngle, transition: iconTransition) iconTransition.setScale(layer: iconLayer, scale: iconPosition.scale * (1.0 - itemScaleFraction)) - iconTransition.setAlpha(layer: iconLayer, alpha: 1.0 - itemScaleFraction) + + if !self.scheduledAnimateIn { + iconTransition.setAlpha(layer: iconLayer, alpha: 1.0 - itemScaleFraction) + } index += 1 } diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift index 2a88b1ced1..51dd286db5 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift @@ -488,7 +488,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr switch product.gift { case let .generic(gift): - subject = .starGift(gift: gift, price: "⭐️ \(gift.price)") + subject = .starGift(gift: gift, price: "# \(gift.price)") peer = product.fromPeer.flatMap { .peer($0) } ?? .anonymous if let availability = gift.availability { diff --git a/submodules/TelegramUI/Components/TabSelectorComponent/Sources/TabSelectorComponent.swift b/submodules/TelegramUI/Components/TabSelectorComponent/Sources/TabSelectorComponent.swift index f107fd6366..efce5db5c6 100644 --- a/submodules/TelegramUI/Components/TabSelectorComponent/Sources/TabSelectorComponent.swift +++ b/submodules/TelegramUI/Components/TabSelectorComponent/Sources/TabSelectorComponent.swift @@ -117,6 +117,8 @@ public final class TabSelectorComponent: Component { private let selectionView: UIImageView private var visibleItems: [AnyHashable: VisibleItem] = [:] + private var didInitiallyScroll = false + override init(frame: CGRect) { self.selectionView = UIImageView() @@ -238,11 +240,15 @@ public final class TabSelectorComponent: Component { )), effectAlignment: .center, minSize: nil, - action: { [weak self] in + action: { [weak self, weak itemView] in guard let self, let component = self.component else { return } component.setSelectedId(itemId) + + if let view = itemView?.title.view, allowScroll && self.contentSize.width > self.bounds.width { + self.scrollRectToVisible(view.frame.insetBy(dx: -64.0, dy: 0.0), animated: true) + } }, animateScale: !isLineSelection )), @@ -336,11 +342,15 @@ public final class TabSelectorComponent: Component { self.selectionView.alpha = 0.0 } - self.contentSize = CGSize(width: contentWidth, height: baseHeight + verticalInset * 2.0) + let contentSize = CGSize(width: contentWidth, height: baseHeight + verticalInset * 2.0) + if self.contentSize != contentSize { + self.contentSize = contentSize + } self.disablesInteractiveTransitionGestureRecognizer = contentWidth > availableSize.width - if let selectedBackgroundRect, self.bounds.width > 0.0 { + if let selectedBackgroundRect, self.bounds.width > 0.0 && !self.didInitiallyScroll { self.scrollRectToVisible(selectedBackgroundRect.insetBy(dx: -spacing, dy: 0.0), animated: false) + self.didInitiallyScroll = true } return CGSize(width: min(contentWidth, availableSize.width), height: baseHeight + verticalInset * 2.0) diff --git a/submodules/TelegramUI/Images.xcassets/Wallet/QrIcon.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Wallet/QrIcon.imageset/Contents.json deleted file mode 100644 index f8015db3bc..0000000000 --- a/submodules/TelegramUI/Images.xcassets/Wallet/QrIcon.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "filename" : "ic_qrcode.pdf", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/submodules/TelegramUI/Images.xcassets/Wallet/QrIcon.imageset/ic_qrcode.pdf b/submodules/TelegramUI/Images.xcassets/Wallet/QrIcon.imageset/ic_qrcode.pdf deleted file mode 100644 index cf234b8223..0000000000 Binary files a/submodules/TelegramUI/Images.xcassets/Wallet/QrIcon.imageset/ic_qrcode.pdf and /dev/null differ diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index 193ccfa97b..1e884bf566 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -1,4 +1,5 @@ import Foundation +import UniformTypeIdentifiers import UIKit import Display import AsyncDisplayKit @@ -44,6 +45,7 @@ import TelegramNotices import AnimatedCountLabelNode import TelegramStringFormatting import TextNodeWithEntities +import DeviceModel private let accessoryButtonFont = Font.medium(14.0) private let counterFont = Font.with(size: 14.0, design: .regular, traits: [.monospacedNumbers]) @@ -4473,10 +4475,14 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch var attributedString: NSAttributedString? if let data = pasteboard.data(forPasteboardType: "private.telegramtext"), let value = chatInputStateStringFromAppSpecificString(data: data) { attributedString = value - } else if let data = pasteboard.data(forPasteboardType: kUTTypeRTF as String) { + } else if let data = pasteboard.data(forPasteboardType: "public.rtf") { attributedString = chatInputStateStringFromRTF(data, type: NSAttributedString.DocumentType.rtf) } else if let data = pasteboard.data(forPasteboardType: "com.apple.flat-rtfd") { - attributedString = chatInputStateStringFromRTF(data, type: NSAttributedString.DocumentType.rtfd) + if let _ = pasteboard.data(forPasteboardType: "com.apple.notes.richtext"), DeviceModel.current.isIpad, let htmlData = pasteboard.data(forPasteboardType: "public.html") { + attributedString = chatInputStateStringFromRTF(htmlData, type: NSAttributedString.DocumentType.html) + } else { + attributedString = chatInputStateStringFromRTF(data, type: NSAttributedString.DocumentType.rtfd) + } } if let attributedString = attributedString { diff --git a/submodules/TranslateUI/Sources/ChatTranslation.swift b/submodules/TranslateUI/Sources/ChatTranslation.swift index 8c03916535..98b317cd03 100644 --- a/submodules/TranslateUI/Sources/ChatTranslation.swift +++ b/submodules/TranslateUI/Sources/ChatTranslation.swift @@ -76,10 +76,14 @@ public struct ChatTranslationState: Codable { } private func cachedChatTranslationState(engine: TelegramEngine, peerId: EnginePeer.Id, threadId: Int64?) -> Signal { - let key = EngineDataBuffer(length: 8) - key.setInt64(0, value: peerId.id._internalGetInt64Value()) + let key: EngineDataBuffer if let threadId { + key = EngineDataBuffer(length: 16) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) key.setInt64(8, value: threadId) + } else { + key = EngineDataBuffer(length: 8) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) } return engine.data.subscribe(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: ApplicationSpecificItemCacheCollectionId.translationState, id: key)) @@ -89,10 +93,14 @@ private func cachedChatTranslationState(engine: TelegramEngine, peerId: EnginePe } private func updateChatTranslationState(engine: TelegramEngine, peerId: EnginePeer.Id, threadId: Int64?, state: ChatTranslationState?) -> Signal { - let key = EngineDataBuffer(length: 8) - key.setInt64(0, value: peerId.id._internalGetInt64Value()) + let key: EngineDataBuffer if let threadId { + key = EngineDataBuffer(length: 16) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) key.setInt64(8, value: threadId) + } else { + key = EngineDataBuffer(length: 8) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) } if let state { @@ -103,10 +111,14 @@ private func updateChatTranslationState(engine: TelegramEngine, peerId: EnginePe } public func updateChatTranslationStateInteractively(engine: TelegramEngine, peerId: EnginePeer.Id, threadId: Int64?, _ f: @escaping (ChatTranslationState?) -> ChatTranslationState?) -> Signal { - let key = EngineDataBuffer(length: 8) - key.setInt64(0, value: peerId.id._internalGetInt64Value()) + let key: EngineDataBuffer if let threadId { + key = EngineDataBuffer(length: 16) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) key.setInt64(8, value: threadId) + } else { + key = EngineDataBuffer(length: 8) + key.setInt64(0, value: peerId.id._internalGetInt64Value()) } return engine.data.get(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: ApplicationSpecificItemCacheCollectionId.translationState, id: key)) diff --git a/submodules/WebUI/Sources/WebAppController.swift b/submodules/WebUI/Sources/WebAppController.swift index 4324257087..dda6079112 100644 --- a/submodules/WebUI/Sources/WebAppController.swift +++ b/submodules/WebUI/Sources/WebAppController.swift @@ -828,7 +828,11 @@ public final class WebAppController: ViewController, AttachmentContainable { } if let webView = self.webView { - var scrollInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0) + let inputHeight = self.validLayout?.0.inputHeight ?? 0.0 + + let intrinsicBottomInset = layout.intrinsicInsets.bottom > 40.0 ? layout.intrinsicInsets.bottom : 0.0 + + var scrollInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: max(inputHeight, intrinsicBottomInset), right: 0.0) var frameBottomInset: CGFloat = 0.0 if scrollInset.bottom > 40.0 { frameBottomInset = scrollInset.bottom @@ -841,12 +845,12 @@ public final class WebAppController: ViewController, AttachmentContainable { if !webView.frame.width.isZero && webView.frame != webViewFrame { self.updateWebViewWhenStable = true } - - var bottomInset = layout.intrinsicInsets.bottom + layout.additionalInsets.bottom - if let inputHeight = self.validLayout?.0.inputHeight, inputHeight > 44.0 { - bottomInset = max(bottomInset, inputHeight) + + var viewportBottomInset = max(frameBottomInset, scrollInset.bottom) + if (self.validLayout?.0.inputHeight ?? 0.0) < 44.0 { + viewportBottomInset += layout.additionalInsets.bottom } - let viewportFrame = CGRect(origin: CGPoint(x: layout.safeInsets.left, y: topInset), size: CGSize(width: layout.size.width - layout.safeInsets.left - layout.safeInsets.right, height: max(1.0, layout.size.height - topInset - bottomInset))) + let viewportFrame = CGRect(origin: CGPoint(x: layout.safeInsets.left, y: topInset), size: CGSize(width: layout.size.width - layout.safeInsets.left - layout.safeInsets.right, height: max(1.0, layout.size.height - topInset - viewportBottomInset))) if webView.scrollView.contentInset != scrollInset { webView.scrollView.contentInset = scrollInset @@ -1061,6 +1065,10 @@ public final class WebAppController: ViewController, AttachmentContainable { } else { self.lastExpansionTimestamp = currentTimestamp controller.requestAttachmentMenuExpansion() + + Queue.mainQueue().after(0.4) { + self.webView?.setNeedsLayout() + } } case "web_app_close": controller.dismiss()