Improve media message editing

This commit is contained in:
Ilya Laktyushin 2020-11-18 15:48:39 +04:00
parent 590cc53737
commit becdf72cba
15 changed files with 4356 additions and 4359 deletions

View File

@ -5892,11 +5892,6 @@ Sorry for the inconvenience.";
"ChatSettings.WidgetSettings" = "Widget";
"Conversation.AddCaption" = "Add a Caption";
"Conversation.EditCaption" = "Edit Caption";
"Conversation.EditThisPhoto" = "Edit This Photo";
"Conversation.ReplacePhoto" = "Replace Photo";
"Conversation.ReplaceFile" = "Replace File";
"Conversation.SendAsNewPhoto" = "Send as New Photo";
"Conversation.EditingPhotoPanelTitle" = "Edit Photo";
"Conversation.TextCopied" = "Text copied to clipboard";

View File

@ -204,9 +204,11 @@
controllerWindow.hidden = false;
galleryController.view.clipsToBounds = true;
// if (paint) {
// [model presentPhotoEditorForItem:galleryItem tab:TGPhotoEditorPaintTab];
// }
if (paint) {
TGDispatchAfter(0.05, dispatch_get_main_queue(), ^{
[model presentPhotoEditorForItem:galleryItem tab:TGPhotoEditorPaintTab];
});
}
}
@end

View File

@ -472,48 +472,7 @@ public struct PresentationResourcesChat {
public static func chatInputPanelEditAttachmentButtonImage(_ theme: PresentationTheme) -> UIImage? {
return theme.image(PresentationResourceKey.chatInputPanelEditAttachmentButtonImage.rawValue, { theme in
if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconAttachment"), color: theme.chat.inputPanel.panelControlColor) {
return generateImage(image.size, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
let imageRect = CGRect(origin: CGPoint(), size: image.size)
context.saveGState()
context.translateBy(x: imageRect.midX, y: imageRect.midY)
context.scaleBy(x: 1.0, y: -1.0)
context.translateBy(x: -imageRect.midX, y: -imageRect.midY)
context.draw(image.cgImage!, in: imageRect)
context.restoreGState()
context.setFillColor(UIColor.clear.cgColor)
context.setBlendMode(.copy)
let circleSide: CGFloat = 15.0
let circleRect = CGRect(origin: CGPoint(x: size.width - circleSide - 1.0, y: size.height - circleSide - 1.0), size: CGSize(width: circleSide, height: circleSide))
context.fillEllipse(in: circleRect)
context.translateBy(x: circleRect.minX, y: circleRect.minY)
context.saveGState()
context.translateBy(x: -1.0, y: -5.0)
let _ = try? drawSvgPath(context, path: "M6,0.909090909 L6,14 L13,7.45454545 Z ")
context.restoreGState()
context.setBlendMode(.normal)
context.setFillColor(theme.chat.inputPanel.panelControlAccentColor.cgColor)
let _ = try? drawSvgPath(context, path: "M6.675,-1.99172619 L11.3939989,2.72727273 L6.675,7.44627164 L6.675,-1.99172619 Z ")
context.setStrokeColor(theme.chat.inputPanel.panelControlAccentColor.cgColor)
context.setLineWidth(1.65)
context.setLineCap(.round)
context.saveGState()
context.translateBy(x: 7.5, y: 7.5)
context.scaleBy(x: -1.0, y: -1.0)
context.translateBy(x: -7.5, y: -7.5)
let _ = try? drawSvgPath(context, path: "M7.5,12.2727273 C10.1359045,12.2727273 12.2727273,10.1359045 12.2727273,7.5 C12.2727273,4.86409551 10.1359045,2.72727273 7.5,2.72727273 C4.86409551,2.72727273 2.72727273,4.86409551 2.72727273,7.5 S ")
context.restoreGState()
})
} else {
return nil
}
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/Replace"), color: theme.chat.inputPanel.panelControlAccentColor)
})
}

View File

@ -1,7 +1,7 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
},
"properties" : {
"provides-namespace" : true

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "ic_replace.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -5979,6 +5979,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
chatController.canReadHistory.set(false)
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, passthroughTouches: true)), items: .single(items), reactionItems: [], gesture: gesture)
strongSelf.presentInGlobalOverlay(contextController)
}, editMessageMedia: { [weak self] messageId, draw in
if let strongSelf = self {
strongSelf.controllerInteraction?.editMessageMedia(messageId, draw)
}
}, statuses: ChatPanelInterfaceInteractionStatuses(editingMessage: self.editingMessage.get(), startingBot: self.startingBot.get(), unblockingPeer: self.unblockingPeer.get(), searching: self.searching.get(), loadingMessage: self.loadingMessage.get(), inlineSearch: self.performingInlineSearch.get()))
do {

View File

@ -126,6 +126,7 @@ final class ChatPanelInterfaceInteraction {
let scrollToTop: () -> Void
let viewReplies: (MessageId?, ChatReplyThreadMessage) -> Void
let activatePinnedListPreview: (ASDisplayNode, ContextGesture) -> Void
let editMessageMedia: (MessageId, Bool) -> Void
let statuses: ChatPanelInterfaceInteractionStatuses?
init(
@ -205,6 +206,7 @@ final class ChatPanelInterfaceInteraction {
scrollToTop: @escaping () -> Void,
viewReplies: @escaping (MessageId?, ChatReplyThreadMessage) -> Void,
activatePinnedListPreview: @escaping (ASDisplayNode, ContextGesture) -> Void,
editMessageMedia: @escaping (MessageId, Bool) -> Void,
statuses: ChatPanelInterfaceInteractionStatuses?
) {
self.setupReplyMessage = setupReplyMessage
@ -283,6 +285,7 @@ final class ChatPanelInterfaceInteraction {
self.scrollToTop = scrollToTop
self.viewReplies = viewReplies
self.activatePinnedListPreview = activatePinnedListPreview
self.editMessageMedia = editMessageMedia
self.statuses = statuses
}
}

View File

@ -132,6 +132,7 @@ final class ChatRecentActionsController: TelegramBaseController {
}, scrollToTop: {
}, viewReplies: { _, _ in
}, activatePinnedListPreview: { _, _ in
}, editMessageMedia: { _, _ in
}, statuses: nil)
self.navigationItem.titleView = self.titleView

View File

@ -1562,7 +1562,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
self.actionButtons.sendButton.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2)
self.actionButtons.sendButtonRadialStatusNode?.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2)
self.actionButtons.sendButtonRadialStatusNode?.alpha = 0.0
self.actionButtons.sendButtonRadialStatusNode?.alpha = 0.0
self.actionButtons.sendButtonRadialStatusNode?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
}
}

View File

@ -22,6 +22,8 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
let titleNode: ImmediateTextNode
let textNode: ImmediateTextNode
let imageNode: TransformImageNode
let dimNode: ASDisplayNode
let iconNode: ASImageNode
private let actionArea: AccessibilityAreaNode
@ -32,6 +34,7 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
private let messageDisposable = MetaDisposable()
private let editingMessageDisposable = MetaDisposable()
private var isPhoto = false
private var currentMessage: Message?
private var currentEditMediaReference: AnyMediaReference?
private var previousMediaReference: AnyMediaReference?
@ -96,6 +99,16 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
self.imageNode.isHidden = true
self.imageNode.isUserInteractionEnabled = true
self.dimNode = ASDisplayNode()
self.dimNode.backgroundColor = UIColor(rgb: 0x000000, alpha: 0.6)
self.dimNode.cornerRadius = 2.0
self.dimNode.isHidden = true
self.iconNode = ASImageNode()
self.iconNode.contentMode = .center
self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Draw"), color: .white)
self.iconNode.isHidden = true
self.activityIndicator = ActivityIndicator(type: .custom(theme.chat.inputPanel.panelControlAccentColor, 22.0, 2.0, false))
self.activityIndicator.isHidden = true
@ -114,6 +127,8 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
self.addSubnode(self.titleNode)
self.addSubnode(self.textNode)
self.addSubnode(self.imageNode)
self.addSubnode(self.dimNode)
self.addSubnode(self.iconNode)
self.addSubnode(self.activityIndicator)
self.addSubnode(self.statusNode)
self.addSubnode(self.tapNode)
@ -190,11 +205,13 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
}
self.previousMediaReference = updatedMediaReference
var isPhoto = false
var updateImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?
if mediaUpdated {
if let updatedMediaReference = updatedMediaReference, imageDimensions != nil {
if let imageReference = updatedMediaReference.concrete(TelegramMediaImage.self) {
updateImageSignal = chatMessagePhotoThumbnail(account: self.context.account, photoReference: imageReference)
isPhoto = true
} else if let fileReference = updatedMediaReference.concrete(TelegramMediaFile.self) {
if fileReference.media.isVideo {
updateImageSignal = chatMessageVideoThumbnail(account: self.context.account, fileReference: fileReference)
@ -206,6 +223,7 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
updateImageSignal = .single({ _ in return nil })
}
}
self.isPhoto = isPhoto
let isMedia: Bool
if let message = message {
@ -230,7 +248,12 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
canEditMedia = false
}
let titleString = canEditMedia ? self.strings.Conversation_EditingCaptionPanelTitle : self.strings.Conversation_EditingMessagePanelTitle
let titleString: String
if canEditMedia {
titleString = isPhoto ? self.strings.Conversation_EditingPhotoPanelTitle : self.strings.Conversation_EditingCaptionPanelTitle
} else {
titleString = self.strings.Conversation_EditingMessagePanelTitle
}
self.titleNode.attributedText = NSAttributedString(string: titleString, font: Font.medium(15.0), textColor: self.theme.chat.inputPanel.panelControlAccentColor)
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(15.0), textColor: isMedia ? self.theme.chat.inputPanel.secondaryTextColor : self.theme.chat.inputPanel.primaryTextColor)
@ -244,6 +267,14 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
self.imageNode.isHidden = true
}
if isPhoto && !self.imageNode.isHidden {
self.dimNode.isHidden = false
self.iconNode.isHidden = false
} else {
self.dimNode.isHidden = true
self.iconNode.isHidden = true
}
if let updateImageSignal = updateImageSignal {
self.imageNode.setSignal(.single({ arguments in
/*let context = DrawingContext(size: arguments.boundingSize)
@ -329,6 +360,8 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
imageTextInset = 9.0 + 35.0
}
self.imageNode.frame = CGRect(origin: CGPoint(x: leftInset + 9.0, y: 8.0), size: CGSize(width: 35.0, height: 35.0))
self.dimNode.frame = self.imageNode.frame
self.iconNode.frame = self.imageNode.frame
let titleSize = self.titleNode.updateLayout(CGSize(width: bounds.size.width - leftInset - textLineInset - rightInset - textRightInset - imageTextInset, height: bounds.size.height))
self.titleNode.frame = CGRect(origin: CGPoint(x: leftInset + textLineInset + imageTextInset, y: 7.0), size: titleSize)
@ -347,7 +380,11 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
@objc func contentTap(_ recognizer: UITapGestureRecognizer) {
if case .ended = recognizer.state, let message = self.currentMessage {
self.interfaceInteraction?.navigateToMessage(message.id, false, true, .generic)
if self.isPhoto {
self.interfaceInteraction?.editMessageMedia(message.id, true)
} else {
self.interfaceInteraction?.navigateToMessage(message.id, false, true, .generic)
}
}
}
}

View File

@ -285,18 +285,6 @@ public func fetchVideoLibraryMediaResource(account: Account, resource: VideoLibr
if let result = next as? TGMediaVideoConversionResult {
var value = stat()
if stat(result.fileURL.path, &value) == 0 {
// if config.remuxToFMp4 {
// let tempFile = TempBox.shared.tempFile(fileName: "video.mp4")
// if FFMpegRemuxer.remux(result.fileURL.path, to: tempFile.path) {
// let _ = try? FileManager.default.removeItem(atPath: result.fileURL.path)
// subscriber.putNext(.moveTempFile(file: tempFile))
// } else {
// TempBox.shared.dispose(tempFile)
// subscriber.putNext(.moveLocalFile(path: result.fileURL.path))
// }
// } else {
// subscriber.putNext(.moveLocalFile(path: result.fileURL.path))
// }
if let data = try? Data(contentsOf: result.fileURL, options: [.mappedRead]) {
var range: Range<Int>?
let _ = updatedSize.modify { updatedSize in

View File

@ -438,6 +438,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
}, scrollToTop: {
}, viewReplies: { _, _ in
}, activatePinnedListPreview: { _, _ in
}, editMessageMedia: { _, _ in
}, statuses: nil)
self.selectionPanel.interfaceInteraction = interfaceInteraction