diff --git a/submodules/TelegramUI/Components/AudioWaveformNode/Sources/AudioWaveformNode.swift b/submodules/TelegramUI/Components/AudioWaveformNode/Sources/AudioWaveformNode.swift index 965cafee55..35fdd70885 100644 --- a/submodules/TelegramUI/Components/AudioWaveformNode/Sources/AudioWaveformNode.swift +++ b/submodules/TelegramUI/Components/AudioWaveformNode/Sources/AudioWaveformNode.swift @@ -6,13 +6,15 @@ import AudioWaveform private final class AudioWaveformNodeParameters: NSObject { let waveform: AudioWaveform? + let drawFakeSamplesIfNeeded: Bool let color: UIColor? let gravity: AudioWaveformNode.Gravity? let progress: CGFloat? let trimRange: Range? - init(waveform: AudioWaveform?, color: UIColor?, gravity: AudioWaveformNode.Gravity?, progress: CGFloat?, trimRange: Range?) { + init(waveform: AudioWaveform?, drawFakeSamplesIfNeeded: Bool, color: UIColor?, gravity: AudioWaveformNode.Gravity?, progress: CGFloat?, trimRange: Range?) { self.waveform = waveform + self.drawFakeSamplesIfNeeded = drawFakeSamplesIfNeeded self.color = color self.gravity = gravity self.progress = progress @@ -31,6 +33,7 @@ public final class AudioWaveformNode: ASDisplayNode { private var waveform: AudioWaveform? private var color: UIColor? private var gravity: Gravity? + public var drawFakeSamplesIfNeeded = false public var progress: CGFloat? { didSet { @@ -77,7 +80,7 @@ public final class AudioWaveformNode: ASDisplayNode { } override public func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? { - return AudioWaveformNodeParameters(waveform: self.waveform, color: self.color, gravity: self.gravity, progress: self.progress, trimRange: self.trimRange) + return AudioWaveformNodeParameters(waveform: self.waveform, drawFakeSamplesIfNeeded: self.drawFakeSamplesIfNeeded, color: self.color, gravity: self.gravity, progress: self.progress, trimRange: self.trimRange) } @objc override public class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled: () -> Bool, isRasterizing: Bool) { @@ -117,18 +120,12 @@ public final class AudioWaveformNode: ASDisplayNode { let numSamples = Int(floor(size.width / (sampleWidth + distance))) - let adjustedSamplesMemory = malloc(numSamples * 2)! - let adjustedSamples = adjustedSamplesMemory.assumingMemoryBound(to: UInt16.self) - defer { - free(adjustedSamplesMemory) - } - memset(adjustedSamplesMemory, 0, numSamples * 2) - + var adjustedSamples = Array(repeating: 0, count: numSamples) var generateFakeSamples = false var bins: [UInt16: Int] = [:] for i in 0 ..< maxReadSamples { - let index = i * numSamples / maxReadSamples + let index = min(i * numSamples / max(1, maxReadSamples), numSamples - 1) let sample = samples[i] if adjustedSamples[index] < sample { adjustedSamples[index] = sample @@ -158,7 +155,7 @@ public final class AudioWaveformNode: ASDisplayNode { topCountPercent = Float(topCount) / Float(totalCount) } - if topCountPercent > 0.75 { + if parameters.drawFakeSamplesIfNeeded && topCountPercent > 0.75 { generateFakeSamples = true } diff --git a/submodules/TelegramUI/Components/MediaScrubberComponent/Sources/MediaScrubberComponent.swift b/submodules/TelegramUI/Components/MediaScrubberComponent/Sources/MediaScrubberComponent.swift index 70af5bfa7f..1df1b22a8e 100644 --- a/submodules/TelegramUI/Components/MediaScrubberComponent/Sources/MediaScrubberComponent.swift +++ b/submodules/TelegramUI/Components/MediaScrubberComponent/Sources/MediaScrubberComponent.swift @@ -1672,20 +1672,43 @@ public class TrimView: UIView { self.rightHandleView.addSubview(self.rightCapsuleView) self.addSubview(self.borderView) - self.zoneView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.handleZoneHandlePan(_:)))) - self.leftHandleView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.handleLeftHandlePan(_:)))) - self.rightHandleView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.handleRightHandlePan(_:)))) + let zoneHandlePanGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.handleZoneHandlePan(_:))) + zoneHandlePanGesture.minimumPressDuration = 0.0 + zoneHandlePanGesture.allowableMovement = .infinity + + let leftHandlePanGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLeftHandlePan(_:))) + leftHandlePanGesture.minimumPressDuration = 0.0 + leftHandlePanGesture.allowableMovement = .infinity + + let rightHandlePanGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.handleRightHandlePan(_:))) + rightHandlePanGesture.minimumPressDuration = 0.0 + rightHandlePanGesture.allowableMovement = .infinity + + self.zoneView.addGestureRecognizer(zoneHandlePanGesture) + self.leftHandleView.addGestureRecognizer(leftHandlePanGesture) + self.rightHandleView.addGestureRecognizer(rightHandlePanGesture) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - @objc private func handleZoneHandlePan(_ gestureRecognizer: UIPanGestureRecognizer) { + private var panStartLocation: CGPoint? + + @objc private func handleZoneHandlePan(_ gestureRecognizer: UILongPressGestureRecognizer) { guard let params = self.params else { return } - let translation = gestureRecognizer.translation(in: self) + + let location = gestureRecognizer.location(in: self) + if case .began = gestureRecognizer.state { + self.panStartLocation = location + } + + let translation = CGPoint( + x: location.x - (self.panStartLocation?.x ?? 0.0), + y: location.y - (self.panStartLocation?.y ?? 0.0) + ) let start = handleWidth / 2.0 let end = self.frame.width - handleWidth / 2.0 @@ -1706,6 +1729,7 @@ public class TrimView: UIView { transition = .easeInOut(duration: 0.25) } case .ended, .cancelled: + self.panStartLocation = nil self.isPanningTrimHandle = false self.trimUpdated(startValue, endValue, false, true) transition = .easeInOut(duration: 0.25) @@ -1713,15 +1737,15 @@ public class TrimView: UIView { break } - gestureRecognizer.setTranslation(.zero, in: self) self.updated(transition) } - @objc private func handleLeftHandlePan(_ gestureRecognizer: UIPanGestureRecognizer) { + @objc private func handleLeftHandlePan(_ gestureRecognizer: UILongPressGestureRecognizer) { guard let params = self.params else { return } let location = gestureRecognizer.location(in: self) + let start = handleWidth / 2.0 let end = params.scrubberSize.width - handleWidth / 2.0 let length = end - start @@ -1746,6 +1770,7 @@ public class TrimView: UIView { transition = .easeInOut(duration: 0.25) } case .ended, .cancelled: + self.panStartLocation = nil self.isPanningTrimHandle = false self.trimUpdated(startValue, endValue, false, true) transition = .easeInOut(duration: 0.25) @@ -1755,7 +1780,7 @@ public class TrimView: UIView { self.updated(transition) } - @objc private func handleRightHandlePan(_ gestureRecognizer: UIPanGestureRecognizer) { + @objc private func handleRightHandlePan(_ gestureRecognizer: UILongPressGestureRecognizer) { guard let params = self.params else { return } @@ -1784,6 +1809,7 @@ public class TrimView: UIView { transition = .easeInOut(duration: 0.25) } case .ended, .cancelled: + self.panStartLocation = nil self.isPanningTrimHandle = false self.trimUpdated(startValue, endValue, true, true) transition = .easeInOut(duration: 0.25) diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift index 87a5746086..51646ef38c 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift @@ -496,6 +496,7 @@ extension ChatControllerImpl { }) } + //TODO:localize if let recordedMediaPreview = self.presentationInterfaceState.interfaceState.mediaDraftState, case let .audio(audio) = recordedMediaPreview, let _ = audio.trimRange { self.present( textAlertController( @@ -503,7 +504,7 @@ extension ChatControllerImpl { title: "Trim to selected range?", text: "Audio outside that range will be discarded, and recording will start immediately.", actions: [ - TextAlertAction(type: .genericAction, title: "Cancel", action: {}), + TextAlertAction(type: .genericAction, title: self.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: "Proceed", action: { proceed() })