Various fixes

This commit is contained in:
Ilya Laktyushin 2022-12-23 10:11:08 +04:00
parent 729b4d952c
commit 9937826307
30 changed files with 484 additions and 2603 deletions

View File

@ -197,7 +197,7 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
}
private var initialEntitiesData: Data?
public func setup(withEntitiesData entitiesData: Data!) {
public func setup(withEntitiesData entitiesData: Data?) {
self.clear()
self.initialEntitiesData = entitiesData
@ -329,12 +329,13 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
let view = entity.makeView(context: self.context)
view.containerView = self
view.onSnapToXAxis = { [weak self] snappedToX in
guard let strongSelf = self else {
view.onSnapToXAxis = { [weak self, weak view] snappedToX in
guard let strongSelf = self, let strongView = view else {
return
}
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
if snappedToX {
strongSelf.insertSubview(strongSelf.xAxisView, belowSubview: strongView)
if strongSelf.xAxisView.alpha < 1.0 {
strongSelf.hapticFeedback.impact(.light)
}
@ -343,12 +344,13 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
transition.updateAlpha(layer: strongSelf.xAxisView.layer, alpha: 0.0)
}
}
view.onSnapToYAxis = { [weak self] snappedToY in
guard let strongSelf = self else {
view.onSnapToYAxis = { [weak self, weak view] snappedToY in
guard let strongSelf = self, let strongView = view else {
return
}
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
if snappedToY {
strongSelf.insertSubview(strongSelf.yAxisView, belowSubview: strongView)
if strongSelf.yAxisView.alpha < 1.0 {
strongSelf.hapticFeedback.impact(.light)
}
@ -573,13 +575,13 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
return self.selectedEntityView != nil
}
public func handlePinch(_ gestureRecognizer: UIPinchGestureRecognizer!) {
public func handlePinch(_ gestureRecognizer: UIPinchGestureRecognizer) {
if let selectedEntityView = self.selectedEntityView, let selectionView = selectedEntityView.selectionView {
selectionView.handlePinch(gestureRecognizer)
}
}
public func handleRotate(_ gestureRecognizer: UIRotationGestureRecognizer!) {
public func handleRotate(_ gestureRecognizer: UIRotationGestureRecognizer) {
if let selectedEntityView = self.selectedEntityView, let selectionView = selectedEntityView.selectionView {
selectionView.handleRotate(gestureRecognizer)
}

View File

@ -338,21 +338,105 @@ final class DrawingSettings: Codable, Equatable {
private final class ReferenceContentSource: ContextReferenceContentSource {
private let sourceView: UIView
init(sourceView: UIView) {
private let customPosition: CGPoint
init(sourceView: UIView, customPosition: CGPoint) {
self.sourceView = sourceView
self.customPosition = customPosition
}
func transitionInfo() -> ContextControllerReferenceViewInfo? {
return ContextControllerReferenceViewInfo(referenceView: self.sourceView, contentAreaInScreenSpace: UIScreen.main.bounds, customPosition: CGPoint(x: 7.0, y: 3.0))
return ContextControllerReferenceViewInfo(referenceView: self.sourceView, contentAreaInScreenSpace: UIScreen.main.bounds, customPosition: customPosition)
}
}
private final class BlurredGradientComponent: Component {
enum Position {
case top
case bottom
}
let position: Position
let tag: AnyObject?
public init(
position: Position,
tag: AnyObject?
) {
self.position = position
self.tag = tag
}
public static func ==(lhs: BlurredGradientComponent, rhs: BlurredGradientComponent) -> Bool {
if lhs.position != rhs.position {
return false
}
return true
}
public final class View: BlurredBackgroundView, ComponentTaggedView {
private var component: BlurredGradientComponent?
public func matches(tag: Any) -> Bool {
if let component = self.component, let componentTag = component.tag {
let tag = tag as AnyObject
if componentTag === tag {
return true
}
}
return false
}
private var gradientMask = UIImageView()
private var gradientForeground = SimpleGradientLayer()
public func update(component: BlurredGradientComponent, availableSize: CGSize, transition: Transition) -> CGSize {
self.component = component
self.updateColor(color: UIColor(rgb: 0x000000, alpha: 0.25), transition: transition.containedViewLayoutTransition)
if self.mask == nil {
self.mask = self.gradientMask
self.gradientMask.image = generateGradientImage(
size: CGSize(width: 1.0, height: availableSize.height),
colors: [UIColor(rgb: 0xffffff, alpha: 1.0), UIColor(rgb: 0xffffff, alpha: 1.0), UIColor(rgb: 0xffffff, alpha: 0.0)],
locations: component.position == .top ? [0.0, 0.5, 1.0] : [1.0, 0.5, 0.0],
direction: .vertical
)
self.gradientForeground.colors = [UIColor(rgb: 0x000000, alpha: 0.35).cgColor, UIColor(rgb: 0x000000, alpha: 0.0).cgColor]
self.gradientForeground.startPoint = CGPoint(x: 0.5, y: component.position == .top ? 0.0 : 1.0)
self.gradientForeground.endPoint = CGPoint(x: 0.5, y: component.position == .top ? 1.0 : 0.0)
self.layer.addSublayer(self.gradientForeground)
}
transition.setFrame(view: self.gradientMask, frame: CGRect(origin: .zero, size: availableSize))
transition.setFrame(layer: self.gradientForeground, frame: CGRect(origin: .zero, size: availableSize))
self.update(size: availableSize, transition: transition.containedViewLayoutTransition)
return availableSize
}
}
public func makeView() -> View {
return View(color: nil, enableBlur: true)
}
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
return view.update(component: self, availableSize: availableSize, transition: transition)
}
}
enum DrawingScreenTransition {
case animateIn
case animateOut
}
private let topGradientTag = GenericComponentViewTag()
private let bottomGradientTag = GenericComponentViewTag()
private let undoButtonTag = GenericComponentViewTag()
private let redoButtonTag = GenericComponentViewTag()
private let clearAllButtonTag = GenericComponentViewTag()
@ -365,6 +449,7 @@ private let fillButtonTag = GenericComponentViewTag()
private let zoomOutButtonTag = GenericComponentViewTag()
private let textSettingsTag = GenericComponentViewTag()
private let sizeSliderTag = GenericComponentViewTag()
private let fontTag = GenericComponentViewTag()
private let color1Tag = GenericComponentViewTag()
private let color2Tag = GenericComponentViewTag()
private let color3Tag = GenericComponentViewTag()
@ -373,6 +458,7 @@ private let color5Tag = GenericComponentViewTag()
private let color6Tag = GenericComponentViewTag()
private let color7Tag = GenericComponentViewTag()
private let color8Tag = GenericComponentViewTag()
private let colorTags = [color1Tag, color2Tag, color3Tag, color4Tag, color5Tag, color6Tag, color7Tag, color8Tag]
private let doneButtonTag = GenericComponentViewTag()
private final class DrawingScreenComponent: CombinedComponent {
@ -399,6 +485,7 @@ private final class DrawingScreenComponent: CombinedComponent {
let presentFastColorPicker: (UIView) -> Void
let updateFastColorPickerPan: (CGPoint) -> Void
let dismissFastColorPicker: () -> Void
let presentFontPicker: (UIView) -> Void
init(
context: AccountContext,
@ -420,7 +507,8 @@ private final class DrawingScreenComponent: CombinedComponent {
presentColorPicker: @escaping (DrawingColor) -> Void,
presentFastColorPicker: @escaping (UIView) -> Void,
updateFastColorPickerPan: @escaping (CGPoint) -> Void,
dismissFastColorPicker: @escaping () -> Void
dismissFastColorPicker: @escaping () -> Void,
presentFontPicker: @escaping (UIView) -> Void
) {
self.context = context
self.isVideo = isVideo
@ -442,6 +530,7 @@ private final class DrawingScreenComponent: CombinedComponent {
self.presentFastColorPicker = presentFastColorPicker
self.updateFastColorPickerPan = updateFastColorPickerPan
self.dismissFastColorPicker = dismissFastColorPicker
self.presentFontPicker = presentFontPicker
}
static func ==(lhs: DrawingScreenComponent, rhs: DrawingScreenComponent) -> Bool {
@ -758,7 +847,7 @@ private final class DrawingScreenComponent: CombinedComponent {
)
]
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: defaultDarkPresentationTheme)
let contextController = ContextController(account: self.context.account, presentationData: presentationData, source: .reference(ReferenceContentSource(sourceView: sourceView)), items: .single(ContextController.Items(content: .list(items))))
let contextController = ContextController(account: self.context.account, presentationData: presentationData, source: .reference(ReferenceContentSource(sourceView: sourceView, customPosition: CGPoint(x: 7.0, y: 3.0))), items: .single(ContextController.Items(content: .list(items))))
self.present(contextController)
}
@ -804,6 +893,9 @@ private final class DrawingScreenComponent: CombinedComponent {
}
static var body: Body {
let topGradient = Child(BlurredGradientComponent.self)
let bottomGradient = Child(BlurredGradientComponent.self)
let undoButton = Child(Button.self)
let redoButton = Child(Button.self)
@ -887,10 +979,36 @@ private final class DrawingScreenComponent: CombinedComponent {
let presentFastColorPicker = component.presentFastColorPicker
let updateFastColorPickerPan = component.updateFastColorPickerPan
let dismissFastColorPicker = component.dismissFastColorPicker
let presentFontPicker = component.presentFontPicker
let topInset = environment.safeInsets.top + 31.0
let bottomInset: CGFloat = environment.inputHeight > 0.0 ? environment.inputHeight : 145.0
let topGradient = topGradient.update(
component: BlurredGradientComponent(
position: .top,
tag: topGradientTag
),
availableSize: CGSize(width: context.availableSize.width, height: 111.0),
transition: .immediate
)
context.add(topGradient
.position(CGPoint(x: context.availableSize.width / 2.0, y: topGradient.size.height / 2.0))
)
let bottomGradient = bottomGradient.update(
component: BlurredGradientComponent(
position: .bottom,
tag: bottomGradientTag
),
availableSize: CGSize(width: context.availableSize.width, height: 155.0),
transition: .immediate
)
context.add(bottomGradient
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height - bottomGradient.size.height / 2.0))
)
if let textEntity = state.selectedEntity as? DrawingTextEntity {
let textSettings = textSettings.update(
component: TextSettingsComponent(
@ -900,6 +1018,7 @@ private final class DrawingScreenComponent: CombinedComponent {
font: DrawingTextFont(font: textEntity.font),
isEmojiKeyboard: false,
tag: textSettingsTag,
fontTag: fontTag,
toggleStyle: { [weak state, weak textEntity] in
guard let textEntity = textEntity else {
return
@ -940,15 +1059,10 @@ private final class DrawingScreenComponent: CombinedComponent {
}
state?.updated(transition: .easeInOut(duration: 0.2))
},
updateFont: { [weak state, weak textEntity] font in
guard let textEntity = textEntity else {
return
presentFontPicker: {
if let controller = controller() as? DrawingScreen, let buttonView = controller.node.componentHost.findTaggedView(tag: fontTag) {
presentFontPicker(buttonView)
}
textEntity.font = font.font
if let entityView = textEntity.currentEntityView {
entityView.update()
}
state?.updated(transition: .easeInOut(duration: 0.2))
},
toggleKeyboard: nil
),
@ -958,12 +1072,12 @@ private final class DrawingScreenComponent: CombinedComponent {
context.add(textSettings
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height - environment.safeInsets.bottom - textSettings.size.height / 2.0 - 89.0))
.appear(Transition.Appear({ _, view, transition in
if let view = findTaggedComponentViewImpl(view: view, tag: textSettingsTag) as? TextFontComponent.View, !transition.animation.isImmediate {
if let view = view as? TextSettingsComponent.View, !transition.animation.isImmediate {
view.animateIn()
}
}))
.disappear(Transition.Disappear({ view, transition, completion in
if let view = findTaggedComponentViewImpl(view: view, tag: textSettingsTag) as? TextFontComponent.View, !transition.animation.isImmediate {
if let view = view as? TextSettingsComponent.View, !transition.animation.isImmediate {
view.animateOut(completion: completion)
} else {
completion()
@ -1769,11 +1883,11 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
private let textEditAccessoryView: UIInputView
private let textEditAccessoryHost: ComponentView<Empty>
private var presentationData: PresentationData
private let hapticFeedback = HapticFeedback()
private var validLayout: (ContainerViewLayout, UIInterfaceOrientation?)?
private var _drawingView: DrawingView?
var drawingView: DrawingView {
if self._drawingView == nil, let controller = self.controller {
@ -1802,7 +1916,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Paint_ClearConfirm, color: .destructive, action: { [weak actionSheet, weak self] in
actionSheet?.dismissAnimated()
self?._drawingView?.performAction(action)
})
]),
@ -1841,7 +1955,11 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
private var _entitiesView: DrawingEntitiesView?
var entitiesView: DrawingEntitiesView {
if self._entitiesView == nil, let controller = self.controller {
self._entitiesView = DrawingEntitiesView(context: self.context, size: controller.size)
if let externalEntitiesView = controller.externalEntitiesView {
self._entitiesView = externalEntitiesView
} else {
self._entitiesView = DrawingEntitiesView(context: self.context, size: controller.size)
}
self._drawingView?.entitiesView = self._entitiesView
self._entitiesView?.drawingView = self._drawingView
self._entitiesView?.entityAdded = { [weak self] entity in
@ -1870,21 +1988,6 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
} else {
return nil
}
// let image = generateImage(controller.size, contextGenerator: { size, context in
// let bounds = CGRect(origin: .zero, size: size)
// if let cgImage = currentImage.cgImage {
// context.draw(cgImage, in: bounds)
// }
// if let cgImage = strongSelf.drawingView.drawingImage?.cgImage {
// context.draw(cgImage, in: bounds)
// }
// telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes)
//
//
//
// }, opaque: true, scale: 1.0)
// return image
} else {
return nil
}
@ -2039,7 +2142,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: strongSelf.presentationData.strings.PhotoEditor_DiscardChanges, color: .accent, action: { [weak actionSheet, weak self] in
actionSheet?.dismissAnimated()
self?.controller?.requestDismiss()
})
]),
@ -2063,7 +2166,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
self.view.disablesInteractiveKeyboardGestureRecognizer = true
self.view.disablesInteractiveTransitionGestureRecognizer = true
}
private var currentEyedropperView: EyedropperView?
func presentEyedropper(retryLaterForVideo: Bool = true, dismissed: @escaping () -> Void) {
guard let controller = self.controller else {
@ -2080,17 +2183,11 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
}
guard let currentImage = controller.getCurrentImage() else {
// if controller.isVideo && retryIfFailed {
// Queue.mainQueue().after(0.01) {
// self.presentEyedropper(retryIfFailed: false, dismissed: dismissed)
// }
// } else {
self.entitiesView.play()
controller.updateVideoPlayback(true)
// }
self.entitiesView.play()
controller.updateVideoPlayback(true)
return
}
let sourceImage = generateImage(controller.drawingView.imageSize, contextGenerator: { size, context in
let bounds = CGRect(origin: .zero, size: size)
if let cgImage = currentImage.cgImage {
@ -2135,6 +2232,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
func presentColorPicker(initialColor: DrawingColor, dismissed: @escaping () -> Void = {}) {
self.dismissCurrentEyedropper()
self.dismissFontPicker()
guard let controller = self.controller else {
return
@ -2153,6 +2251,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
private var fastColorPickerView: ColorSpectrumPickerView?
func presentFastColorPicker(sourceView: UIView) {
self.dismissCurrentEyedropper()
self.dismissFontPicker()
guard self.fastColorPickerView == nil, let superview = sourceView.superview else {
return
@ -2191,7 +2290,61 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
})
}
private weak var currentFontPicker: ContextController?
func presentFontPicker(sourceView: UIView) {
guard !self.dismissFontPicker() else {
return
}
let fonts: [DrawingTextFont] = [
.sanFrancisco,
.newYork,
.other("MarkerFelt-Wide", "Marker Felt"),
.other("Chalkduster", "Chalkduster"),
.other("Menlo-Bold", "Menlo"),
.other("Copperplate-Bold", "Copperplate"),
.other("GillSans-SemiBold", "Gill Sans"),
.other("Papyrus", "Papyrus")
]
var items: [ContextMenuItem] = []
for font in fonts {
items.append(.action(ContextMenuActionItem(text: font.title, textFont: .custom(font.uiFont(size: 17.0)), icon: { _ in return nil }, animationName: nil, action: { [weak self] f in
f.dismissWithResult(.default)
guard let strongSelf = self, let entityView = strongSelf.entitiesView.selectedEntityView as? DrawingTextEntityView, let textEntity = entityView.entity as? DrawingTextEntity else {
return
}
textEntity.font = font.font
entityView.update()
if let (layout, orientation) = strongSelf.validLayout {
strongSelf.containerLayoutUpdated(layout: layout, orientation: orientation, forceUpdate: true, transition: .immediate)
}
})))
}
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: defaultDarkPresentationTheme)
let contextController = ContextController(account: self.context.account, presentationData: presentationData, source: .reference(ReferenceContentSource(sourceView: sourceView, customPosition: CGPoint(x: 7.0, y: 0.0))), items: .single(ContextController.Items(content: .list(items))))
self.controller?.present(contextController, in: .window(.root))
self.currentFontPicker = contextController
}
@discardableResult
func dismissFontPicker() -> Bool {
if let currentFontPicker = self.currentFontPicker {
self.currentFontPicker = nil
currentFontPicker.dismiss()
return true
}
return false
}
func animateIn() {
if let view = self.componentHost.findTaggedView(tag: topGradientTag) {
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
}
if let view = self.componentHost.findTaggedView(tag: bottomGradientTag) {
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
}
if let buttonView = self.componentHost.findTaggedView(tag: undoButtonTag) {
buttonView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
buttonView.layer.animateScale(from: 0.01, to: 1.0, duration: 0.3)
@ -2205,7 +2358,6 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
buttonView.layer.animateScale(from: 0.01, to: 1.0, duration: 0.3)
}
var delay: Double = 0.0
let colorTags = [color1Tag, color2Tag, color3Tag, color4Tag, color5Tag, color6Tag, color7Tag, color8Tag]
for tag in colorTags {
if let view = self.componentHost.findTaggedView(tag: tag) {
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, delay: delay)
@ -2223,6 +2375,12 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
self.containerLayoutUpdated(layout: layout, orientation: orientation, animateOut: true, transition: .easeInOut(duration: 0.2))
}
if let view = self.componentHost.findTaggedView(tag: topGradientTag) {
view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false)
}
if let view = self.componentHost.findTaggedView(tag: bottomGradientTag) {
view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false)
}
if let buttonView = self.componentHost.findTaggedView(tag: undoButtonTag) {
buttonView.alpha = 0.0
buttonView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3)
@ -2264,8 +2422,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
if let view = self.componentHost.findTaggedView(tag: sizeSliderTag) {
view.layer.animatePosition(from: CGPoint(), to: CGPoint(x: -33.0, y: 0.0), duration: 0.3, removeOnCompletion: false, additive: true)
}
let colorTags = [color1Tag, color2Tag, color3Tag, color4Tag, color5Tag, color6Tag, color7Tag, color8Tag]
for tag in colorTags {
if let view = self.componentHost.findTaggedView(tag: tag) {
view.alpha = 0.0
@ -2278,7 +2435,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
view.animateOut(completion: {
completion()
})
} else if let view = self.componentHost.findTaggedView(tag: textSettingsTag) as? TextFontComponent.View {
} else if let view = self.componentHost.findTaggedView(tag: textSettingsTag) as? TextSettingsComponent.View {
view.animateOut(completion: {
completion()
})
@ -2301,7 +2458,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
return result
}
func containerLayoutUpdated(layout: ContainerViewLayout, orientation: UIInterfaceOrientation?, animateOut: Bool = false, transition: Transition) {
func containerLayoutUpdated(layout: ContainerViewLayout, orientation: UIInterfaceOrientation?, forceUpdate: Bool = false, animateOut: Bool = false, transition: Transition) {
guard let controller = self.controller else {
return
}
@ -2370,13 +2527,16 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
},
dismissFastColorPicker: { [weak self] in
self?.dismissFastColorPicker()
},
presentFontPicker: { [weak self] sourceView in
self?.presentFontPicker(sourceView: sourceView)
}
)
),
environment: {
environment
},
forceUpdate: animateOut,
forceUpdate: forceUpdate || animateOut,
containerSize: layout.size
)
if let componentView = self.componentHost.view {
@ -2409,6 +2569,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
font: DrawingTextFont(font: textEntity.font),
isEmojiKeyboard: entityView.textView.inputView != nil,
tag: nil,
fontTag: fontTag,
presentColorPicker: { [weak self] in
guard let strongSelf = self, let entityView = strongSelf.entitiesView.selectedEntityView as? DrawingTextEntityView, let textEntity = entityView.entity as? DrawingTextEntity else {
return
@ -2430,6 +2591,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
self?.dismissFastColorPicker()
},
toggleStyle: { [weak self] in
self?.dismissFontPicker()
guard let strongSelf = self, let entityView = strongSelf.entitiesView.selectedEntityView as? DrawingTextEntityView, let textEntity = entityView.entity as? DrawingTextEntity else {
return
}
@ -2452,6 +2614,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
}
},
toggleAlignment: { [weak self] in
self?.dismissFontPicker()
guard let strongSelf = self, let entityView = strongSelf.entitiesView.selectedEntityView as? DrawingTextEntityView, let textEntity = entityView.entity as? DrawingTextEntity else {
return
}
@ -2471,21 +2634,16 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
strongSelf.containerLayoutUpdated(layout: layout, orientation: orientation, transition: .immediate)
}
},
updateFont: { [weak self] font in
guard let strongSelf = self, let entityView = strongSelf.entitiesView.selectedEntityView as? DrawingTextEntityView, let textEntity = entityView.entity as? DrawingTextEntity else {
return
}
textEntity.font = font.font
entityView.update()
if let (layout, orientation) = strongSelf.validLayout {
strongSelf.containerLayoutUpdated(layout: layout, orientation: orientation, transition: .immediate)
presentFontPicker: { [weak self] in
if let buttonView = self?.textEditAccessoryHost.findTaggedView(tag: fontTag) {
self?.presentFontPicker(sourceView: buttonView)
}
},
toggleKeyboard: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.dismissFontPicker()
strongSelf.toggleInputMode()
}
)
@ -2567,19 +2725,26 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
private let originalSize: CGSize
private let isVideo: Bool
private let isAvatar: Bool
private let externalEntitiesView: DrawingEntitiesView?
public var requestDismiss: (() -> Void)!
public var requestApply: (() -> Void)!
public var getCurrentImage: (() -> UIImage?)!
public var updateVideoPlayback: ((Bool) -> Void)!
public var requestDismiss: () -> Void = {}
public var requestApply: () -> Void = {}
public var getCurrentImage: () -> UIImage? = { return nil }
public var updateVideoPlayback: (Bool) -> Void = { _ in }
public init(context: AccountContext, size: CGSize, originalSize: CGSize, isVideo: Bool, isAvatar: Bool ) {
public init(context: AccountContext, size: CGSize, originalSize: CGSize, isVideo: Bool, isAvatar: Bool, entitiesView: (UIView & TGPhotoDrawingEntitiesView)?) {
self.context = context
self.size = size
self.originalSize = originalSize
self.isVideo = isVideo
self.isAvatar = isAvatar
if let entitiesView = entitiesView as? DrawingEntitiesView {
self.externalEntitiesView = entitiesView
} else {
self.externalEntitiesView = nil
}
super.init(navigationBarPresentationData: nil)
self.statusBar.statusBarStyle = .Hide
@ -2612,7 +2777,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
super.displayNodeDidLoad()
}
public func generateResultData() -> TGPaintingData! {
public func generateResultData() -> TGPaintingData? {
if self.drawingView.isEmpty && self.entitiesView.entities.isEmpty {
return nil
}
@ -2692,7 +2857,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
return image
}
public func animateOut(_ completion: (() -> Void)!) {
public func animateOut(_ completion: @escaping (() -> Void)) {
self.selectionContainerView.alpha = 0.0
self.node.animateOut(completion: completion)

View File

@ -576,14 +576,14 @@ class DrawingEntitySnapTool {
var updatedPosition = updatedPosition
let snapXDelta: CGFloat = (entityView.superview?.frame.width ?? 0.0) * 0.02
let snapXVelocity: CGFloat = snapXDelta * 16.0
let snapXVelocity: CGFloat = snapXDelta * 12.0
let snapXSkipTranslation: CGFloat = snapXDelta * 2.0
if abs(velocity.x) < snapXVelocity || self.xState?.waitForLeave == true {
if let snapLocation = (entityView.superview as? DrawingEntitiesView)?.getEntityCenterPosition() {
if let (skipped, waitForLeave) = self.xState {
if waitForLeave {
if updatedPosition.x > snapLocation.x - snapXDelta * 1.5 && updatedPosition.x < snapLocation.x + snapXDelta * 1.5 {
if updatedPosition.x > snapLocation.x - snapXDelta * 2.0 && updatedPosition.x < snapLocation.x + snapXDelta * 2.0 {
} else {
self.xState = nil
@ -604,22 +604,19 @@ class DrawingEntitySnapTool {
}
}
} else {
if self.xState != nil {
print()
}
self.xState = nil
self.onSnapXUpdated(false)
}
let snapYDelta: CGFloat = (entityView.superview?.frame.width ?? 0.0) * 0.02
let snapYVelocity: CGFloat = snapYDelta * 16.0
let snapYVelocity: CGFloat = snapYDelta * 12.0
let snapYSkipTranslation: CGFloat = snapYDelta * 2.0
if abs(velocity.y) < snapYVelocity || self.yState?.waitForLeave == true {
if let snapLocation = (entityView.superview as? DrawingEntitiesView)?.getEntityCenterPosition() {
if let (skipped, waitForLeave) = self.yState {
if waitForLeave {
if updatedPosition.y > snapLocation.y - snapYDelta * 1.5 && updatedPosition.y < snapLocation.y + snapYDelta * 1.5 {
if updatedPosition.y > snapLocation.y - snapYDelta * 2.0 && updatedPosition.y < snapLocation.y + snapYDelta * 2.0 {
} else {
self.yState = nil

View File

@ -79,9 +79,7 @@ public final class DrawingTextEntity: DrawingEntity, Codable {
enum Font: Codable {
case sanFrancisco
case newYork
case monospaced
case round
case custom(String, String)
case other(String, String)
}
enum Alignment: Codable {
@ -543,7 +541,7 @@ final class DrawingTextEntityView: DrawingEntityView, UITextViewDelegate {
self.textView.drawingLayoutManager.textContainers.first?.lineFragmentPadding = floor(fontSize * 0.24)
if let (font, name) = availableFonts[text.string.lowercased()] {
self.textEntity.font = .custom(font, name)
self.textEntity.font = .other(font, name)
}
var font: UIFont
@ -552,11 +550,7 @@ final class DrawingTextEntityView: DrawingEntityView, UITextViewDelegate {
font = Font.with(size: fontSize, design: .regular, weight: .semibold)
case .newYork:
font = Font.with(size: fontSize, design: .serif, weight: .semibold)
case .monospaced:
font = Font.with(size: fontSize, design: .monospace, weight: .semibold)
case .round:
font = Font.with(size: fontSize, design: .round, weight: .semibold)
case let .custom(fontName, _):
case let .other(fontName, _):
font = UIFont(name: fontName, size: fontSize) ?? Font.with(size: fontSize, design: .regular, weight: .semibold)
}
@ -854,7 +848,7 @@ final class DrawingTextEntititySelectionView: DrawingEntitySelectionView, UIGest
switch gestureRecognizer.state {
case .began, .changed:
let scale = gestureRecognizer.scale
entity.fontSize = max(0.1, entity.scale * scale)
entity.scale = max(0.1, entity.scale * scale)
entityView.update()
gestureRecognizer.scale = 1.0

View File

@ -699,63 +699,6 @@ class BezierPath {
}
}
func concaveHullPath(points: [CGPoint]) -> CGPath {
let hull = getHull(points, concavity: 1000.0)
let hullPath = CGMutablePath()
var moved = true
for point in hull {
if moved {
hullPath.move(to: point)
moved = false
} else {
hullPath.addLine(to: point)
}
}
hullPath.closeSubpath()
return hullPath
}
func expandPath(_ path: CGPath, width: CGFloat) -> CGPath {
let expandedPath = path.copy(strokingWithWidth: width * 2.0, lineCap: .round, lineJoin: .round, miterLimit: 0.0)
class UserInfo {
let outputPath = CGMutablePath()
var passedFirst = false
}
var userInfo = UserInfo()
withUnsafeMutablePointer(to: &userInfo) { userInfoPointer in
expandedPath.apply(info: userInfoPointer) { (userInfo, nextElementPointer) in
let element = nextElementPointer.pointee
let userInfoPointer = userInfo!.assumingMemoryBound(to: UserInfo.self)
let userInfo = userInfoPointer.pointee
if !userInfo.passedFirst {
if case .closeSubpath = element.type {
userInfo.passedFirst = true
}
} else {
switch element.type {
case .moveToPoint:
userInfo.outputPath.move(to: element.points[0])
case .addLineToPoint:
userInfo.outputPath.addLine(to: element.points[0])
case .addQuadCurveToPoint:
userInfo.outputPath.addQuadCurve(to: element.points[1], control: element.points[0])
case .addCurveToPoint:
userInfo.outputPath.addCurve(to: element.points[2], control1: element.points[0], control2: element.points[1])
case .closeSubpath:
userInfo.outputPath.closeSubpath()
@unknown default:
userInfo.outputPath.closeSubpath()
}
}
}
}
return userInfo.outputPath
}
class Matrix {
private(set) var m: [Float]

View File

@ -365,14 +365,12 @@ public final class DrawingView: UIView, UIGestureRecognizerDelegate, TGPhotoDraw
self.strokeRecognitionTimer?.invalidate()
}
public func setup(withDrawing drawingData: Data!) {
public func setup(withDrawing drawingData: Data?) {
if let drawingData = drawingData, let image = UIImage(data: drawingData) {
self.hasOpaqueData = true
self.drawingImage = image
self.layer.contents = image.cgImage
//let codableElements = try? JSONDecoder().decode([CodableDrawingElement].self, from: drawingData) {
//self.elements = codableElements.map { $0.element }
//self.commit(reset: true)
self.updateInternalState()
}
}

View File

@ -104,7 +104,7 @@ class ModeAndSizeComponent: Component {
init() {
self.backgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0x888888, alpha: 0.3))
self.node = SegmentedControlNode(theme: SegmentedControlTheme(backgroundColor: .clear, foregroundColor: UIColor(rgb: 0x6f7075, alpha: 0.6), shadowColor: .black, textColor: UIColor(rgb: 0xffffff), dividerColor: UIColor(rgb: 0x505155, alpha: 0.6)), items: [], selectedIndex: 0, cornerRadius: 16.0)
self.node = SegmentedControlNode(theme: SegmentedControlTheme(backgroundColor: .clear, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shadowColor: .black, textColor: UIColor(rgb: 0xffffff), dividerColor: UIColor(rgb: 0x505155, alpha: 0.6)), items: [], selectedIndex: 0, cornerRadius: 16.0)
self.knob = UIImageView(image: generateKnobImage())

View File

@ -2,7 +2,7 @@ import Foundation
import UIKit
import Display
final class PenTool: DrawingElement, Codable {
final class PenTool: DrawingElement {
class RenderView: UIView, DrawingRenderView {
private weak var element: PenTool?
private var isEraser = false
@ -12,11 +12,10 @@ final class PenTool: DrawingElement, Codable {
private var start = 0
private var segmentsCount = 0
private var velocity: CGFloat?
private var displayScale: CGFloat = 1.0
func setup(size: CGSize, screenSize: CGSize, isEraser: Bool, useDisplayLink: Bool) {
func setup(size: CGSize, screenSize: CGSize, isEraser: Bool) {
self.isEraser = isEraser
self.backgroundColor = .clear
@ -75,7 +74,7 @@ final class PenTool: DrawingElement, Codable {
})
}
fileprivate func draw(element: PenTool, velocity: CGFloat, rect: CGRect) {
fileprivate func draw(element: PenTool, rect: CGRect) {
self.element = element
self.alpha = element.color.alpha
@ -105,7 +104,7 @@ final class PenTool: DrawingElement, Codable {
context.scaleBy(x: 1.0 / self.displayScale, y: 1.0 / self.displayScale)
context.setBlendMode(.copy)
element.drawSegments(in: context, from: self.start, upTo: newStart)
element.drawSegments(in: context, from: self.start, to: newStart)
}, opaque: false)
self.accumulationImage = image
self.layer.contents = image?.cgImage
@ -115,11 +114,6 @@ final class PenTool: DrawingElement, Codable {
self.segmentsCount = element.segments.count
// if let previous = self.velocity {
// self.velocity = velocity * 0.4 + previous * 0.6
// } else {
// self.velocity = velocity
// }
if let rect = rect {
self.activeView?.setNeedsDisplay(rect.insetBy(dx: -10.0, dy: -10.0).applying(CGAffineTransform(scaleX: 1.0 / self.displayScale, y: 1.0 / self.displayScale)))
} else {
@ -134,7 +128,7 @@ final class PenTool: DrawingElement, Codable {
return
}
context.scaleBy(x: 1.0 / parent.displayScale, y: 1.0 / parent.displayScale)
element.drawSegments(in: context, from: parent.start, upTo: parent.segmentsCount)
element.drawSegments(in: context, from: parent.start, to: parent.segmentsCount)
}
}
}
@ -195,67 +189,7 @@ final class PenTool: DrawingElement, Codable {
self.renderColor = color.withUpdatedAlpha(1.0).toUIColor()
}
private enum CodingKeys: String, CodingKey {
case uuid
case drawingSize
case color
case isEraser
case hasArrow
case isBlur
case renderLineWidth
case renderMinLineWidth
case renderArrowLength
case renderArrowLineWidth
case arrowStart
case arrowDirection
case renderSegments
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.uuid = try container.decode(UUID.self, forKey: .uuid)
self.drawingSize = try container.decode(CGSize.self, forKey: .drawingSize)
self.color = try container.decode(DrawingColor.self, forKey: .color)
self.isEraser = try container.decode(Bool.self, forKey: .isEraser)
self.hasArrow = try container.decode(Bool.self, forKey: .hasArrow)
self.isBlur = try container.decode(Bool.self, forKey: .isBlur)
self.renderLineWidth = try container.decode(CGFloat.self, forKey: .renderLineWidth)
self.renderMinLineWidth = try container.decode(CGFloat.self, forKey: .renderMinLineWidth)
self.renderArrowLength = try container.decode(CGFloat.self, forKey: .renderArrowLength)
self.renderArrowLineWidth = try container.decode(CGFloat.self, forKey: .renderArrowLineWidth)
self.arrowStart = try container.decodeIfPresent(CGPoint.self, forKey: .arrowStart)
self.arrowDirection = try container.decodeIfPresent(CGFloat.self, forKey: .arrowDirection)
self.segments = try container.decode([Segment].self, forKey: .renderSegments)
self.renderColor = self.color.withUpdatedAlpha(1.0).toUIColor()
self.maybeSetupArrow()
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.uuid, forKey: .uuid)
try container.encode(self.drawingSize, forKey: .drawingSize)
try container.encode(self.color, forKey: .color)
try container.encode(self.isEraser, forKey: .isEraser)
try container.encode(self.hasArrow, forKey: .hasArrow)
try container.encode(self.isBlur, forKey: .isBlur)
try container.encode(self.renderLineWidth, forKey: .renderLineWidth)
try container.encode(self.renderMinLineWidth, forKey: .renderMinLineWidth)
try container.encode(self.renderArrowLength, forKey: .renderArrowLength)
try container.encode(self.renderArrowLineWidth, forKey: .renderArrowLineWidth)
try container.encodeIfPresent(self.arrowStart, forKey: .arrowStart)
try container.encodeIfPresent(self.arrowDirection, forKey: .arrowDirection)
try container.encode(self.segments, forKey: .renderSegments)
}
var isFinishingArrow = false
func finishArrow(_ completion: @escaping () -> Void) {
if let arrowStart, let arrowDirection {
@ -271,7 +205,7 @@ final class PenTool: DrawingElement, Codable {
func setupRenderView(screenSize: CGSize) -> DrawingRenderView? {
let view = RenderView()
view.setup(size: self.drawingSize, screenSize: screenSize, isEraser: self.isEraser, useDisplayLink: self.color.toUIColor().rgb == 0xbf5af2)
view.setup(size: self.drawingSize, screenSize: screenSize, isEraser: self.isEraser)
self.currentRenderView = view
return view
}
@ -290,9 +224,9 @@ final class PenTool: DrawingElement, Codable {
if point.velocity > 1200.0 {
filterDistance = 70.0
} else {
filterDistance = 15.0
filterDistance = 5.0
}
if let previousPoint, point.location.distance(to: previousPoint) < filterDistance, state == .changed, self.segments.count > 1 {
return
}
@ -312,7 +246,7 @@ final class PenTool: DrawingElement, Codable {
let rect = append(point: Point(position: point.location, width: effectiveRenderLineWidth))
if let currentRenderView = self.currentRenderView as? RenderView, let rect = rect {
currentRenderView.draw(element: self, velocity: point.velocity, rect: rect)
currentRenderView.draw(element: self, rect: rect)
}
if state == .ended {
@ -385,7 +319,7 @@ final class PenTool: DrawingElement, Codable {
if self.isBlur, let blurredImage = self.blurredImage {
let maskContext = DrawingContext(size: size, scale: 0.5, clear: true)
maskContext?.withFlippedContext { maskContext in
self.drawSegments(in: maskContext, from: 0, upTo: self.segments.count)
self.drawSegments(in: maskContext, from: 0, to: self.segments.count)
}
if let maskImage = maskContext?.generateImage()?.cgImage, let blurredImage = blurredImage.cgImage {
context.clip(to: CGRect(origin: .zero, size: size), mask: maskImage)
@ -396,7 +330,7 @@ final class PenTool: DrawingElement, Codable {
}
} else {
self.drawSegments(in: context, from: 0, upTo: self.segments.count)
self.drawSegments(in: context, from: 0, to: self.segments.count)
}
if let arrowLeftPath, let arrowRightPath {
@ -434,38 +368,6 @@ final class PenTool: DrawingElement, Codable {
self.radius2 = radius2
self.rect = rect
}
private enum CodingKeys: String, CodingKey {
case a
case b
case c
case d
case radius1
case radius2
case rect
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.a = try container.decode(CGPoint.self, forKey: .a)
self.b = try container.decode(CGPoint.self, forKey: .b)
self.c = try container.decode(CGPoint.self, forKey: .c)
self.d = try container.decode(CGPoint.self, forKey: .d)
self.radius1 = try container.decode(CGFloat.self, forKey: .radius1)
self.radius2 = try container.decode(CGFloat.self, forKey: .radius2)
self.rect = try container.decode(CGRect.self, forKey: .rect)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.a, forKey: .a)
try container.encode(self.b, forKey: .b)
try container.encode(self.c, forKey: .c)
try container.encode(self.d, forKey: .d)
try container.encode(self.radius1, forKey: .radius1)
try container.encode(self.radius2, forKey: .radius2)
try container.encode(self.rect, forKey: .rect)
}
}
private struct Point {
@ -708,11 +610,10 @@ final class PenTool: DrawingElement, Codable {
return path
}
private func drawSegments(in context: CGContext, from: Int, upTo: Int) {
// context.setStrokeColor(self.renderColor.cgColor)
private func drawSegments(in context: CGContext, from: Int, to: Int) {
context.setFillColor(self.renderColor.cgColor)
for i in from ..< upTo {
for i in from ..< to {
let segment = self.segments[i]
var segmentPath: CGPath
@ -726,7 +627,6 @@ final class PenTool: DrawingElement, Codable {
context.addPath(segmentPath)
context.fillPath()
// context.strokePath()
}
}
}

View File

@ -47,9 +47,7 @@ enum DrawingTextAlignment: Equatable {
enum DrawingTextFont: Equatable, Hashable {
case sanFrancisco
case newYork
case monospaced
case round
case custom(String, String)
case other(String, String)
init(font: DrawingTextEntity.Font) {
switch font {
@ -57,12 +55,8 @@ enum DrawingTextFont: Equatable, Hashable {
self = .sanFrancisco
case .newYork:
self = .newYork
case .monospaced:
self = .monospaced
case .round:
self = .round
case let .custom(font, name):
self = .custom(font, name)
case let .other(font, name):
self = .other(font, name)
}
}
@ -72,12 +66,8 @@ enum DrawingTextFont: Equatable, Hashable {
return .sanFrancisco
case .newYork:
return .newYork
case .monospaced:
return .monospaced
case .round:
return .round
case let .custom(font, name):
return .custom(font, name)
case let .other(font, name):
return .other(font, name)
}
}
@ -87,27 +77,19 @@ enum DrawingTextFont: Equatable, Hashable {
return "San Francisco"
case .newYork:
return "New York"
case .monospaced:
return "Monospaced"
case .round:
return "Rounded"
case let .custom(_, name):
case let .other(_, name):
return name
}
}
var uiFont: UIFont {
func uiFont(size: CGFloat) -> UIFont {
switch self {
case .sanFrancisco:
return Font.semibold(13.0)
return Font.semibold(size)
case .newYork:
return Font.with(size: 13.0, design: .serif, weight: .semibold)
case .monospaced:
return Font.with(size: 13.0, design: .monospace, weight: .semibold)
case .round:
return Font.with(size: 13.0, design: .round, weight: .semibold)
case let .custom(font, _):
return UIFont(name: font, size: 13.0) ?? Font.semibold(13.0)
return Font.with(size: size, design: .serif, weight: .semibold)
case let .other(font, _):
return UIFont(name: font, size: size) ?? Font.semibold(size)
}
}
}
@ -185,40 +167,24 @@ final class TextAlignmentComponent: Component {
}
final class TextFontComponent: Component {
let styleButton: AnyComponent<Empty>
let alignmentButton: AnyComponent<Empty>
let values: [DrawingTextFont]
let selectedValue: DrawingTextFont
let tag: AnyObject?
let updated: (DrawingTextFont) -> Void
let tapped: () -> Void
init(styleButton: AnyComponent<Empty>, alignmentButton: AnyComponent<Empty>, values: [DrawingTextFont], selectedValue: DrawingTextFont, tag: AnyObject?, updated: @escaping (DrawingTextFont) -> Void) {
self.styleButton = styleButton
self.alignmentButton = alignmentButton
self.values = values
init(selectedValue: DrawingTextFont, tag: AnyObject?, tapped: @escaping () -> Void) {
self.selectedValue = selectedValue
self.tag = tag
self.updated = updated
self.tapped = tapped
}
static func == (lhs: TextFontComponent, rhs: TextFontComponent) -> Bool {
return lhs.styleButton == rhs.styleButton && lhs.alignmentButton == rhs.alignmentButton && lhs.values == rhs.values && lhs.selectedValue == rhs.selectedValue
return lhs.selectedValue == rhs.selectedValue
}
final class View: UIView, ComponentTaggedView {
private let styleButtonHost: ComponentView<Empty>
private let alignmentButtonHost: ComponentView<Empty>
private var buttons: [DrawingTextFont: HighlightableButton] = [:]
private let scrollView = UIScrollView()
private let scrollMask = UIView()
private let maskLeft = SimpleGradientLayer()
private let maskCenter = SimpleLayer()
private let maskRight = SimpleGradientLayer()
private var button = HighlightableButton()
private var component: TextFontComponent?
private var updated: (DrawingTextFont) -> Void = { _ in }
public func matches(tag: Any) -> Bool {
if let component = self.component, let componentTag = component.tag {
@ -231,39 +197,9 @@ final class TextFontComponent: Component {
}
override init(frame: CGRect) {
if #available(iOS 11.0, *) {
self.scrollView.contentInsetAdjustmentBehavior = .never
}
self.scrollView.showsHorizontalScrollIndicator = false
self.scrollView.showsVerticalScrollIndicator = false
self.scrollView.decelerationRate = .fast
self.styleButtonHost = ComponentView()
self.alignmentButtonHost = ComponentView()
super.init(frame: frame)
self.mask = self.scrollMask
self.maskLeft.type = .axial
self.maskLeft.startPoint = CGPoint(x: 0.0, y: 0.5)
self.maskLeft.endPoint = CGPoint(x: 1.0, y: 0.5)
self.maskLeft.colors = [UIColor.white.withAlphaComponent(0.0).cgColor, UIColor.white.cgColor]
self.maskLeft.locations = [0.0, 1.0]
self.maskCenter.backgroundColor = UIColor.white.cgColor
self.maskRight.type = .axial
self.maskRight.startPoint = CGPoint(x: 0.0, y: 0.5)
self.maskRight.endPoint = CGPoint(x: 1.0, y: 0.5)
self.maskRight.colors = [UIColor.white.cgColor, UIColor.white.withAlphaComponent(0.0).cgColor]
self.maskRight.locations = [0.0, 1.0]
self.scrollMask.layer.addSublayer(self.maskLeft)
self.scrollMask.layer.addSublayer(self.maskCenter)
self.scrollMask.layer.addSublayer(self.maskRight)
self.addSubview(self.scrollView)
self.addSubview(self.button)
}
required init?(coder: NSCoder) {
@ -271,160 +207,26 @@ final class TextFontComponent: Component {
}
@objc private func pressed(_ sender: HighlightableButton) {
for (font, button) in self.buttons {
if button === sender {
self.updated(font)
break
}
}
}
func animateIn() {
var delay: Double = 0.0
if let view = self.styleButtonHost.view {
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
view.layer.animateScale(from: 0.01, to: 1.0, duration: 0.2)
delay += 0.02
}
if let view = self.alignmentButtonHost.view {
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, delay: delay)
view.layer.animateScale(from: 0.01, to: 1.0, duration: 0.2, delay: delay)
delay += 0.02
}
if let component = self.component {
for value in component.values {
if let view = self.buttons[value] {
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, delay: delay)
view.layer.animateScale(from: 0.01, to: 1.0, duration: 0.2, delay: delay)
delay += 0.02
}
}
component.tapped()
}
}
func animateOut(completion: @escaping () -> Void) {
if let view = self.styleButtonHost.view {
view.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
}
if let view = self.alignmentButtonHost.view {
view.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
}
if let component = self.component {
for value in component.values {
if let view = self.buttons[value] {
view.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
}
}
}
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
completion()
})
}
private var previousValue: DrawingTextFont?
func update(component: TextFontComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
self.component = component
self.updated = component.updated
var contentWidth: CGFloat = 10.0
let value = component.selectedValue
let styleSize = self.styleButtonHost.update(
transition: transition,
component: component.styleButton,
environment: {},
containerSize: CGSize(width: 30.0, height: 30.0)
)
if let view = self.styleButtonHost.view {
if view.superview == nil {
self.scrollView.addSubview(view)
}
view.frame = CGRect(origin: CGPoint(x: contentWidth - 7.0, y: -7.0), size: styleSize)
}
self.button.setTitle(value.title, for: .normal)
self.button.titleLabel?.font = value.uiFont(size: 13.0)
self.button.sizeToFit()
self.button.frame = CGRect(origin: .zero, size: CGSize(width: self.button.frame.width + 16.0, height: 30.0))
self.button.layer.cornerRadius = 11.0
self.button.layer.borderWidth = 1.0 - UIScreenPixel
self.button.layer.borderColor = UIColor.white.cgColor
self.button.addTarget(self, action: #selector(self.pressed(_:)), for: .touchUpInside)
contentWidth += 44.0
let alignmentSize = self.alignmentButtonHost.update(
transition: transition,
component: component.alignmentButton,
environment: {},
containerSize: CGSize(width: 30.0, height: 30.0)
)
if let view = self.alignmentButtonHost.view {
if view.superview == nil {
self.scrollView.addSubview(view)
}
view.frame = CGRect(origin: CGPoint(x: contentWidth - 7.0, y: -6.0 - UIScreenPixel), size: alignmentSize)
}
contentWidth += 36.0
var validIds = Set<DrawingTextFont>()
for value in component.values {
validIds.insert(value)
contentWidth += 12.0
let button: HighlightableButton
if let current = self.buttons[value] {
button = current
} else {
button = HighlightableButton()
button.setTitle(value.title, for: .normal)
button.titleLabel?.font = value.uiFont
button.sizeToFit()
button.frame = CGRect(origin: .zero, size: CGSize(width: button.frame.width + 16.0, height: 30.0))
button.layer.cornerRadius = 11.0
button.addTarget(self, action: #selector(self.pressed(_:)), for: .touchUpInside)
self.buttons[value] = button
self.scrollView.addSubview(button)
}
if value == component.selectedValue {
button.layer.borderWidth = 1.0 - UIScreenPixel
button.layer.borderColor = UIColor.white.cgColor
} else {
button.layer.borderWidth = UIScreenPixel
button.layer.borderColor = UIColor.white.withAlphaComponent(0.5).cgColor
}
button.frame = CGRect(origin: CGPoint(x: contentWidth, y: 0.0), size: button.frame.size)
contentWidth += button.frame.width
}
contentWidth += 12.0
for (font, button) in self.buttons {
if !validIds.contains(font) {
button.removeFromSuperview()
self.buttons[font] = nil
}
}
if self.scrollView.contentSize.width != contentWidth {
self.scrollView.contentSize = CGSize(width: contentWidth, height: 30.0)
}
self.scrollView.frame = CGRect(origin: .zero, size: availableSize)
self.scrollMask.frame = CGRect(origin: .zero, size: availableSize)
self.maskLeft.frame = CGRect(origin: .zero, size: CGSize(width: 12.0, height: 30.0))
self.maskCenter.frame = CGRect(origin: CGPoint(x: 12.0, y: 0.0), size: CGSize(width: availableSize.width - 24.0, height: 30.0))
self.maskRight.frame = CGRect(origin: CGPoint(x: availableSize.width - 12.0, y: 0.0), size: CGSize(width: 12.0, height: 30.0))
if component.selectedValue != self.previousValue {
self.previousValue = component.selectedValue
if let button = self.buttons[component.selectedValue] {
self.scrollView.scrollRectToVisible(button.frame.insetBy(dx: -48.0, dy: 0.0), animated: true)
}
}
return availableSize
return CGSize(width: self.button.frame.width, height: availableSize.height)
}
}
@ -444,6 +246,7 @@ final class TextSettingsComponent: CombinedComponent {
let font: DrawingTextFont
let isEmojiKeyboard: Bool
let tag: AnyObject?
let fontTag: AnyObject?
let presentColorPicker: () -> Void
let presentFastColorPicker: (GenericComponentViewTag) -> Void
@ -451,7 +254,7 @@ final class TextSettingsComponent: CombinedComponent {
let dismissFastColorPicker: () -> Void
let toggleStyle: () -> Void
let toggleAlignment: () -> Void
let updateFont: (DrawingTextFont) -> Void
let presentFontPicker: () -> Void
let toggleKeyboard: (() -> Void)?
init(
@ -461,13 +264,14 @@ final class TextSettingsComponent: CombinedComponent {
font: DrawingTextFont,
isEmojiKeyboard: Bool,
tag: AnyObject?,
fontTag: AnyObject?,
presentColorPicker: @escaping () -> Void = {},
presentFastColorPicker: @escaping (GenericComponentViewTag) -> Void = { _ in },
updateFastColorPickerPan: @escaping (CGPoint) -> Void = { _ in },
dismissFastColorPicker: @escaping () -> Void = {},
toggleStyle: @escaping () -> Void,
toggleAlignment: @escaping () -> Void,
updateFont: @escaping (DrawingTextFont) -> Void,
presentFontPicker: @escaping () -> Void,
toggleKeyboard: (() -> Void)?
) {
self.color = color
@ -476,13 +280,14 @@ final class TextSettingsComponent: CombinedComponent {
self.font = font
self.isEmojiKeyboard = isEmojiKeyboard
self.tag = tag
self.fontTag = fontTag
self.presentColorPicker = presentColorPicker
self.presentFastColorPicker = presentFastColorPicker
self.updateFastColorPickerPan = updateFastColorPickerPan
self.dismissFastColorPicker = dismissFastColorPicker
self.toggleStyle = toggleStyle
self.toggleAlignment = toggleAlignment
self.updateFont = updateFont
self.presentFontPicker = presentFontPicker
self.toggleKeyboard = toggleKeyboard
}
@ -540,6 +345,46 @@ final class TextSettingsComponent: CombinedComponent {
}
}
class View: UIView, ComponentTaggedView {
var componentTag: AnyObject?
public func matches(tag: Any) -> Bool {
if let componentTag = self.componentTag {
let tag = tag as AnyObject
if componentTag === tag {
return true
}
}
return false
}
func animateIn() {
var delay: Double = 0.0
for view in self.subviews {
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, delay: delay)
view.layer.animateScale(from: 0.01, to: 1.0, duration: 0.2, delay: delay)
delay += 0.02
}
}
func animateOut(completion: @escaping () -> Void) {
var isFirst = true
for view in self.subviews {
view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: isFirst ? { _ in
completion()
} : nil)
view.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
isFirst = false
}
}
}
func makeView() -> View {
let view = View()
view.componentTag = self.tag
return view
}
func makeState() -> State {
State()
}
@ -548,6 +393,8 @@ final class TextSettingsComponent: CombinedComponent {
let colorButton = Child(ColorSwatchComponent.self)
let colorButtonTag = GenericComponentViewTag()
let alignmentButton = Child(Button.self)
let styleButton = Child(Button.self)
let keyboardButton = Child(Button.self)
let font = Child(TextFontComponent.self)
@ -557,7 +404,6 @@ final class TextSettingsComponent: CombinedComponent {
let toggleStyle = component.toggleStyle
let toggleAlignment = component.toggleAlignment
let updateFont = component.updateFont
var offset: CGFloat = 6.0
if let color = component.color {
@ -588,9 +434,9 @@ final class TextSettingsComponent: CombinedComponent {
transition: context.transition
)
context.add(colorButton
.position(CGPoint(x: colorButton.size.width / 2.0, y: context.availableSize.height / 2.0))
.position(CGPoint(x: colorButton.size.width / 2.0 + 2.0, y: context.availableSize.height / 2.0))
)
offset += 32.0
offset += 42.0
}
let styleImage: UIImage
@ -610,55 +456,53 @@ final class TextSettingsComponent: CombinedComponent {
fontAvailableWidth -= 72.0
}
var fonts: [DrawingTextFont] = [
.sanFrancisco,
.newYork,
.monospaced,
.round
]
if case .custom = component.font {
fonts.insert(component.font, at: 0)
}
let font = font.update(
component: TextFontComponent(
styleButton: AnyComponent(
Button(
content: AnyComponent(
Image(
image: styleImage
)
),
action: {
toggleStyle()
}
).minSize(CGSize(width: 44.0, height: 44.0))
let styleButton = styleButton.update(
component: Button(
content: AnyComponent(
Image(
image: styleImage
)
),
alignmentButton: AnyComponent(
Button(
content: AnyComponent(
TextAlignmentComponent(
alignment: component.alignment
)
),
action: {
toggleAlignment()
}
).minSize(CGSize(width: 44.0, height: 44.0))
),
values: fonts,
selectedValue: component.font,
tag: component.tag,
updated: { font in
updateFont(font)
action: {
toggleStyle()
}
),
availableSize: CGSize(width: fontAvailableWidth, height: 30.0),
).minSize(CGSize(width: 44.0, height: 44.0)),
availableSize: CGSize(width: 30.0, height: 30.0),
transition: .easeInOut(duration: 0.2)
)
context.add(font
.position(CGPoint(x: offset + font.size.width / 2.0, y: context.availableSize.height / 2.0))
context.add(styleButton
.position(CGPoint(x: offset + styleButton.size.width / 2.0, y: context.availableSize.height / 2.0))
.update(Transition.Update { _, view, transition in
if let snapshot = view.snapshotView(afterScreenUpdates: false) {
transition.setAlpha(view: snapshot, alpha: 0.0, completion: { [weak snapshot] _ in
snapshot?.removeFromSuperview()
})
snapshot.frame = view.frame
transition.animateAlpha(view: view, from: 0.0, to: 1.0)
view.superview?.addSubview(snapshot)
}
})
)
offset += 44.0
let alignmentButton = alignmentButton.update(
component: Button(
content: AnyComponent(
TextAlignmentComponent(
alignment: component.alignment
)
),
action: {
toggleAlignment()
}
).minSize(CGSize(width: 44.0, height: 44.0)),
availableSize: context.availableSize,
transition: .easeInOut(duration: 0.2)
)
context.add(alignmentButton
.position(CGPoint(x: offset + alignmentButton.size.width / 2.0, y: context.availableSize.height / 2.0 + 1.0 - UIScreenPixel))
)
offset += 45.0
if let toggleKeyboard = component.toggleKeyboard {
let keyboardButton = keyboardButton.update(
@ -675,13 +519,28 @@ final class TextSettingsComponent: CombinedComponent {
}
).minSize(CGSize(width: 44.0, height: 44.0)),
availableSize: CGSize(width: 32.0, height: 32.0),
transition: .easeInOut(duration: 0.2)
transition: .easeInOut(duration: 0.15)
)
context.add(keyboardButton
.position(CGPoint(x: context.availableSize.width - keyboardButton.size.width / 2.0, y: context.availableSize.height / 2.0))
.position(CGPoint(x: offset + keyboardButton.size.width / 2.0 + (component.isEmojiKeyboard ? 3.0 : 0.0), y: context.availableSize.height / 2.0))
)
}
let font = font.update(
component: TextFontComponent(
selectedValue: component.font,
tag: component.fontTag,
tapped: {
component.presentFontPicker()
}
),
availableSize: CGSize(width: fontAvailableWidth, height: 30.0),
transition: .easeInOut(duration: 0.2)
)
context.add(font
.position(CGPoint(x: context.availableSize.width - font.size.width / 2.0 - 16.0, y: context.availableSize.height / 2.0))
)
return context.availableSize
}
}

View File

@ -7,7 +7,7 @@
@protocol TGPhotoPaintEntityRenderer <NSObject>
- (void)entitiesForTime:(CMTime)time fps:(NSInteger)fps size:(CGSize)size completion:(void(^)(NSArray<CIImage *> *))completion;
- (void)entitiesForTime:(CMTime)time fps:(NSInteger)fps size:(CGSize)size completion:(void(^_Nonnull)(NSArray<CIImage *> * _Nonnull))completion;
@end
@ -17,45 +17,18 @@
@end
@protocol TGPhotoPaintStickerRenderView <NSObject>
@property (nonatomic, copy) void(^started)(double);
- (void)setIsVisible:(bool)isVisible;
- (void)seekTo:(double)timestamp;
- (void)play;
- (void)pause;
- (void)resetToStart;
- (void)playFromFrame:(NSInteger)frameIndex;
- (void)copyStickerView:(NSObject<TGPhotoPaintStickerRenderView> *)view;
- (int64_t)documentId;
- (UIImage *)image;
@end
@protocol TGPhotoPaintStickersScreen <NSObject>
@property (nonatomic, copy) void(^screenDidAppear)(void);
@property (nonatomic, copy) void(^screenWillDisappear)(void);
- (void)restore;
- (void)invalidate;
@end
@protocol TGCaptionPanelView <NSObject>
@property (nonatomic, readonly) UIView *view;
@property (nonatomic, readonly) UIView * _Nonnull view;
- (NSAttributedString *)caption;
- (void)setCaption:(NSAttributedString *)caption;
- (NSAttributedString * _Nonnull)caption;
- (void)setCaption:(NSAttributedString * _Nullable)caption;
- (void)dismissInput;
@property (nonatomic, copy) void(^sendPressed)(NSAttributedString *string);
@property (nonatomic, copy) void(^focusUpdated)(BOOL focused);
@property (nonatomic, copy) void(^heightUpdated)(BOOL animated);
@property (nonatomic, copy) void(^ _Nullable sendPressed)(NSAttributedString * _Nullable string);
@property (nonatomic, copy) void(^ _Nullable focusUpdated)(BOOL focused);
@property (nonatomic, copy) void(^ _Nullable heightUpdated)(BOOL animated);
- (CGFloat)updateLayoutSize:(CGSize)size sideInset:(CGFloat)sideInset;
- (CGFloat)baseHeight;
@ -67,20 +40,20 @@
@property (nonatomic, readonly) BOOL isTracking;
@property (nonatomic, copy) void(^zoomOut)(void);
@property (nonatomic, copy) void(^ _Nonnull zoomOut)(void);
- (void)updateZoomScale:(CGFloat)scale;
- (void)setupWithDrawingData:(NSData *)drawingData;
- (void)setupWithDrawingData:(NSData * _Nullable)drawingData;
@end
@protocol TGPhotoDrawingEntitiesView <NSObject>
@property (nonatomic, copy) CGPoint (^getEntityCenterPosition)(void);
@property (nonatomic, copy) CGFloat (^getEntityInitialRotation)(void);
@property (nonatomic, copy) CGPoint (^ _Nonnull getEntityCenterPosition)(void);
@property (nonatomic, copy) CGFloat (^ _Nonnull getEntityInitialRotation)(void);
@property (nonatomic, copy) void(^hasSelectionChanged)(bool);
@property (nonatomic, copy) void(^ _Nonnull hasSelectionChanged)(bool);
@property (nonatomic, readonly) BOOL hasSelection;
- (void)play;
@ -91,22 +64,22 @@
- (void)clearSelection;
- (void)onZoom;
- (void)handlePinch:(UIPinchGestureRecognizer *)gestureRecognizer;
- (void)handleRotate:(UIRotationGestureRecognizer *)gestureRecognizer;
- (void)handlePinch:(UIPinchGestureRecognizer * _Nonnull)gestureRecognizer;
- (void)handleRotate:(UIRotationGestureRecognizer * _Nonnull)gestureRecognizer;
- (void)setupWithEntitiesData:(NSData *)entitiesData;
- (void)setupWithEntitiesData:(NSData * _Nullable)entitiesData;
@end
@protocol TGPhotoDrawingInterfaceController <NSObject>
@property (nonatomic, copy) void(^requestDismiss)(void);
@property (nonatomic, copy) void(^requestApply)(void);
@property (nonatomic, copy) UIImage *(^getCurrentImage)(void);
@property (nonatomic, copy) void(^updateVideoPlayback)(bool);
@property (nonatomic, copy) void(^ _Nonnull requestDismiss)(void);
@property (nonatomic, copy) void(^ _Nonnull requestApply)(void);
@property (nonatomic, copy) UIImage * _Nullable(^ _Nonnull getCurrentImage)(void);
@property (nonatomic, copy) void(^ _Nonnull updateVideoPlayback)(bool);
- (TGPaintingData *)generateResultData;
- (void)animateOut:(void(^)(void))completion;
- (TGPaintingData * _Nullable)generateResultData;
- (void)animateOut:(void(^_Nonnull)(void))completion;
- (void)adapterContainerLayoutUpdatedSize:(CGSize)size
intrinsicInsets:(UIEdgeInsets)intrinsicInsets
@ -121,30 +94,23 @@
@protocol TGPhotoDrawingAdapter <NSObject>
@property (nonatomic, readonly) id<TGPhotoDrawingView> drawingView;
@property (nonatomic, readonly) id<TGPhotoDrawingEntitiesView> drawingEntitiesView;
@property (nonatomic, readonly) UIView * selectionContainerView;
@property (nonatomic, readonly) UIView * contentWrapperView;
@property (nonatomic, readonly) id<TGPhotoDrawingInterfaceController> interfaceController;
@property (nonatomic, readonly) id<TGPhotoDrawingView> _Nonnull drawingView;
@property (nonatomic, readonly) id<TGPhotoDrawingEntitiesView> _Nonnull drawingEntitiesView;
@property (nonatomic, readonly) UIView * _Nonnull selectionContainerView;
@property (nonatomic, readonly) UIView * _Nonnull contentWrapperView;
@property (nonatomic, readonly) id<TGPhotoDrawingInterfaceController> _Nonnull interfaceController;
@end
@protocol TGPhotoPaintStickersContext <NSObject>
- (int64_t)documentIdForDocument:(id)document;
- (TGStickerMaskDescription *)maskDescriptionForDocument:(id)document;
- (UIView<TGPhotoPaintStickerRenderView> *)stickerViewForDocument:(id)document;
@property (nonatomic, copy) id<TGPhotoPaintStickersScreen>(^presentStickersController)(void(^)(id, bool, UIView *, CGRect));
@property (nonatomic, copy) id<TGCaptionPanelView>(^captionPanelView)(void);
@property (nonatomic, copy) id<TGCaptionPanelView> _Nullable(^ _Nullable captionPanelView)(void);
- (UIView<TGPhotoSolidRoundedButtonView> *)solidRoundedButton:(NSString *)title action:(void(^)(void))action;
- (id<TGPhotoDrawingAdapter>)drawingAdapter:(CGSize)size originalSize:(CGSize)originalSize isVideo:(bool)isVideo isAvatar:(bool)isAvatar;
- (UIView<TGPhotoSolidRoundedButtonView> *_Nonnull)solidRoundedButton:(NSString *_Nonnull)title action:(void(^_Nonnull)(void))action;
- (id<TGPhotoDrawingAdapter> _Nonnull)drawingAdapter:(CGSize)size originalSize:(CGSize)originalSize isVideo:(bool)isVideo isAvatar:(bool)isAvatar entitiesView:(UIView<TGPhotoDrawingEntitiesView> * _Nullable)entitiesView;
- (UIView<TGPhotoDrawingEntitiesView> *)drawingEntitiesViewWithSize:(CGSize)size;
- (UIView<TGPhotoDrawingEntitiesView> * _Nonnull)drawingEntitiesViewWithSize:(CGSize)size;
@end

View File

@ -85,7 +85,7 @@ const CGSize TGPhotoPaintingMaxSize = { 1920.0f, 1920.0f };
_stickersContext = stickersContext;
CGSize size = TGScaleToSize(photoEditor.originalSize, [TGPhotoDrawingController maximumPaintingSize]);
_drawingAdapter = [_stickersContext drawingAdapter:size originalSize:photoEditor.originalSize isVideo:photoEditor.forVideo isAvatar:isAvatar];
_drawingAdapter = [_stickersContext drawingAdapter:size originalSize:photoEditor.originalSize isVideo:photoEditor.forVideo isAvatar:isAvatar entitiesView:entitiesView];
_interfaceController = (UIViewController<TGPhotoDrawingInterfaceController> *)_drawingAdapter.interfaceController;
__weak TGPhotoDrawingController *weakSelf = self;

View File

@ -336,7 +336,7 @@
_fullPaintingView = [[UIImageView alloc] init];
_fullPaintingView.frame = _fullPreviewView.frame;
_fullEntitiesView = [_stickersContext drawingEntitiesViewWithSize:CGSizeMake(0, 0)];
_fullEntitiesView = [_stickersContext drawingEntitiesViewWithSize:_photoEditor.originalSize];
_fullEntitiesView.userInteractionEnabled = false;
CGRect rect = [TGPhotoDrawingController fittedCropRect:_photoEditor.cropRect originalSize:_photoEditor.originalSize keepOriginalSize:true];
_fullEntitiesView.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);

View File

@ -1162,35 +1162,6 @@
//
//#pragma mark Stickers
//
//- (void)presentStickersView
//{
// if (_stickersScreen != nil) {
// [_stickersScreen restore];
// return;
// }
//
// __weak TGPhotoPaintController *weakSelf = self;
// _stickersScreen = _stickersContext.presentStickersController(^(id document, bool animated, UIView *view, CGRect rect) {
// __strong TGPhotoPaintController *strongSelf = weakSelf;
// if (strongSelf != nil) {
// [strongSelf createNewStickerWithDocument:document animated:animated transitionPoint:CGPointZero snapshotView:nil];
// }
// });
// _stickersScreen.screenDidAppear = ^{
// __strong TGPhotoPaintController *strongSelf = weakSelf;
// if (strongSelf != nil) {
// strongSelf.controlVideoPlayback(false);
// [strongSelf->_entitiesContainerView updateVisibility:false];
// }
// };
// _stickersScreen.screenWillDisappear = ^{
// __strong TGPhotoPaintController *strongSelf = weakSelf;
// if (strongSelf != nil) {
// strongSelf.controlVideoPlayback(true);
// [strongSelf->_entitiesContainerView updateVisibility:true];
// }
// };
//}
//
//- (void)createNewStickerWithDocument:(id)document animated:(bool)animated transitionPoint:(CGPoint)transitionPoint snapshotView:(UIView *)snapshotView
//{

View File

@ -32,8 +32,6 @@ const CGFloat TGPhotoStickerSelectionViewHandleSide = 30.0f;
@interface TGPhotoStickerEntityView ()
{
UIView<TGPhotoPaintStickerRenderView> *_stickerView;
id _document;
bool _animated;
bool _mirrored;
@ -53,17 +51,7 @@ const CGFloat TGPhotoStickerSelectionViewHandleSide = 30.0f;
_entityUUID = entity.uuid;
_baseSize = entity.baseSize;
_mirrored = entity.isMirrored;
_stickerView = [context stickerViewForDocument:entity.document];
__weak TGPhotoStickerEntityView *weakSelf = self;
_stickerView.started = ^(double duration) {
__strong TGPhotoStickerEntityView *strongSelf = weakSelf;
if (strongSelf != nil && strongSelf.started != nil)
strongSelf.started(duration);
};
[self addSubview:_stickerView];
_document = entity.document;
_animated = entity.animated;
@ -71,14 +59,9 @@ const CGFloat TGPhotoStickerSelectionViewHandleSide = 30.0f;
CGSize displaySize = [self fittedSizeForSize:imageSize maxSize:CGSizeMake(512.0f, 512.0f)];
_stickerView.frame = CGRectMake(CGFloor((self.frame.size.width - displaySize.width) / 2.0f), CGFloor((self.frame.size.height - displaySize.height) / 2.0f), displaySize.width, displaySize.height);
CGFloat scale = displaySize.width > displaySize.height ? self.frame.size.width / displaySize.width : self.frame.size.height / displaySize.height;
_defaultTransform = CATransform3DMakeScale(scale, scale, 1.0f);
_stickerView.layer.transform = _defaultTransform;
if (_mirrored)
_stickerView.layer.transform = CATransform3DRotate(_defaultTransform, M_PI, 0, 1, 0);
}
return self;
}
@ -127,45 +110,17 @@ const CGFloat TGPhotoStickerSelectionViewHandleSide = 30.0f;
- (bool)precisePointInside:(CGPoint)point
{
CGPoint imagePoint = [_stickerView convertPoint:point fromView:self];
if (![_stickerView pointInside:[_stickerView convertPoint:point fromView:self] withEvent:nil])
return false;
return [_stickerView isOpaqueAtPoint:imagePoint];
return false;
}
- (void)mirror
{
_mirrored = !_mirrored;
if (iosMajorVersion() >= 7)
{
CATransform3D startTransform = _defaultTransform;
if (!_mirrored)
{
startTransform = _stickerView.layer.transform;
}
CATransform3D targetTransform = CATransform3DRotate(_defaultTransform, 0, 0, 1, 0);
if (_mirrored)
{
targetTransform = CATransform3DRotate(_defaultTransform, M_PI, 0, 1, 0);
targetTransform.m34 = -1.0f / _stickerView.frame.size.width;
}
[UIView animateWithDuration:0.25 animations:^
{
_stickerView.layer.transform = targetTransform;
}];
}
else
{
_stickerView.layer.transform = CATransform3DRotate(_defaultTransform, _mirrored ? M_PI : 0, 0, 1, 0);
}
}
- (UIImage *)image
{
return [_stickerView image];
return nil;
}
- (TGPhotoPaintEntitySelectionView *)createSelectionView
@ -182,35 +137,35 @@ const CGFloat TGPhotoStickerSelectionViewHandleSide = 30.0f;
}
- (void)updateVisibility:(bool)visible {
[_stickerView setIsVisible:visible];
}
- (void)seekTo:(double)timestamp {
[_stickerView seekTo:timestamp];
}
- (void)play {
[_stickerView play];
}
- (void)pause {
[_stickerView pause];
}
- (void)resetToStart {
[_stickerView resetToStart];
}
- (void)playFromFrame:(NSInteger)frameIndex {
[_stickerView playFromFrame:frameIndex];
}
- (void)copyStickerView:(TGPhotoStickerEntityView *)view {
[_stickerView copyStickerView:view->_stickerView];
}
- (int64_t)documentId {
return [_stickerView documentId];
return 0;
}
@end

View File

@ -58,7 +58,7 @@ public enum LegacyAttachmentMenuMediaEditing {
case file
}
public func legacyMediaEditor(context: AccountContext, peer: Peer, threadTitle: String?, media: AnyMediaReference, initialCaption: NSAttributedString, snapshots: [UIView], transitionCompletion: (() -> Void)?, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, present: @escaping (ViewController, Any?) -> Void) {
public func legacyMediaEditor(context: AccountContext, peer: Peer, threadTitle: String?, media: AnyMediaReference, initialCaption: NSAttributedString, snapshots: [UIView], transitionCompletion: (() -> Void)?, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, present: @escaping (ViewController, Any?) -> Void) {
let _ = (fetchMediaData(context: context, postbox: context.account.postbox, userLocation: .other, mediaReference: media)
|> deliverOnMainQueue).start(next: { (value, isImage) in
guard case let .data(data) = value, data.complete else {
@ -76,13 +76,6 @@ public func legacyMediaEditor(context: AccountContext, peer: Peer, threadTitle:
paintStickersContext.captionPanelView = {
return getCaptionPanelView()
}
paintStickersContext.presentStickersController = { completion in
return presentStickers({ file, animated, view, rect in
let coder = PostboxEncoder()
coder.encodeRootObject(file)
completion?(coder.makeData(), animated, view, rect)
})
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let recipientName: String
@ -132,7 +125,7 @@ public func legacyMediaEditor(context: AccountContext, peer: Peer, threadTitle:
})
}
public func legacyAttachmentMenu(context: AccountContext, peer: Peer, threadTitle: String?, chatLocation: ChatLocation, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, canSendPolls: Bool, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: NSAttributedString, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentJpegConversionAlert: @escaping (@escaping (Bool) -> Void) -> Void, presentSchedulePicker: @escaping (Bool, @escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32, ((String) -> UIView?)?, @escaping () -> Void) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, present: @escaping (ViewController, Any?) -> Void) -> TGMenuSheetController {
public func legacyAttachmentMenu(context: AccountContext, peer: Peer, threadTitle: String?, chatLocation: ChatLocation, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, canSendPolls: Bool, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: NSAttributedString, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentJpegConversionAlert: @escaping (@escaping (Bool) -> Void) -> Void, presentSchedulePicker: @escaping (Bool, @escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32, ((String) -> UIView?)?, @escaping () -> Void) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, present: @escaping (ViewController, Any?) -> Void) -> TGMenuSheetController {
let defaultVideoPreset = defaultVideoPresetForContext(context)
UserDefaults.standard.set(defaultVideoPreset.rawValue as NSNumber, forKey: "TG_preferredVideoPreset_v0")
@ -195,13 +188,6 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, threadTitl
paintStickersContext.captionPanelView = {
return getCaptionPanelView()
}
paintStickersContext.presentStickersController = { completion in
return presentStickers({ file, animated, view, rect in
let coder = PostboxEncoder()
coder.encodeRootObject(file)
completion?(coder.makeData(), animated, view, rect)
})
}
if canSendImageOrVideo {
let carouselItem = TGAttachmentCarouselItemView(context: parentController.context, camera: PGCamera.cameraAvailable(), selfPortrait: false, forProfilePhoto: false, assetType: TGMediaAssetAnyType, saveEditedPhotos: !isSecretChat && saveEditedPhotos, allowGrouping: editMediaOptions == nil && allowGrouping, allowSelection: editMediaOptions == nil, allowEditing: true, document: false, selectionLimit: selectionLimit)!

View File

@ -20,18 +20,11 @@ public func guessMimeTypeByFileExtension(_ ext: String) -> String {
return TGMimeTypeMap.mimeType(forExtension: ext) ?? "application/binary"
}
public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, chatLocation: ChatLocation, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: NSAttributedString, hasSchedule: Bool, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void, presentSchedulePicker: @escaping (Bool, @escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, getCaptionPanelView: @escaping () -> TGCaptionPanelView?) {
public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, chatLocation: ChatLocation, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: NSAttributedString, hasSchedule: Bool, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void, presentSchedulePicker: @escaping (Bool, @escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, getCaptionPanelView: @escaping () -> TGCaptionPanelView?) {
let paintStickersContext = LegacyPaintStickersContext(context: context)
paintStickersContext.captionPanelView = {
return getCaptionPanelView()
}
paintStickersContext.presentStickersController = { completion in
return presentStickers({ file, animated, view, rect in
let coder = PostboxEncoder()
coder.encodeRootObject(file)
completion?(coder.makeData(), animated, view, rect)
})
}
controller.captionsEnabled = captionsEnabled
controller.inhibitDocumentCaptions = false

View File

@ -1,187 +0,0 @@
import UIKit
import Display
import TelegramCore
import AccountContext
import SwiftSignalKit
import AnimatedStickerNode
import TelegramAnimatedStickerNode
import StickerResources
import LegacyComponents
class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
var started: ((Double) -> Void)?
private let context: AccountContext
private let file: TelegramMediaFile
private var currentSize: CGSize?
private var dimensions: CGSize?
private let imageNode: TransformImageNode
private var animationNode: AnimatedStickerNode?
private var didSetUpAnimationNode = false
private let stickerFetchedDisposable = MetaDisposable()
private let cachedDisposable = MetaDisposable()
init(context: AccountContext, file: TelegramMediaFile) {
self.context = context
self.file = file
self.imageNode = TransformImageNode()
super.init(frame: CGRect())
self.addSubnode(self.imageNode)
self.setup()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
self.stickerFetchedDisposable.dispose()
self.cachedDisposable.dispose()
}
func image() -> UIImage! {
if self.imageNode.contents != nil {
return UIImage(cgImage: self.imageNode.contents as! CGImage)
} else {
return nil
}
}
func documentId() -> Int64 {
return self.file.fileId.id
}
private func setup() {
if let dimensions = self.file.dimensions {
if self.file.isAnimatedSticker || self.file.isVideoSticker {
if self.animationNode == nil {
let animationNode = DefaultAnimatedStickerNodeImpl()
animationNode.autoplay = false
self.animationNode = animationNode
animationNode.started = { [weak self, weak animationNode] in
self?.imageNode.isHidden = true
if let animationNode = animationNode {
let _ = (animationNode.status
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] status in
self?.started?(status.duration)
})
}
}
self.addSubnode(animationNode)
}
let dimensions = self.file.dimensions ?? PixelDimensions(width: 512, height: 512)
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: self.context.account.postbox, userLocation: .other, file: self.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 256.0, height: 256.0))))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: self.context.account, userLocation: .other, fileReference: stickerPackFileReference(self.file), resource: self.file.resource).start())
} else {
if let animationNode = self.animationNode {
animationNode.visibility = false
self.animationNode = nil
animationNode.removeFromSupernode()
self.imageNode.isHidden = false
self.didSetUpAnimationNode = false
}
self.imageNode.setSignal(chatMessageSticker(account: self.context.account, userLocation: .other, file: self.file, small: false, synchronousLoad: false))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: self.context.account, userLocation: .other, fileReference: stickerPackFileReference(self.file), resource: chatMessageStickerResource(file: self.file, small: false)).start())
}
self.dimensions = dimensions.cgSize
self.setNeedsLayout()
}
}
var isVisible: Bool = true
func setIsVisible(_ visible: Bool) {
self.isVisible = visible
self.updateVisibility()
}
var isPlaying = false
func updateVisibility() {
let isPlaying = self.isVisible
if self.isPlaying != isPlaying {
self.isPlaying = isPlaying
if isPlaying && !self.didSetUpAnimationNode {
self.didSetUpAnimationNode = true
let dimensions = self.file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 384.0, height: 384.0))
let source = AnimatedStickerResourceSource(account: self.context.account, resource: self.file.resource, isVideo: self.file.isVideoSticker)
self.animationNode?.setup(source: source, width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
self.cachedDisposable.set((source.cachedDataPath(width: 384, height: 384)
|> deliverOn(Queue.concurrentDefaultQueue())).start())
}
self.animationNode?.visibility = isPlaying
}
}
func seek(to timestamp: Double) {
self.isVisible = false
self.isPlaying = false
self.animationNode?.seekTo(.timestamp(timestamp))
}
func play() {
self.isVisible = true
self.updateVisibility()
}
func pause() {
self.isVisible = false
self.isPlaying = false
self.animationNode?.pause()
}
func resetToStart() {
self.isVisible = false
self.isPlaying = false
self.animationNode?.seekTo(.timestamp(0.0))
}
func play(fromFrame frameIndex: Int) {
self.isVisible = true
self.updateVisibility()
self.animationNode?.play(firstFrame: false, fromIndex: frameIndex)
}
func copyStickerView(_ view: TGPhotoPaintStickerRenderView!) {
guard let view = view as? LegacyPaintStickerView, let animationNode = view.animationNode else {
return
}
self.animationNode?.cloneCurrentFrame(from: animationNode)
self.animationNode?.play(firstFrame: false, fromIndex: animationNode.currentFrameIndex)
self.updateVisibility()
}
override func layoutSubviews() {
super.layoutSubviews()
let size = self.bounds.size
if size.width > 0 && self.currentSize != size {
self.currentSize = size
let sideSize: CGFloat = size.width
let boundingSize = CGSize(width: sideSize, height: sideSize)
if let dimensions = self.dimensions {
let imageSize = dimensions.aspectFitted(boundingSize)
self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))()
self.imageNode.frame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: (size.height - imageSize.height) / 2.0), size: imageSize)
if let animationNode = self.animationNode {
animationNode.frame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: (size.height - imageSize.height) / 2.0), size: imageSize)
animationNode.updateLayout(size: imageSize)
}
}
}
}
}

View File

@ -482,14 +482,14 @@ public final class LegacyPaintEntityRenderer: NSObject, TGPhotoPaintEntityRender
}
}
public func entities(for time: CMTime, fps: Int, size: CGSize, completion: (([CIImage]?) -> Void)!) {
public func entities(for time: CMTime, fps: Int, size: CGSize, completion: @escaping ([CIImage]) -> Void) {
let entities = self.entities
let maxSide = max(size.width, size.height)
let paintingScale = maxSide / 1920.0
self.queue.async {
if entities.isEmpty {
completion(nil)
completion([])
} else {
let count = Atomic<Int>(value: 1)
let images = Atomic<[(CIImage, Int)]>(value: [])
@ -543,8 +543,7 @@ public final class LegacyPaintEntityRenderer: NSObject, TGPhotoPaintEntityRender
}
public final class LegacyPaintStickersContext: NSObject, TGPhotoPaintStickersContext {
public var captionPanelView: (() -> TGCaptionPanelView?)!
public var presentStickersController: ((((Any?, Bool, UIView?, CGRect) -> Void)?) -> TGPhotoPaintStickersScreen?)!
public var captionPanelView: (() -> TGCaptionPanelView?)?
private let context: AccountContext
@ -552,63 +551,15 @@ public final class LegacyPaintStickersContext: NSObject, TGPhotoPaintStickersCon
self.context = context
}
public func documentId(forDocument document: Any!) -> Int64 {
if let data = document as? Data{
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: data))
if let file = decoder.decodeRootObject() as? TelegramMediaFile {
return file.fileId.id
} else {
return 0
}
} else {
return 0
}
}
public func maskDescription(forDocument document: Any!) -> TGStickerMaskDescription? {
if let data = document as? Data{
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: data))
if let file = decoder.decodeRootObject() as? TelegramMediaFile {
for attribute in file.attributes {
if case let .Sticker(_, _, maskData) = attribute {
if let maskData = maskData {
return TGStickerMaskDescription(n: maskData.n, point: CGPoint(x: maskData.x, y: maskData.y), zoom: CGFloat(maskData.zoom))
} else {
return nil
}
}
}
return nil
} else {
return nil
}
} else {
return nil
}
}
public func stickerView(forDocument document: Any!) -> (UIView & TGPhotoPaintStickerRenderView)! {
if let data = document as? Data{
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: data))
if let file = decoder.decodeRootObject() as? TelegramMediaFile {
return LegacyPaintStickerView(context: self.context, file: file)
} else {
return nil
}
} else {
return nil
}
}
class LegacyDrawingAdapter: NSObject, TGPhotoDrawingAdapter {
let drawingView: TGPhotoDrawingView!
let drawingEntitiesView: TGPhotoDrawingEntitiesView!
let drawingView: TGPhotoDrawingView
let drawingEntitiesView: TGPhotoDrawingEntitiesView
let selectionContainerView: UIView
let contentWrapperView: UIView!
let interfaceController: TGPhotoDrawingInterfaceController!
let contentWrapperView: UIView
let interfaceController: TGPhotoDrawingInterfaceController
init(context: AccountContext, size: CGSize, originalSize: CGSize, isVideo: Bool, isAvatar: Bool) {
let interfaceController = DrawingScreen(context: context, size: size, originalSize: originalSize, isVideo: isVideo, isAvatar: isAvatar)
init(context: AccountContext, size: CGSize, originalSize: CGSize, isVideo: Bool, isAvatar: Bool, entitiesView: (UIView & TGPhotoDrawingEntitiesView)?) {
let interfaceController = DrawingScreen(context: context, size: size, originalSize: originalSize, isVideo: isVideo, isAvatar: isAvatar, entitiesView: entitiesView)
self.interfaceController = interfaceController
self.drawingView = interfaceController.drawingView
self.drawingEntitiesView = interfaceController.entitiesView
@ -619,18 +570,18 @@ public final class LegacyPaintStickersContext: NSObject, TGPhotoPaintStickersCon
}
}
public func drawingAdapter(_ size: CGSize, originalSize: CGSize, isVideo: Bool, isAvatar: Bool) -> TGPhotoDrawingAdapter! {
return LegacyDrawingAdapter(context: self.context, size: size, originalSize: originalSize, isVideo: isVideo, isAvatar: isAvatar)
public func drawingAdapter(_ size: CGSize, originalSize: CGSize, isVideo: Bool, isAvatar: Bool, entitiesView: (UIView & TGPhotoDrawingEntitiesView)?) -> TGPhotoDrawingAdapter {
return LegacyDrawingAdapter(context: self.context, size: size, originalSize: originalSize, isVideo: isVideo, isAvatar: isAvatar, entitiesView: entitiesView)
}
public func solidRoundedButton(_ title: String!, action: (() -> Void)!) -> (UIView & TGPhotoSolidRoundedButtonView)! {
public func solidRoundedButton(_ title: String, action: @escaping () -> Void) -> UIView & TGPhotoSolidRoundedButtonView {
let theme = SolidRoundedButtonTheme(theme: self.context.sharedContext.currentPresentationData.with { $0 }.theme)
let button = SolidRoundedButtonView(title: title, theme: theme, height: 50.0, cornerRadius: 10.0)
button.pressed = action
return button
}
public func drawingEntitiesView(with size: CGSize) -> (UIView & TGPhotoDrawingEntitiesView)! {
public func drawingEntitiesView(with size: CGSize) -> UIView & TGPhotoDrawingEntitiesView {
let view = DrawingEntitiesView(context: self.context, size: size)
return view
}

View File

@ -100,7 +100,7 @@ enum LegacyMediaPickerGallerySource {
case selection(item: TGMediaSelectableItem)
}
func presentLegacyMediaPickerGallery(context: AccountContext, peer: EnginePeer?, threadTitle: String?, chatLocation: ChatLocation?, presentationData: PresentationData, source: LegacyMediaPickerGallerySource, immediateThumbnail: UIImage?, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext, hasSilentPosting: Bool, hasSchedule: Bool, hasTimer: Bool, updateHiddenMedia: @escaping (String?) -> Void, initialLayout: ContainerViewLayout?, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (String) -> UIView?, completed: @escaping (TGMediaSelectableItem & TGMediaEditableItem, Bool, Int32?, @escaping () -> Void) -> Void, presentStickers: ((@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?)?, presentSchedulePicker: @escaping (Bool, @escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, present: @escaping (ViewController, Any?) -> Void, finishedTransitionIn: @escaping () -> Void, willTransitionOut: @escaping () -> Void, dismissAll: @escaping () -> Void) -> TGModernGalleryController {
func presentLegacyMediaPickerGallery(context: AccountContext, peer: EnginePeer?, threadTitle: String?, chatLocation: ChatLocation?, presentationData: PresentationData, source: LegacyMediaPickerGallerySource, immediateThumbnail: UIImage?, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext, hasSilentPosting: Bool, hasSchedule: Bool, hasTimer: Bool, updateHiddenMedia: @escaping (String?) -> Void, initialLayout: ContainerViewLayout?, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (String) -> UIView?, completed: @escaping (TGMediaSelectableItem & TGMediaEditableItem, Bool, Int32?, @escaping () -> Void) -> Void, presentSchedulePicker: @escaping (Bool, @escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, present: @escaping (ViewController, Any?) -> Void, finishedTransitionIn: @escaping () -> Void, willTransitionOut: @escaping () -> Void, dismissAll: @escaping () -> Void) -> TGModernGalleryController {
let reminder = peer?.id == context.account.peerId
let hasSilentPosting = hasSilentPosting && peer?.id != context.account.peerId
@ -111,17 +111,6 @@ func presentLegacyMediaPickerGallery(context: AccountContext, peer: EnginePeer?,
paintStickersContext.captionPanelView = {
return getCaptionPanelView()
}
paintStickersContext.presentStickersController = { completion in
if let presentStickers = presentStickers {
return presentStickers({ file, animated, view, rect in
let coder = PostboxEncoder()
coder.encodeRootObject(file)
completion?(coder.makeData(), animated, view, rect)
})
} else {
return nil
}
}
let controller = TGModernGalleryController(context: legacyController.context)!
controller.asyncTransitionIn = true

View File

@ -151,7 +151,6 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
public weak var webSearchController: WebSearchController?
public var openCamera: ((TGAttachmentCameraView?) -> Void)?
public var presentStickers: ((@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?)?
public var presentSchedulePicker: (Bool, @escaping (Int32) -> Void) -> Void = { _, _ in }
public var presentTimerPicker: (@escaping (Int32) -> Void) -> Void = { _ in }
public var presentWebSearch: (MediaGroupsScreen) -> Void = { _ in }
@ -681,7 +680,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
if let strongSelf = self {
strongSelf.controller?.interaction?.sendSelected(result, silently, scheduleTime, false, completion)
}
}, presentStickers: controller.presentStickers, presentSchedulePicker: controller.presentSchedulePicker, presentTimerPicker: controller.presentTimerPicker, getCaptionPanelView: controller.getCaptionPanelView, present: { [weak self] c, a in
}, presentSchedulePicker: controller.presentSchedulePicker, presentTimerPicker: controller.presentTimerPicker, getCaptionPanelView: controller.getCaptionPanelView, present: { [weak self] c, a in
self?.controller?.present(c, in: .window(.root), with: a)
}, finishedTransitionIn: { [weak self] in
self?.openingMedia = false
@ -717,7 +716,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
if let strongSelf = self {
strongSelf.controller?.interaction?.sendSelected(result, silently, scheduleTime, false, completion)
}
}, presentStickers: controller.presentStickers, presentSchedulePicker: controller.presentSchedulePicker, presentTimerPicker: controller.presentTimerPicker, getCaptionPanelView: controller.getCaptionPanelView, present: { [weak self] c, a in
}, presentSchedulePicker: controller.presentSchedulePicker, presentTimerPicker: controller.presentTimerPicker, getCaptionPanelView: controller.getCaptionPanelView, present: { [weak self] c, a in
self?.controller?.present(c, in: .window(.root), with: a, blockInteraction: true)
}, finishedTransitionIn: { [weak self] in
self?.openingMedia = false
@ -1498,7 +1497,6 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
if let strongSelf = self {
let mediaPicker = MediaPickerScreen(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: strongSelf.peer, threadTitle: strongSelf.threadTitle, chatLocation: strongSelf.chatLocation, bannedSendMedia: strongSelf.bannedSendMedia, subject: .assets(collection), editingContext: strongSelf.interaction?.editingState, selectionContext: strongSelf.interaction?.selectionState)
mediaPicker.presentStickers = strongSelf.presentStickers
mediaPicker.presentSchedulePicker = strongSelf.presentSchedulePicker
mediaPicker.presentTimerPicker = strongSelf.presentTimerPicker
mediaPicker.getCaptionPanelView = strongSelf.getCaptionPanelView

View File

@ -6154,16 +6154,6 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
}
let paintStickersContext = LegacyPaintStickersContext(context: strongSelf.context)
// paintStickersContext.presentStickersController = { completion in
// let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { fileReference, node, rect in
// let coder = PostboxEncoder()
// coder.encodeRootObject(fileReference.media)
// completion?(coder.makeData(), fileReference.media.isAnimatedSticker, node.view, rect)
// return true
// })
// strongSelf.controller?.present(controller, in: .window(.root))
// return controller
// }
let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: hasPhotos && !fromGallery, hasViewButton: false, personalPhoto: peerId.namespace == Namespaces.Peer.CloudUser, isVideo: false, saveEditedPhotos: false, saveCapturedMedia: false, signup: false, forum: false, title: nil, isSuggesting: false)!
mixin.forceDark = true
@ -6308,9 +6298,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
}
let uploadInterface = LegacyLiveUploadInterface(context: context)
let signal: SSignal
if let asset = asset as? AVAsset {
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
} else if let url = asset as? URL, let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
let durationSignal: SSignal = SSignal(generator: { subscriber in
let disposable = (entityRenderer.duration()).start(next: { duration in
subscriber.putNext(duration)
@ -6329,6 +6317,8 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
}
})
} else if let asset = asset as? AVAsset {
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
} else {
signal = SSignal.complete()
}

View File

@ -1012,19 +1012,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
transitionCompletion()
}, presentStickers: { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
}, sendMessagesWithSignals: { [weak self] signals, _, _ in
@ -3807,20 +3794,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, initialCaption: NSAttributedString(string: message.text), snapshots: [], transitionCompletion: nil, presentStickers: { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}, getCaptionPanelView: { [weak self] in
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, initialCaption: NSAttributedString(string: message.text), snapshots: [], transitionCompletion: nil, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
}, sendMessagesWithSignals: { [weak self] signals, _, _ in
if let strongSelf = self {
@ -11923,19 +11897,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
done(time)
})
}
}, presentStickers: { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
}, dismissedWithResult: { [weak self] in
@ -12567,19 +12528,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
done(time)
})
}
}, presentStickers: { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
})
@ -12667,19 +12615,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
})
}
}, presentStickers: { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
}, present: { [weak self] c, a in
@ -12881,20 +12816,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
})
}
controller.presentStickers = { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}
controller.presentSchedulePicker = { [weak self] media, done in
if let strongSelf = self {
strongSelf.presentScheduleTimePicker(style: media ? .media : .default, completion: { [weak self] time in
@ -12980,20 +12901,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
})
}))
controller.presentStickers = { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}
controller.getCaptionPanelView = { [weak self] in
return self?.getCaptionPanelView()
}
@ -13029,19 +12936,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
done(time)
})
}
}, presentStickers: { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
})
@ -13088,20 +12982,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
})
}))
controller.presentStickers = { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}
controller.getCaptionPanelView = { [weak self] in
return self?.getCaptionPanelView()
}

View File

@ -366,9 +366,7 @@ public func createChannelController(context: AccountContext) -> ViewController {
}
let uploadInterface = LegacyLiveUploadInterface(context: context)
let signal: SSignal
if let asset = asset as? AVAsset {
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
} else if let url = asset as? URL, let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
let durationSignal: SSignal = SSignal(generator: { subscriber in
let disposable = (entityRenderer.duration()).start(next: { duration in
subscriber.putNext(duration)
@ -387,6 +385,8 @@ public func createChannelController(context: AccountContext) -> ViewController {
}
})
} else if let asset = asset as? AVAsset {
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
} else {
signal = SSignal.complete()
}

View File

@ -639,9 +639,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
}
let uploadInterface = LegacyLiveUploadInterface(context: context)
let signal: SSignal
if let asset = asset as? AVAsset {
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
} else if let url = asset as? URL, let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
let durationSignal: SSignal = SSignal(generator: { subscriber in
let disposable = (entityRenderer.duration()).start(next: { duration in
subscriber.putNext(duration)
@ -660,6 +658,8 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
}
})
} else if let asset = asset as? AVAsset {
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
} else {
signal = SSignal.complete()
}

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ import ShareController
import LegacyUI
import LegacyMediaPickerUI
func presentedLegacyCamera(context: AccountContext, peer: Peer, chatLocation: ChatLocation, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, attachmentController: ViewController? = nil, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: NSAttributedString, hasSchedule: Bool, photoOnly: Bool, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }, presentSchedulePicker: @escaping (Bool, @escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, dismissedWithResult: @escaping () -> Void = {}, finishedTransitionIn: @escaping () -> Void = {}) {
func presentedLegacyCamera(context: AccountContext, peer: Peer, chatLocation: ChatLocation, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, attachmentController: ViewController? = nil, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: NSAttributedString, hasSchedule: Bool, photoOnly: Bool, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }, presentSchedulePicker: @escaping (Bool, @escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, dismissedWithResult: @escaping () -> Void = {}, finishedTransitionIn: @escaping () -> Void = {}) {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme)
legacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait)
@ -70,13 +70,6 @@ func presentedLegacyCamera(context: AccountContext, peer: Peer, chatLocation: Ch
paintStickersContext.captionPanelView = {
return getCaptionPanelView()
}
paintStickersContext.presentStickersController = { completion in
return presentStickers({ file, animated, view, rect in
let coder = PostboxEncoder()
coder.encodeRootObject(file)
completion?(coder.makeData(), animated, view, rect)
})
}
controller.stickersContext = paintStickersContext
controller.isImportant = true

View File

@ -3912,19 +3912,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: message.associatedThreadInfo?.title, media: mediaReference, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
transitionCompletion()
}, presentStickers: { [weak self] completion in
if let strongSelf = self {
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
completion(fileReference.media, fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
strongSelf.controller?.present(controller, in: .window(.root))
return controller
} else {
return nil
}
}, getCaptionPanelView: {
return nil
}, sendMessagesWithSignals: { [weak self] signals, _, _ in
@ -6948,9 +6935,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
let uploadInterface = LegacyLiveUploadInterface(context: context)
let signal: SSignal
if let asset = asset as? AVAsset {
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
} else if let url = asset as? URL, let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
let durationSignal: SSignal = SSignal(generator: { subscriber in
let disposable = (entityRenderer.duration()).start(next: { duration in
subscriber.putNext(duration)
@ -6969,6 +6954,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
})
} else if let asset = asset as? AVAsset {
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
} else {
signal = SSignal.complete()
}
@ -7153,19 +7140,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
let paintStickersContext = LegacyPaintStickersContext(context: strongSelf.context)
paintStickersContext.presentStickersController = { completion in
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { result in
if let (fileReference, view, rect) = result {
let coder = PostboxEncoder()
coder.encodeRootObject(fileReference.media)
completion?(coder.makeData(), fileReference.media.isAnimatedSticker || fileReference.media.isVideoSticker, view, rect)
}
return true
})
(strongSelf.controller?.navigationController?.topViewController as? ViewController)?.present(controller, in: .window(.root))
return controller
}
var isForum = false
if let peer = strongSelf.data?.peer as? TelegramChannel, peer.flags.contains(.isForum) {
isForum = true

View File

@ -312,7 +312,7 @@ private func galleryItems(account: Account, results: [ChatContextResult], curren
return (galleryItems, focusItem)
}
func presentLegacyWebSearchGallery(context: AccountContext, peer: EnginePeer?, threadTitle: String?, chatLocation: ChatLocation?, presentationData: PresentationData, results: [ChatContextResult], current: ChatContextResult, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext, updateHiddenMedia: @escaping (String?) -> Void, initialLayout: ContainerViewLayout?, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (ChatContextResult) -> UIView?, completed: @escaping (ChatContextResult) -> Void, presentStickers: ((@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?)?, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, present: (ViewController, Any?) -> Void) {
func presentLegacyWebSearchGallery(context: AccountContext, peer: EnginePeer?, threadTitle: String?, chatLocation: ChatLocation?, presentationData: PresentationData, results: [ChatContextResult], current: ChatContextResult, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext, updateHiddenMedia: @escaping (String?) -> Void, initialLayout: ContainerViewLayout?, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (ChatContextResult) -> UIView?, completed: @escaping (ChatContextResult) -> Void, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, present: (ViewController, Any?) -> Void) {
let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme, initialLayout: nil)
legacyController.statusBar.statusBarStyle = presentationData.theme.rootController.statusBarStyle.style
@ -331,17 +331,6 @@ func presentLegacyWebSearchGallery(context: AccountContext, peer: EnginePeer?, t
paintStickersContext.captionPanelView = {
return getCaptionPanelView()
}
paintStickersContext.presentStickersController = { completion in
if let presentStickers = presentStickers {
return presentStickers({ file, animated, view, rect in
let coder = PostboxEncoder()
coder.encodeRootObject(file)
completion?(coder.makeData(), animated, view, rect)
})
} else {
return nil
}
}
let controller = TGModernGalleryController(context: legacyController.context)!
controller.asyncTransitionIn = true

View File

@ -107,12 +107,6 @@ public final class WebSearchController: ViewController {
private var navigationContentNode: WebSearchNavigationContentNode?
public var presentStickers: ((@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?)? {
didSet {
self.controllerNode.presentStickers = self.presentStickers
}
}
public var getCaptionPanelView: () -> TGCaptionPanelView? = { return nil } {
didSet {
self.controllerNode.getCaptionPanelView = self.getCaptionPanelView

View File

@ -184,7 +184,6 @@ class WebSearchControllerNode: ASDisplayNode {
var cancel: (() -> Void)?
var dismissInput: (() -> Void)?
var presentStickers: ((@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?)?
var getCaptionPanelView: () -> TGCaptionPanelView? = { return nil }
init(controller: WebSearchController, context: AccountContext, presentationData: PresentationData, controllerInteraction: WebSearchControllerInteraction, peer: EnginePeer?, chatLocation: ChatLocation?, mode: WebSearchMode, attachment: Bool) {
@ -744,7 +743,7 @@ class WebSearchControllerNode: ASDisplayNode {
strongSelf.controllerInteraction.sendSelected(result, false, nil)
strongSelf.cancel?()
}
}, presentStickers: self.presentStickers, getCaptionPanelView: self.getCaptionPanelView, present: present)
}, getCaptionPanelView: self.getCaptionPanelView, present: present)
}
} else {
if let results = self.currentProcessedResults?.results {