Translation Improvements

This commit is contained in:
Ilya Laktyushin 2022-03-21 02:46:33 +04:00
parent 0949f2dab3
commit e35a0fb64f
7 changed files with 74 additions and 56 deletions

View File

@ -255,7 +255,7 @@ final class AttachmentContainer: ASDisplayNode, UIGestureRecognizerDelegate {
let topInset: CGFloat = edgeTopInset let topInset: CGFloat = edgeTopInset
var dismissing = false var dismissing = false
if bounds.minY < -60 || (bounds.minY < 0.0 && velocity.y > 300.0) || (self.isExpanded && bounds.minY.isZero && velocity.y > 600.0) { if bounds.minY < -60 || (bounds.minY < 0.0 && velocity.y > 300.0) || (self.isExpanded && bounds.minY.isZero && velocity.y > 1800.0) {
self.interactivelyDismissed?() self.interactivelyDismissed?()
dismissing = true dismissing = true
} else if self.isExpanded { } else if self.isExpanded {

View File

@ -279,6 +279,9 @@ public class AttachmentController: ViewController {
} }
@objc func dimTapGesture(_ recognizer: UITapGestureRecognizer) { @objc func dimTapGesture(_ recognizer: UITapGestureRecognizer) {
guard !self.isDismissing else {
return
}
if case .ended = recognizer.state { if case .ended = recognizer.state {
if let controller = self.currentControllers.last { if let controller = self.currentControllers.last {
controller.requestDismiss(completion: { [weak self] in controller.requestDismiss(completion: { [weak self] in

View File

@ -354,7 +354,10 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
case .speak: case .speak:
let _ = speakText(string) let _ = speakText(string)
case .translate: case .translate:
translateText(context: strongSelf.context, text: string) if let parentController = strongSelf.baseNavigationController()?.topViewController as? ViewController {
let controller = TranslateScreen(context: strongSelf.context, text: string, fromLanguage: nil)
parentController.present(controller, in: .window(.root))
}
} }
}) })
recognizedContentNode.barcodeAction = { [weak self] payload, rect in recognizedContentNode.barcodeAction = { [weak self] payload, rect in

View File

@ -1048,8 +1048,9 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
let (canTranslate, language) = canTranslateText(context: context, text: text, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages) let (canTranslate, language) = canTranslateText(context: context, text: text, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages)
if canTranslate { if canTranslate {
actions.append(ContextMenuAction(content: .text(title: strings.Conversation_ContextMenuTranslate, accessibilityLabel: strings.Conversation_ContextMenuTranslate), action: { actions.append(ContextMenuAction(content: .text(title: strings.Conversation_ContextMenuTranslate, accessibilityLabel: strings.Conversation_ContextMenuTranslate), action: { [weak self] in
translateText(context: context, text: text, fromLang: language) let controller = TranslateScreen(context: context, text: text, fromLanguage: language)
self?.present(controller, nil)
})) }))
} }

View File

@ -21,8 +21,6 @@ import SparseItemGrid
import UndoUI import UndoUI
import PresentationDataUtils import PresentationDataUtils
let overflowInset: CGFloat = 0.0
final class MediaPickerInteraction { final class MediaPickerInteraction {
let openMedia: (PHFetchResult<PHAsset>, Int, UIImage?) -> Void let openMedia: (PHFetchResult<PHAsset>, Int, UIImage?) -> Void
let openSelectedMedia: (TGMediaSelectableItem, UIImage?) -> Void let openSelectedMedia: (TGMediaSelectableItem, UIImage?) -> Void
@ -326,7 +324,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
if self.controller?.collection != nil { if self.controller?.collection != nil {
self.gridNode.view.interactiveTransitionGestureRecognizerTest = { point -> Bool in self.gridNode.view.interactiveTransitionGestureRecognizerTest = { point -> Bool in
return point.x > 44.0 + overflowInset return point.x > 44.0
} }
} }
@ -381,7 +379,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
} }
} }
if self.controller?.collection != nil { if self.controller?.collection != nil {
self.selectionGesture?.sideInset = 44.0 + overflowInset self.selectionGesture?.sideInset = 44.0
} }
} }
@ -853,7 +851,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
insets.top += navigationBarHeight insets.top += navigationBarHeight
let bounds = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: layout.size.height)) let bounds = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: layout.size.height))
let innerBounds = CGRect(origin: CGPoint(x: -overflowInset, y: 0.0), size: CGSize(width: layout.size.width, height: layout.size.height)) let innerBounds = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: layout.size.height))
let itemsPerRow: Int let itemsPerRow: Int
if case .compact = layout.metrics.widthClass { if case .compact = layout.metrics.widthClass {
@ -960,7 +958,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
transition.updateFrame(node: self.backgroundNode, frame: innerBounds) transition.updateFrame(node: self.backgroundNode, frame: innerBounds)
self.backgroundNode.update(size: bounds.size, transition: transition) self.backgroundNode.update(size: bounds.size, transition: transition)
transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(x: overflowInset, y: 0.0), size: CGSize(width: bounds.width - overflowInset * 2.0, height: bounds.height))) transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: bounds.width, height: bounds.height)))
self.gridNode.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: nil, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: bounds.size, insets: gridInsets, scrollIndicatorInsets: nil, preloadSize: itemWidth, type: .fixed(itemSize: CGSize(width: itemWidth, height: itemWidth), fillWidth: true, lineSpacing: itemSpacing, itemSpacing: itemSpacing), cutout: cameraRect), transition: transition), itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil, updateOpaqueState: nil, synchronousLoads: false), completion: { [weak self] _ in self.gridNode.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: nil, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: bounds.size, insets: gridInsets, scrollIndicatorInsets: nil, preloadSize: itemWidth, type: .fixed(itemSize: CGSize(width: itemWidth, height: itemWidth), fillWidth: true, lineSpacing: itemSpacing, itemSpacing: itemSpacing), cutout: cameraRect), transition: transition), itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil, updateOpaqueState: nil, synchronousLoads: false), completion: { [weak self] _ in
guard let strongSelf = self else { guard let strongSelf = self else {
@ -1065,6 +1063,8 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
} }
private let groupedPromise = ValuePromise<Bool>(true) private let groupedPromise = ValuePromise<Bool>(true)
private var isDismissing = false
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer?, chatLocation: ChatLocation?, bannedSendMedia: (Int32, Bool)?, collection: PHAssetCollection? = nil, editingContext: TGMediaEditingContext? = nil, selectionContext: TGMediaSelectionContext? = nil) { public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer?, chatLocation: ChatLocation?, bannedSendMedia: (Int32, Bool)?, collection: PHAssetCollection? = nil, editingContext: TGMediaEditingContext? = nil, selectionContext: TGMediaSelectionContext? = nil) {
self.context = context self.context = context
@ -1165,7 +1165,8 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
} }
} }
}, sendSelected: { [weak self] currentItem, silently, scheduleTime, animated, completion in }, sendSelected: { [weak self] currentItem, silently, scheduleTime, animated, completion in
if let strongSelf = self, let selectionState = strongSelf.interaction?.selectionState { if let strongSelf = self, let selectionState = strongSelf.interaction?.selectionState, !strongSelf.isDismissing {
strongSelf.isDismissing = true
if let currentItem = currentItem { if let currentItem = currentItem {
selectionState.setItem(currentItem, selected: true) selectionState.setItem(currentItem, selected: true)
} }
@ -1314,12 +1315,16 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
public func requestDismiss(completion: @escaping () -> Void) { public func requestDismiss(completion: @escaping () -> Void) {
if let selectionState = self.interaction?.selectionState, selectionState.count() > 0 { if let selectionState = self.interaction?.selectionState, selectionState.count() > 0 {
self.isDismissing = true
let controller = textAlertController(context: self.context, title: nil, text: self.presentationData.strings.Attachment_CancelSelectionAlertText, actions: [TextAlertAction(type: .genericAction, title: self.presentationData.strings.Attachment_CancelSelectionAlertNo, action: { let controller = textAlertController(context: self.context, title: nil, text: self.presentationData.strings.Attachment_CancelSelectionAlertText, actions: [TextAlertAction(type: .genericAction, title: self.presentationData.strings.Attachment_CancelSelectionAlertNo, action: {
}), TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Attachment_CancelSelectionAlertYes, action: { [weak self] in }), TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Attachment_CancelSelectionAlertYes, action: { [weak self] in
self?.dismissAllTooltips() self?.dismissAllTooltips()
completion() completion()
})]) })])
controller.dismissed = { [weak self] in
self?.isDismissing = false
}
self.present(controller, in: .window(.root)) self.present(controller, in: .window(.root))
} else { } else {
completion() completion()

View File

@ -5029,8 +5029,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
let (canTranslate, language) = canTranslateText(context: context, text: text, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages) let (canTranslate, language) = canTranslateText(context: context, text: text, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages)
if canTranslate { if canTranslate {
actions.append(ContextMenuAction(content: .text(title: presentationData.strings.Conversation_ContextMenuTranslate, accessibilityLabel: presentationData.strings.Conversation_ContextMenuTranslate), action: { actions.append(ContextMenuAction(content: .text(title: presentationData.strings.Conversation_ContextMenuTranslate, accessibilityLabel: presentationData.strings.Conversation_ContextMenuTranslate), action: { [weak self] in
translateText(context: context, text: text, fromLang: language)
let controller = TranslateScreen(context: context, text: text, fromLanguage: language)
self?.controller?.present(controller, in: .window(.root))
})) }))
} }

View File

@ -588,13 +588,6 @@ public class TranslateScreen: ViewController {
private var isDismissing = false private var isDismissing = false
func animateIn() { func animateIn() {
guard let (layout, _) = self.currentLayout else {
return
}
if case .regular = layout.metrics.widthClass {
ContainedViewLayoutTransition.animated(duration: 0.3, curve: .linear).updateAlpha(node: self.dim, alpha: 0.1)
} else {
ContainedViewLayoutTransition.animated(duration: 0.3, curve: .linear).updateAlpha(node: self.dim, alpha: 1.0) ContainedViewLayoutTransition.animated(duration: 0.3, curve: .linear).updateAlpha(node: self.dim, alpha: 1.0)
let targetPosition = self.containerView.center let targetPosition = self.containerView.center
@ -607,21 +600,10 @@ public class TranslateScreen: ViewController {
}, completion: { _ in }, completion: { _ in
}) })
} }
}
func animateOut(completion: @escaping () -> Void = {}) { func animateOut(completion: @escaping () -> Void = {}) {
self.isDismissing = true self.isDismissing = true
guard let (layout, _) = self.currentLayout else {
return
}
if case .regular = layout.metrics.widthClass {
self.layer.allowsGroupOpacity = true
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak self] _ in
self?.controller?.dismiss(animated: false, completion: completion)
})
} else {
let positionTransition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .easeInOut) let positionTransition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .easeInOut)
positionTransition.updatePosition(layer: self.containerView.layer, position: CGPoint(x: self.containerView.center.x, y: self.bounds.height + self.containerView.bounds.height / 2.0), completion: { [weak self] _ in positionTransition.updatePosition(layer: self.containerView.layer, position: CGPoint(x: self.containerView.center.x, y: self.bounds.height + self.containerView.bounds.height / 2.0), completion: { [weak self] _ in
self?.controller?.dismiss(animated: false, completion: completion) self?.controller?.dismiss(animated: false, completion: completion)
@ -633,7 +615,6 @@ public class TranslateScreen: ViewController {
self.controller?.updateModalStyleOverlayTransitionFactor(0.0, transition: positionTransition) self.controller?.updateModalStyleOverlayTransitionFactor(0.0, transition: positionTransition)
} }
} }
}
func containerLayoutUpdated(layout: ContainerViewLayout, navigationHeight: CGFloat, transition: Transition) { func containerLayoutUpdated(layout: ContainerViewLayout, navigationHeight: CGFloat, transition: Transition) {
self.currentLayout = (layout, navigationHeight) self.currentLayout = (layout, navigationHeight)
@ -668,6 +649,7 @@ public class TranslateScreen: ViewController {
let clipFrame: CGRect let clipFrame: CGRect
if layout.metrics.widthClass == .compact { if layout.metrics.widthClass == .compact {
self.dim.backgroundColor = UIColor(rgb: 0x000000, alpha: 0.25)
if isLandscape { if isLandscape {
self.containerView.layer.cornerRadius = 0.0 self.containerView.layer.cornerRadius = 0.0
} else { } else {
@ -701,13 +683,19 @@ public class TranslateScreen: ViewController {
clipFrame = CGRect(x: containerFrame.minX, y: containerFrame.minY, width: containerFrame.width, height: containerFrame.height) clipFrame = CGRect(x: containerFrame.minX, y: containerFrame.minY, width: containerFrame.width, height: containerFrame.height)
} }
} else { } else {
let unscaledFrame = CGRect(origin: CGPoint(), size: layout.size) self.dim.backgroundColor = UIColor(rgb: 0x000000, alpha: 0.4)
clipFrame = unscaledFrame self.containerView.layer.cornerRadius = 10.0
let verticalInset: CGFloat = 44.0
let maxSide = max(layout.size.width, layout.size.height)
let minSide = min(layout.size.width, layout.size.height)
let containerSize = CGSize(width: min(layout.size.width - 20.0, floor(maxSide / 2.0)), height: min(layout.size.height, minSide) - verticalInset * 2.0)
clipFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - containerSize.width) / 2.0), y: floor((layout.size.height - containerSize.height) / 2.0)), size: containerSize)
} }
transition.setFrame(view: self.containerView, frame: clipFrame) transition.setFrame(view: self.containerView, frame: clipFrame)
transition.setFrame(view: self.scrollView, frame: CGRect(origin: CGPoint(), size: clipFrame.size), completion: nil) transition.setFrame(view: self.scrollView, frame: CGRect(origin: CGPoint(), size: clipFrame.size), completion: nil)
transition.setFrame(view: self.hostView, frame: CGRect(origin: CGPoint(), size: clipFrame.size), completion: nil)
let environment = ViewControllerComponentContainer.Environment( let environment = ViewControllerComponentContainer.Environment(
statusBarHeight: 0.0, statusBarHeight: 0.0,
@ -729,6 +717,7 @@ public class TranslateScreen: ViewController {
forceUpdate: true, forceUpdate: true,
containerSize: CGSize(width: clipFrame.size.width, height: 10000.0) containerSize: CGSize(width: clipFrame.size.width, height: 10000.0)
) )
transition.setFrame(view: self.hostView, frame: CGRect(origin: CGPoint(), size: contentSize), completion: nil)
self.scrollView.contentSize = contentSize self.scrollView.contentSize = contentSize
} }
@ -892,7 +881,7 @@ public class TranslateScreen: ViewController {
let topInset: CGFloat = edgeTopInset let topInset: CGFloat = edgeTopInset
var dismissing = false var dismissing = false
if bounds.minY < -60 || (bounds.minY < 0.0 && velocity.y > 300.0) || (self.isExpanded && bounds.minY.isZero && velocity.y > 600.0) { if bounds.minY < -60 || (bounds.minY < 0.0 && velocity.y > 300.0) || (self.isExpanded && bounds.minY.isZero && velocity.y > 1800.0) {
self.controller?.dismiss(animated: true, completion: nil) self.controller?.dismiss(animated: true, completion: nil)
dismissing = true dismissing = true
} else if self.isExpanded { } else if self.isExpanded {
@ -981,7 +970,11 @@ public class TranslateScreen: ViewController {
public convenience init(context: AccountContext, text: String, fromLanguage: String?, toLanguage: String? = nil, isExpanded: Bool = false) { public convenience init(context: AccountContext, text: String, fromLanguage: String?, toLanguage: String? = nil, isExpanded: Bool = false) {
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let toLanguage = toLanguage ?? presentationData.strings.baseLanguageCode var toLanguage = toLanguage ?? presentationData.strings.baseLanguageCode
if toLanguage == fromLanguage {
toLanguage = "en"
}
var copyTranslationImpl: ((String) -> Void)? var copyTranslationImpl: ((String) -> Void)?
var changeLanguageImpl: ((String, String, @escaping (String, String) -> Void) -> Void)? var changeLanguageImpl: ((String, String, @escaping (String, String) -> Void) -> Void)?
@ -1084,11 +1077,22 @@ public class TranslateScreen: ViewController {
override public func updateNavigationBarLayout(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { override public func updateNavigationBarLayout(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
var navigationLayout = self.navigationLayout(layout: layout) var navigationLayout = self.navigationLayout(layout: layout)
var navigationFrame = navigationLayout.navigationFrame var navigationFrame = navigationLayout.navigationFrame
var layout = layout
if case .regular = layout.metrics.widthClass {
let verticalInset: CGFloat = 44.0
let maxSide = max(layout.size.width, layout.size.height)
let minSide = min(layout.size.width, layout.size.height)
let containerSize = CGSize(width: min(layout.size.width - 20.0, floor(maxSide / 2.0)), height: min(layout.size.height, minSide) - verticalInset * 2.0)
let clipFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - containerSize.width) / 2.0), y: floor((layout.size.height - containerSize.height) / 2.0)), size: containerSize)
navigationFrame.size.width = clipFrame.width
layout.size = clipFrame.size
}
navigationFrame.size.height = 56.0 navigationFrame.size.height = 56.0
navigationLayout.navigationFrame = navigationFrame navigationLayout.navigationFrame = navigationFrame
navigationLayout.defaultContentHeight = 56.0 navigationLayout.defaultContentHeight = 56.0
var layout = layout
layout.statusBarHeight = nil layout.statusBarHeight = nil
self.applyNavigationBarLayout(layout, navigationLayout: navigationLayout, additionalBackgroundHeight: 0.0, transition: transition) self.applyNavigationBarLayout(layout, navigationLayout: navigationLayout, additionalBackgroundHeight: 0.0, transition: transition)