mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-21 03:29:54 +00:00
Merge commit 'e691bf1984472a6bbf1ab1417dce19f154590f6a'
This commit is contained in:
@@ -101,6 +101,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
let panelWidth: CGFloat
|
||||
let animateFlipAction: ActionSlot<Void>
|
||||
let animateShutter: () -> Void
|
||||
let dismissAllTooltips: () -> Void
|
||||
let present: (ViewController) -> Void
|
||||
let push: (ViewController) -> Void
|
||||
let completion: ActionSlot<Signal<CameraScreen.Result, NoError>>
|
||||
@@ -115,6 +116,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
panelWidth: CGFloat,
|
||||
animateFlipAction: ActionSlot<Void>,
|
||||
animateShutter: @escaping () -> Void,
|
||||
dismissAllTooltips: @escaping () -> Void,
|
||||
present: @escaping (ViewController) -> Void,
|
||||
push: @escaping (ViewController) -> Void,
|
||||
completion: ActionSlot<Signal<CameraScreen.Result, NoError>>
|
||||
@@ -128,6 +130,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
self.panelWidth = panelWidth
|
||||
self.animateFlipAction = animateFlipAction
|
||||
self.animateShutter = animateShutter
|
||||
self.dismissAllTooltips = dismissAllTooltips
|
||||
self.present = present
|
||||
self.push = push
|
||||
self.completion = completion
|
||||
@@ -182,6 +185,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
private let updateState: ActionSlot<CameraState>
|
||||
|
||||
private let animateShutter: () -> Void
|
||||
private let dismissAllTooltips: () -> Void
|
||||
|
||||
private var cameraStateDisposable: Disposable?
|
||||
private var resultDisposable = MetaDisposable()
|
||||
@@ -209,7 +213,8 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
present: @escaping (ViewController) -> Void,
|
||||
completion: ActionSlot<Signal<CameraScreen.Result, NoError>>,
|
||||
updateState: ActionSlot<CameraState>,
|
||||
animateShutter: @escaping () -> Void = {}
|
||||
animateShutter: @escaping () -> Void = {},
|
||||
dismissAllTooltips: @escaping () -> Void = {}
|
||||
) {
|
||||
self.context = context
|
||||
self.camera = camera
|
||||
@@ -217,6 +222,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
self.completion = completion
|
||||
self.updateState = updateState
|
||||
self.animateShutter = animateShutter
|
||||
self.dismissAllTooltips = dismissAllTooltips
|
||||
|
||||
super.init()
|
||||
|
||||
@@ -377,6 +383,9 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
self.cameraState = self.cameraState.updatedIsDualCamEnabled(isEnabled)
|
||||
self.updated(transition: .easeInOut(duration: 0.1))
|
||||
|
||||
self.dismissAllTooltips()
|
||||
let _ = ApplicationSpecificNotice.incrementStoriesDualCameraTip(accountManager: self.context.sharedContext.accountManager).start()
|
||||
|
||||
self.hapticFeedback.impact(.light)
|
||||
}
|
||||
|
||||
@@ -394,6 +403,9 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
return
|
||||
}
|
||||
self.isTakingPhoto = true
|
||||
|
||||
self.dismissAllTooltips()
|
||||
|
||||
let takePhoto = self.camera.takePhoto()
|
||||
|> mapToSignal { value -> Signal<CameraScreen.Result, NoError> in
|
||||
switch value {
|
||||
@@ -415,6 +427,9 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
guard case .none = self.cameraState.recording else {
|
||||
return
|
||||
}
|
||||
|
||||
self.dismissAllTooltips()
|
||||
|
||||
self.cameraState = self.cameraState.updatedDuration(0.0).updatedRecording(pressing ? .holding : .handsFree)
|
||||
self.resultDisposable.set((self.camera.startRecording()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] duration in
|
||||
@@ -457,7 +472,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
}
|
||||
|
||||
func makeState() -> State {
|
||||
return State(context: self.context, camera: self.camera, present: self.present, completion: self.completion, updateState: self.updateState, animateShutter: self.animateShutter)
|
||||
return State(context: self.context, camera: self.camera, present: self.present, completion: self.completion, updateState: self.updateState, animateShutter: self.animateShutter, dismissAllTooltips: self.dismissAllTooltips)
|
||||
}
|
||||
|
||||
static var body: Body {
|
||||
@@ -1692,6 +1707,23 @@ public class CameraScreen: ViewController {
|
||||
})
|
||||
}
|
||||
|
||||
fileprivate func dismissAllTooltips() {
|
||||
guard let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
controller.window?.forEachController({ controller in
|
||||
if let controller = controller as? TooltipScreen {
|
||||
controller.dismiss()
|
||||
}
|
||||
})
|
||||
controller.forEachController({ controller in
|
||||
if let controller = controller as? TooltipScreen {
|
||||
controller.dismiss()
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
let result = super.hitTest(point, with: event)
|
||||
if result == self.componentHost.view {
|
||||
@@ -1797,6 +1829,9 @@ public class CameraScreen: ViewController {
|
||||
animateShutter: { [weak self] in
|
||||
self?.mainPreviewContainerView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||
},
|
||||
dismissAllTooltips: { [weak self] in
|
||||
self?.dismissAllTooltips()
|
||||
},
|
||||
present: { [weak self] c in
|
||||
self?.controller?.present(c, in: .window(.root))
|
||||
},
|
||||
@@ -2045,7 +2080,7 @@ public class CameraScreen: ViewController {
|
||||
self.hapticFeedback.impact(.light)
|
||||
}
|
||||
|
||||
self.dismissAllTooltips()
|
||||
self.node.dismissAllTooltips()
|
||||
|
||||
self.node.hasGallery = true
|
||||
|
||||
@@ -2127,7 +2162,7 @@ public class CameraScreen: ViewController {
|
||||
return
|
||||
}
|
||||
|
||||
self.dismissAllTooltips()
|
||||
self.node.dismissAllTooltips()
|
||||
|
||||
if !interactive {
|
||||
self.hapticFeedback.impact(.light)
|
||||
@@ -2156,28 +2191,14 @@ public class CameraScreen: ViewController {
|
||||
self.dismiss(animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
private func dismissAllTooltips() {
|
||||
self.window?.forEachController({ controller in
|
||||
if let controller = controller as? TooltipScreen {
|
||||
controller.dismiss()
|
||||
}
|
||||
})
|
||||
self.forEachController({ controller in
|
||||
if let controller = controller as? TooltipScreen {
|
||||
controller.dismiss()
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
public func updateTransitionProgress(_ transitionFraction: CGFloat, transition: ContainedViewLayoutTransition, completion: @escaping () -> Void = {}) {
|
||||
if let layout = self.validLayout, case .regular = layout.metrics.widthClass {
|
||||
return
|
||||
}
|
||||
|
||||
if self.node.hasAppeared {
|
||||
self.dismissAllTooltips()
|
||||
self.node.dismissAllTooltips()
|
||||
}
|
||||
|
||||
let transitionFraction = max(0.0, min(1.0, transitionFraction))
|
||||
|
||||
@@ -50,7 +50,7 @@ private final class AvatarComponent: Component {
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
let size = CGSize(width: 36.0, height: 36.0)
|
||||
let size = CGSize(width: 32.0, height: 32.0)
|
||||
|
||||
self.avatarNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.avatarNode.setPeer(
|
||||
@@ -177,14 +177,14 @@ final class StoryPreviewComponent: Component {
|
||||
let cancelButtonSize = self.cancelButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(BundleIconComponent(
|
||||
name: "Media Gallery/Close",
|
||||
name: "Stories/Close",
|
||||
tintColor: UIColor.white
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 44.0, height: 44.0)
|
||||
)
|
||||
let cancelButtonFrame = CGRect(
|
||||
origin: CGPoint(x: 17.0, y: 24.0),
|
||||
origin: CGPoint(x: availableSize.width - 40.0, y: 19.0),
|
||||
size: cancelButtonSize
|
||||
)
|
||||
if let cancelButtonView = self.cancelButton.view {
|
||||
@@ -203,10 +203,10 @@ final class StoryPreviewComponent: Component {
|
||||
peer: accountPeer
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 44.0, height: 44.0)
|
||||
containerSize: CGSize(width: 32.0, height: 32.0)
|
||||
)
|
||||
let avatarFrame = CGRect(
|
||||
origin: CGPoint(x: availableSize.width - avatarSize.width - 6.0, y: 14.0),
|
||||
origin: CGPoint(x: 12.0, y: 18.0),
|
||||
size: avatarSize
|
||||
)
|
||||
if let avatarView = self.avatar.view {
|
||||
@@ -222,14 +222,14 @@ final class StoryPreviewComponent: Component {
|
||||
transition: transition,
|
||||
component: AnyComponent(Text(
|
||||
text: "My story",
|
||||
font: Font.semibold(17.0),
|
||||
font: Font.medium(14.0),
|
||||
color: .white
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 180.0, height: 44.0)
|
||||
)
|
||||
let titleFrame = CGRect(
|
||||
origin: CGPoint(x: floorToScreenPixels((availableSize.width - titleSize.width) / 2.0), y: 21.0),
|
||||
origin: CGPoint(x: 53.0, y: floorToScreenPixels(33.0 - titleSize.height / 2.0)),
|
||||
size: titleSize
|
||||
)
|
||||
if let titleView = self.title.view {
|
||||
|
||||
@@ -449,7 +449,7 @@ final class StoryContentCaptionComponent: Component {
|
||||
self.dustNode = dustNode
|
||||
self.scrollView.insertSubview(dustNode.view, aboveSubview: spoilerTextNode.textNode.view)
|
||||
}
|
||||
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
|
||||
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 0.0)
|
||||
dustNode.update(size: dustNode.frame.size, color: .white, textColor: .white, rects: textLayout.0.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.0.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
} else if let spoilerTextNode = self.spoilerTextNode {
|
||||
self.spoilerTextNode = nil
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import ComponentFlow
|
||||
import AccountContext
|
||||
import TelegramCore
|
||||
import TelegramStringFormatting
|
||||
|
||||
final class StoryPositionInfoComponent: Component {
|
||||
let context: AccountContext
|
||||
let position: Int
|
||||
let totalCount: Int
|
||||
|
||||
init(context: AccountContext, position: Int, totalCount: Int) {
|
||||
self.context = context
|
||||
self.position = position
|
||||
self.totalCount = totalCount
|
||||
}
|
||||
|
||||
static func ==(lhs: StoryPositionInfoComponent, rhs: StoryPositionInfoComponent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.position != rhs.position {
|
||||
return false
|
||||
}
|
||||
if lhs.totalCount != rhs.totalCount {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
final class View: UIView {
|
||||
private let title = ComponentView<Empty>()
|
||||
|
||||
private var component: StoryPositionInfoComponent?
|
||||
private weak var state: EmptyComponentState?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func update(component: StoryPositionInfoComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
let size = availableSize
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 })
|
||||
|
||||
let position = max(0, min(component.position + 1, component.totalCount))
|
||||
let title = presentationData.strings.Items_NOfM("\(position)", "\(component.totalCount)").string
|
||||
let titleSize = self.title.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(Text(text: title, font: Font.with(size: 17.0, weight: .semibold, traits: .monospacedNumbers), color: .white)),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
|
||||
let contentHeight: CGFloat = titleSize.height
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) * 0.5), y: floor((availableSize.height - contentHeight) * 0.5)), size: titleSize)
|
||||
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
titleView.isUserInteractionEnabled = false
|
||||
self.addSubview(titleView)
|
||||
}
|
||||
transition.setFrame(view: titleView, frame: titleFrame)
|
||||
}
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user