mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Various improvements
This commit is contained in:
parent
af9c7ed5d3
commit
0337de2cc3
@ -10546,4 +10546,5 @@ Sorry for the inconvenience.";
|
||||
"Premium.Wallpapers" = "Wallpapers for Both Sides";
|
||||
"Premium.WallpapersInfo" = "Set custom wallpapers for you and your chat partner.";
|
||||
|
||||
"MediaEditor.VideoRemovalConfirmation" = "Are you sure you want to delete video message?";
|
||||
"MediaEditor.HoldToRecordVideo" = "Hold to record video";
|
||||
|
@ -75,6 +75,7 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
|
||||
public var present: (ViewController) -> Void = { _ in }
|
||||
public var push: (ViewController) -> Void = { _ in }
|
||||
|
||||
public var canInteract: () -> Bool = { return true }
|
||||
public var hasSelectionChanged: (Bool) -> Void = { _ in }
|
||||
var selectionChanged: (DrawingEntity?) -> Void = { _ in }
|
||||
var requestedMenuForEntityView: (DrawingEntityView, Bool) -> Void = { _, _ in }
|
||||
@ -633,6 +634,9 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
|
||||
}
|
||||
|
||||
@objc private func handleTap(_ gestureRecognzier: UITapGestureRecognizer) {
|
||||
guard self.canInteract() else {
|
||||
return
|
||||
}
|
||||
let location = gestureRecognzier.location(in: self)
|
||||
if let entityView = self.entity(at: location) {
|
||||
self.selectEntity(entityView.entity)
|
||||
@ -757,6 +761,9 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
|
||||
}
|
||||
|
||||
public func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
|
||||
guard self.canInteract() else {
|
||||
return
|
||||
}
|
||||
let location = gestureRecognizer.location(in: self)
|
||||
if let selectedEntityView = self.selectedEntityView, let selectionView = selectedEntityView.selectionView {
|
||||
if !self.hasBin {
|
||||
@ -839,6 +846,9 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
|
||||
}
|
||||
|
||||
public func handlePinch(_ gestureRecognizer: UIPinchGestureRecognizer) {
|
||||
guard self.canInteract() else {
|
||||
return
|
||||
}
|
||||
if !self.hasSelection, let mediaEntityView = self.subviews.first(where: { $0 is DrawingEntityMediaView }) as? DrawingEntityMediaView {
|
||||
mediaEntityView.handlePinch(gestureRecognizer)
|
||||
} else if let selectedEntityView = self.selectedEntityView, let selectionView = selectedEntityView.selectionView {
|
||||
@ -847,6 +857,9 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
|
||||
}
|
||||
|
||||
public func handleRotate(_ gestureRecognizer: UIRotationGestureRecognizer) {
|
||||
guard self.canInteract() else {
|
||||
return
|
||||
}
|
||||
if !self.hasSelection, let mediaEntityView = self.subviews.first(where: { $0 is DrawingEntityMediaView }) as? DrawingEntityMediaView {
|
||||
mediaEntityView.handleRotate(gestureRecognizer)
|
||||
} else if let selectedEntityView = self.selectedEntityView, let selectionView = selectedEntityView.selectionView {
|
||||
|
@ -105,6 +105,8 @@ public final class EntityVideoRecorder {
|
||||
self.previewView.resetPlaceholder(front: true)
|
||||
entityView.animateInsertion()
|
||||
}
|
||||
|
||||
self.entitiesView?.selectEntity(nil)
|
||||
}
|
||||
|
||||
var start: Double = 0.0
|
||||
@ -134,11 +136,9 @@ public final class EntityVideoRecorder {
|
||||
|
||||
public func stopRecording(save: Bool, completion: @escaping () -> Void = {}) {
|
||||
var save = save
|
||||
var remove = false
|
||||
let duration = CACurrentMediaTime() - self.start
|
||||
if duration < 0.2 {
|
||||
save = false
|
||||
remove = true
|
||||
}
|
||||
self.recordingDisposable.set((self.camera.stopRecording()
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||
@ -172,18 +172,22 @@ public final class EntityVideoRecorder {
|
||||
}
|
||||
update()
|
||||
}
|
||||
} else {
|
||||
self.entitiesView?.remove(uuid: self.entity.uuid, animated: true)
|
||||
if remove {
|
||||
mediaEditor.setAdditionalVideo(nil, positionChanges: [])
|
||||
}
|
||||
|
||||
self.camera.stopCapture(invalidate: true)
|
||||
self.mediaEditor?.maybeUnmuteVideo()
|
||||
completion()
|
||||
}
|
||||
}))
|
||||
|
||||
if !save {
|
||||
self.camera.stopCapture(invalidate: true)
|
||||
|
||||
self.mediaEditor?.maybeUnmuteVideo()
|
||||
|
||||
self.entitiesView?.remove(uuid: self.entity.uuid, animated: true)
|
||||
self.mediaEditor?.setAdditionalVideo(nil, positionChanges: [])
|
||||
|
||||
completion()
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
public func togglePosition() {
|
||||
|
@ -13,6 +13,8 @@ extension MediaEditorScreen {
|
||||
|
||||
private var recorder: EntityVideoRecorder?
|
||||
|
||||
var isLocked = false
|
||||
|
||||
init(controller: MediaEditorScreen) {
|
||||
self.controller = controller
|
||||
}
|
||||
@ -28,7 +30,7 @@ extension MediaEditorScreen {
|
||||
context: controller.context,
|
||||
forceTheme: defaultDarkColorPresentationTheme,
|
||||
title: nil,
|
||||
text: "Are you sure you want to delete video message?",
|
||||
text: presentationData.strings.MediaEditor_VideoRemovalConfirmation,
|
||||
actions: [
|
||||
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||
}),
|
||||
@ -77,6 +79,7 @@ extension MediaEditorScreen {
|
||||
return
|
||||
}
|
||||
self.recorder = nil
|
||||
self.isLocked = false
|
||||
self.controller?.node.requestLayout(forceUpdate: true, transition: .easeInOut(duration: 0.2))
|
||||
})
|
||||
|
||||
@ -122,5 +125,9 @@ extension MediaEditorScreen {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var isActive: Bool {
|
||||
return self.status != nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -667,7 +667,7 @@ final class MediaEditorScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
let isRecordingAdditionalVideo = controller.node.recording.status != nil
|
||||
let isRecordingAdditionalVideo = controller.node.recording.isActive
|
||||
|
||||
self.component = component
|
||||
self.state = state
|
||||
@ -715,8 +715,11 @@ final class MediaEditorScreenComponent: Component {
|
||||
size: CGSize(width: 33.0, height: 33.0)
|
||||
)
|
||||
),
|
||||
action: {
|
||||
guard let controller = environment.controller() as? MediaEditorScreen else {
|
||||
action: { [weak self] in
|
||||
guard let environment = self?.environment, let controller = environment.controller() as? MediaEditorScreen else {
|
||||
return
|
||||
}
|
||||
guard !controller.node.recording.isActive else {
|
||||
return
|
||||
}
|
||||
controller.maybePresentDiscardAlert()
|
||||
@ -747,8 +750,11 @@ final class MediaEditorScreenComponent: Component {
|
||||
icon: UIImage(bundleImageName: "Media Editor/Next")!,
|
||||
title: doneButtonTitle.uppercased())),
|
||||
effectAlignment: .center,
|
||||
action: {
|
||||
guard let controller = environment.controller() as? MediaEditorScreen else {
|
||||
action: { [weak self] in
|
||||
guard let environment = self?.environment, let controller = environment.controller() as? MediaEditorScreen else {
|
||||
return
|
||||
}
|
||||
guard !controller.node.recording.isActive else {
|
||||
return
|
||||
}
|
||||
guard controller.checkCaptionLimit() else {
|
||||
@ -798,7 +804,13 @@ final class MediaEditorScreenComponent: Component {
|
||||
image: state.image(.draw),
|
||||
size: CGSize(width: 30.0, height: 30.0)
|
||||
)),
|
||||
action: {
|
||||
action: { [weak self] in
|
||||
guard let environment = self?.environment, let controller = environment.controller() as? MediaEditorScreen else {
|
||||
return
|
||||
}
|
||||
guard !controller.node.recording.isActive else {
|
||||
return
|
||||
}
|
||||
openDrawing(.drawing)
|
||||
}
|
||||
)),
|
||||
@ -827,7 +839,13 @@ final class MediaEditorScreenComponent: Component {
|
||||
image: state.image(.text),
|
||||
size: CGSize(width: 30.0, height: 30.0)
|
||||
)),
|
||||
action: {
|
||||
action: { [weak self] in
|
||||
guard let environment = self?.environment, let controller = environment.controller() as? MediaEditorScreen else {
|
||||
return
|
||||
}
|
||||
guard !controller.node.recording.isActive else {
|
||||
return
|
||||
}
|
||||
openDrawing(.text)
|
||||
}
|
||||
)),
|
||||
@ -856,7 +874,13 @@ final class MediaEditorScreenComponent: Component {
|
||||
image: state.image(.sticker),
|
||||
size: CGSize(width: 30.0, height: 30.0)
|
||||
)),
|
||||
action: {
|
||||
action: { [weak self] in
|
||||
guard let environment = self?.environment, let controller = environment.controller() as? MediaEditorScreen else {
|
||||
return
|
||||
}
|
||||
guard !controller.node.recording.isActive else {
|
||||
return
|
||||
}
|
||||
openDrawing(.sticker)
|
||||
}
|
||||
)),
|
||||
@ -885,7 +909,13 @@ final class MediaEditorScreenComponent: Component {
|
||||
image: state.image(.tools),
|
||||
size: CGSize(width: 30.0, height: 30.0)
|
||||
)),
|
||||
action: {
|
||||
action: { [weak self] in
|
||||
guard let environment = self?.environment, let controller = environment.controller() as? MediaEditorScreen else {
|
||||
return
|
||||
}
|
||||
guard !controller.node.recording.isActive else {
|
||||
return
|
||||
}
|
||||
openTools()
|
||||
}
|
||||
)),
|
||||
@ -1055,12 +1085,6 @@ final class MediaEditorScreenComponent: Component {
|
||||
if case let .video(_, _, _, additionalPath, _, _, _, _, _) = subject, additionalPath != nil {
|
||||
canRecordVideo = false
|
||||
}
|
||||
// if case let .asset(asset) = subject, asset.mediaType == .image {
|
||||
// canRecordVideo = false
|
||||
// }
|
||||
// if case .image = subject {
|
||||
// canRecordVideo = false
|
||||
// }
|
||||
}
|
||||
|
||||
self.inputPanel.parentState = state
|
||||
@ -1105,8 +1129,12 @@ final class MediaEditorScreenComponent: Component {
|
||||
}
|
||||
controller.node.recording.setMediaRecordingActive(isActive, finished: finished, sourceView: sourceView)
|
||||
} : nil,
|
||||
lockMediaRecording: {
|
||||
|
||||
lockMediaRecording: { [weak controller, weak self] in
|
||||
guard let controller, let self else {
|
||||
return
|
||||
}
|
||||
controller.node.recording.isLocked = true
|
||||
self.state?.updated(transition: .easeInOut(duration: 0.2))
|
||||
},
|
||||
stopAndPreviewMediaRecording: { [weak controller] in
|
||||
guard let controller else {
|
||||
@ -1197,7 +1225,7 @@ final class MediaEditorScreenComponent: Component {
|
||||
},
|
||||
audioRecorder: nil,
|
||||
videoRecordingStatus: controller.node.recording.status,
|
||||
isRecordingLocked: false,
|
||||
isRecordingLocked: controller.node.recording.isLocked,
|
||||
hasRecordedVideo: mediaEditor?.values.additionalVideoPath != nil,
|
||||
recordedAudioPreview: nil,
|
||||
hasRecordedVideoPreview: false,
|
||||
@ -1512,12 +1540,16 @@ final class MediaEditorScreenComponent: Component {
|
||||
component: AnyComponent(CameraButton(
|
||||
content: saveContentComponent,
|
||||
action: { [weak self] in
|
||||
guard let environment = self?.environment, let controller = environment.controller() as? MediaEditorScreen else {
|
||||
return
|
||||
}
|
||||
guard !controller.node.recording.isActive else {
|
||||
return
|
||||
}
|
||||
if let view = self?.saveButton.findTaggedView(tag: saveButtonTag) as? LottieAnimationComponent.View {
|
||||
view.playOnce()
|
||||
}
|
||||
if let controller = environment.controller() as? MediaEditorScreen {
|
||||
controller.requestSave()
|
||||
}
|
||||
controller.requestSave()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
@ -1578,16 +1610,21 @@ final class MediaEditorScreenComponent: Component {
|
||||
transition: transition,
|
||||
component: AnyComponent(CameraButton(
|
||||
content: muteContentComponent,
|
||||
action: { [weak state, weak mediaEditor] in
|
||||
action: { [weak self, weak state, weak mediaEditor] in
|
||||
guard let environment = self?.environment, let controller = environment.controller() as? MediaEditorScreen else {
|
||||
return
|
||||
}
|
||||
guard !controller.node.recording.isActive else {
|
||||
return
|
||||
}
|
||||
|
||||
if let mediaEditor {
|
||||
state?.muteDidChange = true
|
||||
let isMuted = !mediaEditor.values.videoIsMuted
|
||||
mediaEditor.setVideoIsMuted(isMuted)
|
||||
state?.updated()
|
||||
|
||||
if let controller = environment.controller() as? MediaEditorScreen {
|
||||
controller.node.presentMutedTooltip()
|
||||
}
|
||||
controller.node.presentMutedTooltip()
|
||||
}
|
||||
}
|
||||
)),
|
||||
@ -1655,7 +1692,13 @@ final class MediaEditorScreenComponent: Component {
|
||||
transition: transition,
|
||||
component: AnyComponent(CameraButton(
|
||||
content: playbackContentComponent,
|
||||
action: { [weak mediaEditor, weak state] in
|
||||
action: { [weak self, weak mediaEditor, weak state] in
|
||||
guard let environment = self?.environment, let controller = environment.controller() as? MediaEditorScreen else {
|
||||
return
|
||||
}
|
||||
guard !controller.node.recording.isActive else {
|
||||
return
|
||||
}
|
||||
if let mediaEditor {
|
||||
state?.playbackDidChange = true
|
||||
mediaEditor.togglePlayback()
|
||||
@ -2094,6 +2137,13 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
self.mediaEditor?.setAdditionalVideo(nil, positionChanges: [])
|
||||
}
|
||||
}
|
||||
self.entitiesView.canInteract = { [weak self] in
|
||||
if let self, let controller = self.controller {
|
||||
return !controller.node.recording.isActive
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
self.availableReactionsDisposable = (allowedStoryReactions(context: controller.context)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] reactions in
|
||||
@ -2562,6 +2612,9 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
}
|
||||
|
||||
@objc func handleTap(_ gestureRecognizer: UITapGestureRecognizer) {
|
||||
guard !self.recording.isActive else {
|
||||
return
|
||||
}
|
||||
let location = gestureRecognizer.location(in: self.view)
|
||||
var entitiesHitTestResult = self.entitiesView.hitTest(self.view.convert(location, to: self.entitiesView), with: nil)
|
||||
if entitiesHitTestResult is DrawingMediaEntityView {
|
||||
|
@ -1671,7 +1671,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
var animateIn = false
|
||||
if mediaRecordingPanelView.superview == nil {
|
||||
animateIn = true
|
||||
self.insertSubview(mediaRecordingPanelView, aboveSubview: self.fieldBackgroundView)
|
||||
self.insertSubview(mediaRecordingPanelView, aboveSubview: self.textClippingView)
|
||||
|
||||
self.mediaRecordingVibrancyContainer.addSubview(mediaRecordingPanelView.vibrancyContainer)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user