Various fixes

This commit is contained in:
Ilya Laktyushin 2023-09-17 15:45:34 +04:00
parent 0f6f18bd39
commit abb3749f8a
6 changed files with 106 additions and 39 deletions

View file

@ -10017,3 +10017,5 @@ Sorry for the inconvenience.";
"Stats.Boosts.OverviewHeader" = "OVERVIEW";
"Stats.Boosts.LinkHeader" = "LINK FOR BOOSTING";
"Stats.Boosts.LinkInfo" = "Share this link with your subscribers to get more boosts.";
"Conversation.SaveToFiles" = "Save to Files";

View file

@ -353,6 +353,9 @@ public final class DrawingStickerEntityView: DrawingEntityView {
self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))()
self.imageNode.frame = imageFrame
if let animationNode = self.animationNode {
if self.isReaction {
animationNode.cornerRadius = floor(imageSize.width * 0.03)
}
animationNode.frame = imageFrame
animationNode.updateLayout(size: imageSize)
@ -363,10 +366,9 @@ public final class DrawingStickerEntityView: DrawingEntityView {
}
if let videoNode = self.videoNode {
let videoSize = self.dimensions.aspectFitted(boundingSize)
videoNode.cornerRadius = floor(videoSize.width * 0.03)
videoNode.frame = CGRect(origin: CGPoint(x: floor((size.width - videoSize.width) * 0.5), y: floor((size.height - videoSize.height) * 0.5)), size: videoSize)
videoNode.updateLayout(size: videoSize, transition: .immediate)
videoNode.cornerRadius = floor(imageSize.width * 0.03)
videoNode.frame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) * 0.5), y: floor((size.height - imageSize.height) * 0.5)), size: imageSize)
videoNode.updateLayout(size: imageSize, transition: .immediate)
}
self.update(animated: false)

View file

@ -652,7 +652,7 @@ public final class MediaEditor {
if self.sourceIsVideo {
start = self.values.videoTrimRange?.lowerBound ?? 0.0
} else {
start = self.values.audioTrackTrimRange?.lowerBound ?? 0.0
start = (self.values.audioTrackOffset ?? 0.0) + (self.values.audioTrackTrimRange?.lowerBound ?? 0.0)
}
let targetTime = CMTime(seconds: start, preferredTimescale: CMTimeScale(1000))
self.player?.seek(to: targetTime)
@ -846,11 +846,7 @@ public final class MediaEditor {
self.audioPlayer?.seek(to: self.audioTime(for: targetPosition), toleranceBefore: .zero, toleranceAfter: .zero)
}
}
private func setupAudioPlayback() {
}
private var audioDelayTimer: SwiftSignalKit.Timer?
private func audioDelay(for time: CMTime) -> Double? {
var time = time
@ -1052,6 +1048,17 @@ public final class MediaEditor {
return values.withUpdatedAudioTrack(audioTrack).withUpdatedAudioTrackSamples(nil).withUpdatedAudioTrackTrimRange(nil).withUpdatedAudioTrackVolume(nil).withUpdatedAudioTrackOffset(nil)
}
if let audioPlayer = self.audioPlayer {
audioPlayer.pause()
self.destroyTimeObservers()
self.audioPlayer = nil
if !self.sourceIsVideo {
self.playerPromise.set(.single(nil))
}
}
if let audioTrack {
let path = fullDraftPath(peerId: self.context.account.peerId, path: audioTrack.path)
let audioAsset = AVURLAsset(url: URL(fileURLWithPath: path))
@ -1066,16 +1073,6 @@ public final class MediaEditor {
if !self.sourceIsVideo {
self.playerPromise.set(.single(player))
}
} else if let audioPlayer = self.audioPlayer {
audioPlayer.pause()
self.destroyTimeObservers()
self.audioPlayer = nil
if !self.sourceIsVideo {
self.playerPromise.set(.single(nil))
}
}
}

View file

@ -760,9 +760,11 @@ final class MediaEditorScreenComponent: Component {
if controller.isEditingStory {
controller.requestCompletion(animated: true)
} else {
controller.openPrivacySettings(completion: { [weak controller] in
controller?.requestCompletion(animated: true)
})
if controller.checkIfCompletionIsAllowed() {
controller.openPrivacySettings(completion: { [weak controller] in
controller?.requestCompletion(animated: true)
})
}
}
}
)),
@ -3101,7 +3103,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
func presentAudioPicker() {
var isSettingTrack = false
self.controller?.present(legacyICloudFilePicker(theme: self.presentationData.theme, mode: .import, documentTypes: ["public.mp3"], forceDarkTheme: true, dismissed: { [weak self] in
self.controller?.present(legacyICloudFilePicker(theme: self.presentationData.theme, mode: .import, documentTypes: ["public.mp3", "public.mpeg-4-audio", "public.aac-audio"], forceDarkTheme: true, dismissed: { [weak self] in
if let self {
Queue.mainQueue().after(0.1) {
if !isSettingTrack {
@ -4188,6 +4190,24 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
self.present(controller, in: .window(.root))
})
}
fileprivate func presentUnavailableReactionPremiumSuggestion(file: TelegramMediaFile) {
self.hapticFeedback.error()
self.dismissAllTooltips()
let context = self.context
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, loop: true, title: nil, text: presentationData.strings.Story_Editor_TooltipPremiumReaction, undoText: nil, customAction: nil), elevatedLayout: true, position: .top, animateInAsReplacement: false, blurred: true, action: { [weak self] action in
if case .info = action, let self {
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .storiesExpirationDurations, forceDark: true, dismissed: nil)
self.push(controller)
}
return false
})
self.present(controller, in: .window(.root))
}
fileprivate func presentCaptionLimitPremiumSuggestion(isPremium: Bool) {
self.dismissAllTooltips()
@ -4442,6 +4462,19 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
}
return true
}
func checkIfCompletionIsAllowed() -> Bool {
if !self.context.isPremium {
let entities = self.node.entitiesView.entities.filter { !($0 is DrawingMediaEntity) }
for entity in entities {
if let stickerEntity = entity as? DrawingStickerEntity, case let .file(file, type) = stickerEntity.content, case let .reaction(reaction, _) = type, case .custom = reaction {
self.presentUnavailableReactionPremiumSuggestion(file: file)
return false
}
}
}
return true
}
private var didComplete = false
func requestCompletion(animated: Bool, skipSendCheck: Bool = false) {

View file

@ -4536,9 +4536,21 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
var file: TelegramMediaFile?
var title: String?
var performer: String?
for media in message.media {
if let mediaFile = media as? TelegramMediaFile, mediaFile.isMusic {
file = mediaFile
for attribute in mediaFile.attributes {
if case let .Audio(_, _, titleValue, performerValue, _) = attribute {
if let titleValue, !titleValue.isEmpty {
title = titleValue
}
if let performerValue, !performerValue.isEmpty {
performer = performerValue
}
}
}
}
}
guard let file else {
@ -4602,28 +4614,49 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let audioUrl = URL(fileURLWithPath: symlinkPath)
let audioAsset = AVURLAsset(url: audioUrl)
var fileExtension = "mp3"
if let filename = file.fileName {
if let dotIndex = filename.lastIndex(of: ".") {
fileExtension = String(filename[filename.index(after: dotIndex)...])
}
}
var nameComponents: [String] = []
var artist: String?
var title: String?
for data in audioAsset.commonMetadata {
if data.commonKey == .commonKeyArtist {
artist = data.stringValue
if let title {
if let performer {
nameComponents.append(performer)
}
if data.commonKey == .commonKeyTitle {
title = data.stringValue
}
}
if let artist, !artist.isEmpty {
nameComponents.append(artist)
}
if let title, !title.isEmpty {
nameComponents.append(title)
} else {
var artist: String?
var title: String?
for data in audioAsset.commonMetadata {
if data.commonKey == .commonKeyArtist {
artist = data.stringValue
}
if data.commonKey == .commonKeyTitle {
title = data.stringValue
}
}
if let artist, !artist.isEmpty {
nameComponents.append(artist)
}
if let title, !title.isEmpty {
nameComponents.append(title)
}
if nameComponents.isEmpty, var filename = file.fileName {
if let dotIndex = filename.lastIndex(of: ".") {
filename = String(filename[..<dotIndex])
}
nameComponents.append(filename)
}
}
if !nameComponents.isEmpty {
try? FileManager.default.removeItem(atPath: symlinkPath)
let filename = "\(nameComponents.joined(separator: " ")).mp3"
symlinkPath = symlinkPath.replacingOccurrences(of: audioUrl.lastPathComponent, with: filename)
let fileName = "\(nameComponents.joined(separator: " ")).\(fileExtension)"
symlinkPath = symlinkPath.replacingOccurrences(of: audioUrl.lastPathComponent, with: fileName)
let _ = try? FileManager.default.linkItem(atPath: data.path, toPath: symlinkPath)
}

View file

@ -1174,7 +1174,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
for media in message.media {
if let file = media as? TelegramMediaFile {
if file.isMusic {
actions.append(.action(ContextMenuActionItem(text: "Save to Files", icon: { theme in
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_SaveToFiles, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
controllerInteraction.saveMediaToFiles(message.id)