mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 01:10:09 +00:00
Web app improvements
This commit is contained in:
parent
2a48721e28
commit
613bba57c2
@ -111,7 +111,7 @@ public enum AttachmentButtonType: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol AttachmentContainable: ViewController {
|
public protocol AttachmentContainable: ViewController, MinimizableController {
|
||||||
var requestAttachmentMenuExpansion: () -> Void { get set }
|
var requestAttachmentMenuExpansion: () -> Void { get set }
|
||||||
var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void { get set }
|
var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void { get set }
|
||||||
var parentController: () -> ViewController? { get set }
|
var parentController: () -> ViewController? { get set }
|
||||||
@ -160,6 +160,14 @@ public extension AttachmentContainable {
|
|||||||
completion()
|
completion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var minimizedBounds: CGRect? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var minimizedTopEdgeOffset: CGFloat? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var isPanGestureEnabled: (() -> Bool)? {
|
var isPanGestureEnabled: (() -> Bool)? {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -231,7 +239,7 @@ private func generateMaskImage() -> UIImage? {
|
|||||||
})?.stretchableImage(withLeftCapWidth: 195, topCapHeight: 110)
|
})?.stretchableImage(withLeftCapWidth: 195, topCapHeight: 110)
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AttachmentController: ViewController {
|
public class AttachmentController: ViewController, MinimizableController {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?
|
private let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?
|
||||||
private let chatLocation: ChatLocation?
|
private let chatLocation: ChatLocation?
|
||||||
@ -260,6 +268,9 @@ public class AttachmentController: ViewController {
|
|||||||
override public var ready: Promise<Bool> {
|
override public var ready: Promise<Bool> {
|
||||||
return self._ready
|
return self._ready
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public private(set) var minimizedTopEdgeOffset: CGFloat?
|
||||||
|
public private(set) var minimizedBounds: CGRect?
|
||||||
|
|
||||||
private final class Node: ASDisplayNode {
|
private final class Node: ASDisplayNode {
|
||||||
private weak var controller: AttachmentController?
|
private weak var controller: AttachmentController?
|
||||||
@ -582,11 +593,7 @@ public class AttachmentController: ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
navigationController.minimizeViewController(controller, damping: damping, velocity: initialVelocity, beforeMaximize: { navigationController, completion in
|
navigationController.minimizeViewController(controller, damping: damping, velocity: initialVelocity, beforeMaximize: { navigationController, completion in
|
||||||
if let controller = controller.mainController as? AttachmentContainable {
|
controller.mainController.beforeMaximize(navigationController: navigationController, completion: completion)
|
||||||
controller.beforeMaximize(navigationController: navigationController, completion: completion)
|
|
||||||
} else {
|
|
||||||
completion()
|
|
||||||
}
|
|
||||||
}, setupContainer: { [weak self] current in
|
}, setupContainer: { [weak self] current in
|
||||||
let minimizedContainer: MinimizedContainerImpl?
|
let minimizedContainer: MinimizedContainerImpl?
|
||||||
if let current = current as? MinimizedContainerImpl {
|
if let current = current as? MinimizedContainerImpl {
|
||||||
@ -1178,7 +1185,7 @@ public class AttachmentController: ViewController {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
public override var isMinimized: Bool {
|
public var isMinimized: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
self.mainController.isMinimized = self.isMinimized
|
self.mainController.isMinimized = self.isMinimized
|
||||||
}
|
}
|
||||||
@ -1199,7 +1206,7 @@ public class AttachmentController: ViewController {
|
|||||||
self.node.containerLayoutUpdated(layout, transition: transition)
|
self.node.containerLayoutUpdated(layout, transition: transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var mainController: ViewController {
|
public var mainController: AttachmentContainable {
|
||||||
return self.node.currentControllers.first!
|
return self.node.currentControllers.first!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -81,6 +81,9 @@ protocol BrowserContent: UIView {
|
|||||||
|
|
||||||
var onScrollingUpdate: (ContentScrollingUpdate) -> Void { get set }
|
var onScrollingUpdate: (ContentScrollingUpdate) -> Void { get set }
|
||||||
|
|
||||||
|
func reload()
|
||||||
|
func stop()
|
||||||
|
|
||||||
func navigateBack()
|
func navigateBack()
|
||||||
func navigateForward()
|
func navigateForward()
|
||||||
|
|
||||||
|
|||||||
@ -171,18 +171,7 @@ final class BrowserNavigationBarComponent: CombinedComponent {
|
|||||||
if !leftItemList.isEmpty || !rightItemList.isEmpty {
|
if !leftItemList.isEmpty || !rightItemList.isEmpty {
|
||||||
availableWidth -= 32.0
|
availableWidth -= 32.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let centerItem = context.component.centerItem.flatMap { item in
|
|
||||||
centerItems[item.id].update(
|
|
||||||
component: item.component,
|
|
||||||
availableSize: CGSize(width: availableWidth, height: expandedHeight),
|
|
||||||
transition: context.transition
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if let centerItem = centerItem {
|
|
||||||
availableWidth -= centerItem.size.width
|
|
||||||
}
|
|
||||||
|
|
||||||
context.add(background
|
context.add(background
|
||||||
.position(CGPoint(x: size.width / 2.0, y: size.height / 2.0))
|
.position(CGPoint(x: size.width / 2.0, y: size.height / 2.0))
|
||||||
)
|
)
|
||||||
@ -205,8 +194,9 @@ final class BrowserNavigationBarComponent: CombinedComponent {
|
|||||||
context.add(item
|
context.add(item
|
||||||
.position(CGPoint(x: leftItemX + item.size.width / 2.0 - (item.size.width / 2.0 * 0.35 * context.component.collapseFraction), y: context.component.topInset + contentHeight / 2.0))
|
.position(CGPoint(x: leftItemX + item.size.width / 2.0 - (item.size.width / 2.0 * 0.35 * context.component.collapseFraction), y: context.component.topInset + contentHeight / 2.0))
|
||||||
.scale(1.0 - 0.35 * context.component.collapseFraction)
|
.scale(1.0 - 0.35 * context.component.collapseFraction)
|
||||||
.appear(.default(scale: false, alpha: true))
|
.opacity(1.0 - context.component.collapseFraction)
|
||||||
.disappear(.default(scale: false, alpha: true))
|
.appear(.default(scale: true, alpha: true))
|
||||||
|
.disappear(.default(scale: true, alpha: true))
|
||||||
)
|
)
|
||||||
leftItemX -= item.size.width + 8.0
|
leftItemX -= item.size.width + 8.0
|
||||||
centerLeftInset += item.size.width + 8.0
|
centerLeftInset += item.size.width + 8.0
|
||||||
@ -219,14 +209,27 @@ final class BrowserNavigationBarComponent: CombinedComponent {
|
|||||||
.position(CGPoint(x: rightItemX - item.size.width / 2.0 + (item.size.width / 2.0 * 0.35 * context.component.collapseFraction), y: context.component.topInset + contentHeight / 2.0))
|
.position(CGPoint(x: rightItemX - item.size.width / 2.0 + (item.size.width / 2.0 * 0.35 * context.component.collapseFraction), y: context.component.topInset + contentHeight / 2.0))
|
||||||
.scale(1.0 - 0.35 * context.component.collapseFraction)
|
.scale(1.0 - 0.35 * context.component.collapseFraction)
|
||||||
.opacity(1.0 - context.component.collapseFraction)
|
.opacity(1.0 - context.component.collapseFraction)
|
||||||
.appear(.default(scale: false, alpha: true))
|
.appear(.default(scale: true, alpha: true))
|
||||||
.disappear(.default(scale: false, alpha: true))
|
.disappear(.default(scale: true, alpha: true))
|
||||||
)
|
)
|
||||||
rightItemX -= item.size.width + 8.0
|
rightItemX -= item.size.width + 8.0
|
||||||
centerRightInset += item.size.width + 8.0
|
centerRightInset += item.size.width + 8.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let maxCenterInset = max(centerLeftInset, centerRightInset)
|
let maxCenterInset = max(centerLeftInset, centerRightInset)
|
||||||
|
|
||||||
|
if !leftItemList.isEmpty || !rightItemList.isEmpty {
|
||||||
|
availableWidth -= 20.0
|
||||||
|
}
|
||||||
|
|
||||||
|
let centerItem = context.component.centerItem.flatMap { item in
|
||||||
|
centerItems[item.id].update(
|
||||||
|
component: item.component,
|
||||||
|
availableSize: CGSize(width: availableWidth, height: expandedHeight),
|
||||||
|
transition: context.transition
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if let centerItem = centerItem {
|
if let centerItem = centerItem {
|
||||||
context.add(centerItem
|
context.add(centerItem
|
||||||
.position(CGPoint(x: maxCenterInset + (context.availableSize.width - maxCenterInset * 2.0) / 2.0, y: context.component.topInset + contentHeight / 2.0))
|
.position(CGPoint(x: maxCenterInset + (context.availableSize.width - maxCenterInset * 2.0) / 2.0, y: context.component.topInset + contentHeight / 2.0))
|
||||||
|
|||||||
@ -70,7 +70,7 @@ private final class BrowserScreenComponent: CombinedComponent {
|
|||||||
return { context in
|
return { context in
|
||||||
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
|
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
|
||||||
let performAction = context.component.performAction
|
let performAction = context.component.performAction
|
||||||
|
|
||||||
let navigationContent: AnyComponentWithIdentity<Empty>?
|
let navigationContent: AnyComponentWithIdentity<Empty>?
|
||||||
let navigationLeftItems: [AnyComponentWithIdentity<Empty>]
|
let navigationLeftItems: [AnyComponentWithIdentity<Empty>]
|
||||||
let navigationRightItems: [AnyComponentWithIdentity<Empty>]
|
let navigationRightItems: [AnyComponentWithIdentity<Empty>]
|
||||||
@ -88,10 +88,11 @@ private final class BrowserScreenComponent: CombinedComponent {
|
|||||||
navigationLeftItems = []
|
navigationLeftItems = []
|
||||||
navigationRightItems = []
|
navigationRightItems = []
|
||||||
} else {
|
} else {
|
||||||
|
let title = context.component.contentState?.title ?? ""
|
||||||
navigationContent = AnyComponentWithIdentity(
|
navigationContent = AnyComponentWithIdentity(
|
||||||
id: "title",
|
id: "title_\(title)",
|
||||||
component: AnyComponent(
|
component: AnyComponent(
|
||||||
MultilineTextComponent(text: .plain(NSAttributedString(string: context.component.contentState?.title ?? "", font: Font.bold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor, paragraphAlignment: .center)), horizontalAlignment: .center, maximumNumberOfLines: 1)
|
MultilineTextComponent(text: .plain(NSAttributedString(string: title, font: Font.bold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor, paragraphAlignment: .center)), horizontalAlignment: .center, maximumNumberOfLines: 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
navigationLeftItems = [
|
navigationLeftItems = [
|
||||||
@ -100,10 +101,7 @@ private final class BrowserScreenComponent: CombinedComponent {
|
|||||||
component: AnyComponent(
|
component: AnyComponent(
|
||||||
Button(
|
Button(
|
||||||
content: AnyComponent(
|
content: AnyComponent(
|
||||||
BundleIconComponent(
|
MultilineTextComponent(text: .plain(NSAttributedString(string: environment.strings.Common_Close, font: Font.regular(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor, paragraphAlignment: .center)), horizontalAlignment: .left, maximumNumberOfLines: 1)
|
||||||
name: "Instant View/Close",
|
|
||||||
tintColor: environment.theme.rootController.navigationBar.primaryTextColor
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
action: {
|
action: {
|
||||||
performAction.invoke(.close)
|
performAction.invoke(.close)
|
||||||
@ -112,9 +110,28 @@ private final class BrowserScreenComponent: CombinedComponent {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
let isLoading = (context.component.contentState?.estimatedProgress ?? 1.0) < 1.0
|
||||||
navigationRightItems = [
|
navigationRightItems = [
|
||||||
AnyComponentWithIdentity(
|
AnyComponentWithIdentity(
|
||||||
id: "close",
|
id: isLoading ? "stop" : "reload",
|
||||||
|
component: AnyComponent(
|
||||||
|
ReferenceButtonComponent(
|
||||||
|
content: AnyComponent(
|
||||||
|
BundleIconComponent(
|
||||||
|
name: isLoading ? "Instant View/CloseIcon" : "Chat/Context Menu/Reload",
|
||||||
|
tintColor: environment.theme.rootController.navigationBar.primaryTextColor
|
||||||
|
)
|
||||||
|
),
|
||||||
|
tag: settingsTag,
|
||||||
|
action: {
|
||||||
|
performAction.invoke(isLoading ? .stop : .reload)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: "settings",
|
||||||
component: AnyComponent(
|
component: AnyComponent(
|
||||||
ReferenceButtonComponent(
|
ReferenceButtonComponent(
|
||||||
content: AnyComponent(
|
content: AnyComponent(
|
||||||
@ -226,9 +243,11 @@ struct BrowserPresentationState: Equatable {
|
|||||||
var searchQueryIsEmpty: Bool
|
var searchQueryIsEmpty: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BrowserScreen: ViewController {
|
public class BrowserScreen: ViewController, MinimizableController {
|
||||||
enum Action {
|
enum Action {
|
||||||
case close
|
case close
|
||||||
|
case reload
|
||||||
|
case stop
|
||||||
case navigateBack
|
case navigateBack
|
||||||
case navigateForward
|
case navigateForward
|
||||||
case share
|
case share
|
||||||
@ -294,7 +313,7 @@ public class BrowserScreen: ViewController {
|
|||||||
}
|
}
|
||||||
strongSelf.controller?.title = state.title
|
strongSelf.controller?.title = state.title
|
||||||
strongSelf.contentState = state
|
strongSelf.contentState = state
|
||||||
strongSelf.requestLayout(transition: .immediate)
|
strongSelf.requestLayout(transition: .easeInOut(duration: 0.25))
|
||||||
}).strict()
|
}).strict()
|
||||||
|
|
||||||
self.content?.onScrollingUpdate = { [weak self] update in
|
self.content?.onScrollingUpdate = { [weak self] update in
|
||||||
@ -308,6 +327,10 @@ public class BrowserScreen: ViewController {
|
|||||||
switch action {
|
switch action {
|
||||||
case .close:
|
case .close:
|
||||||
self.controller?.dismiss()
|
self.controller?.dismiss()
|
||||||
|
case .reload:
|
||||||
|
content.reload()
|
||||||
|
case .stop:
|
||||||
|
content.stop()
|
||||||
case .navigateBack:
|
case .navigateBack:
|
||||||
content.navigateBack()
|
content.navigateBack()
|
||||||
case .navigateForward:
|
case .navigateForward:
|
||||||
@ -682,7 +705,7 @@ public class BrowserScreen: ViewController {
|
|||||||
if let content = self.content {
|
if let content = self.content {
|
||||||
let collapsedHeight: CGFloat = 24.0
|
let collapsedHeight: CGFloat = 24.0
|
||||||
let topInset: CGFloat = environment.statusBarHeight + navigationBarHeight * (1.0 - self.scrollingPanelOffsetFraction) + collapsedHeight * self.scrollingPanelOffsetFraction
|
let topInset: CGFloat = environment.statusBarHeight + navigationBarHeight * (1.0 - self.scrollingPanelOffsetFraction) + collapsedHeight * self.scrollingPanelOffsetFraction
|
||||||
let bottomInset = layout.intrinsicInsets.bottom
|
let bottomInset = 49.0 + layout.intrinsicInsets.bottom
|
||||||
content.updateLayout(size: layout.size, insets: UIEdgeInsets(top: topInset, left: layout.safeInsets.left, bottom: bottomInset, right: layout.safeInsets.right), transition: transition)
|
content.updateLayout(size: layout.size, insets: UIEdgeInsets(top: topInset, left: layout.safeInsets.left, bottom: bottomInset, right: layout.safeInsets.right), transition: transition)
|
||||||
transition.setFrame(view: content, frame: CGRect(origin: .zero, size: layout.size))
|
transition.setFrame(view: content, frame: CGRect(origin: .zero, size: layout.size))
|
||||||
}
|
}
|
||||||
@ -729,6 +752,8 @@ public class BrowserScreen: ViewController {
|
|||||||
|
|
||||||
(self.displayNode as! Node).containerLayoutUpdated(layout: layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.height, transition: ComponentTransition(transition))
|
(self.displayNode as! Node).containerLayoutUpdated(layout: layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.height, transition: ComponentTransition(transition))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var isMinimized = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class BrowserReferenceContentSource: ContextReferenceContentSource {
|
private final class BrowserReferenceContentSource: ContextReferenceContentSource {
|
||||||
|
|||||||
@ -367,4 +367,3 @@ final class SearchToolbarContentComponent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -246,6 +246,14 @@ final class BrowserWebContent: UIView, BrowserContent, UIScrollViewDelegate {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stop() {
|
||||||
|
self.webView.stopLoading()
|
||||||
|
}
|
||||||
|
|
||||||
|
func reload() {
|
||||||
|
self.webView.reload()
|
||||||
|
}
|
||||||
|
|
||||||
func navigateBack() {
|
func navigateBack() {
|
||||||
self.webView.goBack()
|
self.webView.goBack()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1483,6 +1483,8 @@ public class ComposePollScreen: ViewControllerComponentContainer, AttachmentCont
|
|||||||
|
|
||||||
fileprivate private(set) var sendButtonItem: UIBarButtonItem?
|
fileprivate private(set) var sendButtonItem: UIBarButtonItem?
|
||||||
|
|
||||||
|
public var isMinimized: Bool = false
|
||||||
|
|
||||||
public var requestAttachmentMenuExpansion: () -> Void = {
|
public var requestAttachmentMenuExpansion: () -> Void = {
|
||||||
}
|
}
|
||||||
public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in
|
public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in
|
||||||
|
|||||||
@ -584,6 +584,7 @@ public class CreatePollControllerImpl: ItemListController, AttachmentContainable
|
|||||||
public var cancelPanGesture: () -> Void = { }
|
public var cancelPanGesture: () -> Void = { }
|
||||||
public var isContainerPanning: () -> Bool = { return false }
|
public var isContainerPanning: () -> Bool = { return false }
|
||||||
public var isContainerExpanded: () -> Bool = { return false }
|
public var isContainerExpanded: () -> Bool = { return false }
|
||||||
|
public var isMinimized: Bool = false
|
||||||
|
|
||||||
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
||||||
return CreatePollContext()
|
return CreatePollContext()
|
||||||
|
|||||||
@ -3,16 +3,45 @@ import AsyncDisplayKit
|
|||||||
|
|
||||||
public protocol MinimizedContainer: ASDisplayNode {
|
public protocol MinimizedContainer: ASDisplayNode {
|
||||||
var navigationController: NavigationController? { get set }
|
var navigationController: NavigationController? { get set }
|
||||||
var controllers: [ViewController] { get }
|
var controllers: [MinimizableController] { get }
|
||||||
var isExpanded: Bool { get }
|
var isExpanded: Bool { get }
|
||||||
|
|
||||||
var willMaximize: (() -> Void)? { get set }
|
var willMaximize: (() -> Void)? { get set }
|
||||||
|
|
||||||
func addController(_ viewController: ViewController, beforeMaximize: @escaping (NavigationController, @escaping () -> Void) -> Void, transition: ContainedViewLayoutTransition)
|
var statusBarStyle: StatusBarStyle { get }
|
||||||
func maximizeController(_ viewController: ViewController, animated: Bool, completion: @escaping (Bool) -> Void)
|
var statusBarStyleUpdated: (() -> Void)? { get set }
|
||||||
|
|
||||||
|
func addController(_ viewController: MinimizableController, beforeMaximize: @escaping (NavigationController, @escaping () -> Void) -> Void, transition: ContainedViewLayoutTransition)
|
||||||
|
func maximizeController(_ viewController: MinimizableController, animated: Bool, completion: @escaping (Bool) -> Void)
|
||||||
func collapse()
|
func collapse()
|
||||||
func dismissAll(completion: @escaping () -> Void)
|
func dismissAll(completion: @escaping () -> Void)
|
||||||
|
|
||||||
func updateLayout(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition)
|
func updateLayout(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition)
|
||||||
func collapsedHeight(layout: ContainerViewLayout) -> CGFloat
|
func collapsedHeight(layout: ContainerViewLayout) -> CGFloat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public protocol MinimizableController: ViewController {
|
||||||
|
var minimizedTopEdgeOffset: CGFloat? { get }
|
||||||
|
var minimizedBounds: CGRect? { get }
|
||||||
|
var isMinimized: Bool { get set }
|
||||||
|
|
||||||
|
func makeContentSnapshotView() -> UIView?
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension MinimizableController {
|
||||||
|
var minimizedTopEdgeOffset: CGFloat? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var minimizedBounds: CGRect? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var isMinimized: Bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeContentSnapshotView() -> UIView? {
|
||||||
|
return self.displayNode.view.snapshotView(afterScreenUpdates: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -160,6 +160,12 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
self.isMaximizing = true
|
self.isMaximizing = true
|
||||||
self.updateContainersNonReentrant(transition: .animated(duration: 0.4, curve: .spring))
|
self.updateContainersNonReentrant(transition: .animated(duration: 0.4, curve: .spring))
|
||||||
}
|
}
|
||||||
|
self.minimizedContainer?.statusBarStyleUpdated = { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.updateContainersNonReentrant(transition: .animated(duration: 0.3, curve: .easeInOut))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,6 +1171,16 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
statusBarHidden = true
|
statusBarHidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let minimizedContainer = self.minimizedContainer, minimizedContainer.isExpanded {
|
||||||
|
if case .Hide = minimizedContainer.statusBarStyle {
|
||||||
|
statusBarHidden = true
|
||||||
|
statusBarStyle = .White
|
||||||
|
} else {
|
||||||
|
statusBarHidden = false
|
||||||
|
statusBarStyle = minimizedContainer.statusBarStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let resolvedStatusBarStyle: NavigationStatusBarStyle
|
let resolvedStatusBarStyle: NavigationStatusBarStyle
|
||||||
switch statusBarStyle {
|
switch statusBarStyle {
|
||||||
case .Ignore, .Hide:
|
case .Ignore, .Hide:
|
||||||
@ -1577,19 +1593,11 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
self._viewControllersPromise.set(self.viewControllers)
|
self._viewControllersPromise.set(self.viewControllers)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func minimizeViewController(_ viewController: ViewController, damping: CGFloat?, velocity: CGFloat? = nil, beforeMaximize: @escaping (NavigationController, @escaping () -> Void) -> Void, setupContainer: (MinimizedContainer?) -> MinimizedContainer?, animated: Bool) {
|
public func minimizeViewController(_ viewController: MinimizableController, damping: CGFloat?, velocity: CGFloat? = nil, beforeMaximize: @escaping (NavigationController, @escaping () -> Void) -> Void, setupContainer: (MinimizedContainer?) -> MinimizedContainer?, animated: Bool) {
|
||||||
let transition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.4, curve: .customSpring(damping: damping ?? 124.0, initialVelocity: velocity ?? 0.0)) : .immediate
|
let transition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.4, curve: .customSpring(damping: damping ?? 124.0, initialVelocity: velocity ?? 0.0)) : .immediate
|
||||||
|
|
||||||
let minimizedContainer = setupContainer(self.minimizedContainer)
|
let minimizedContainer = setupContainer(self.minimizedContainer)
|
||||||
if self.minimizedContainer !== minimizedContainer {
|
if self.minimizedContainer !== minimizedContainer {
|
||||||
minimizedContainer?.willMaximize = { [weak self] in
|
|
||||||
guard let self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self.isMaximizing = true
|
|
||||||
self.updateContainersNonReentrant(transition: .animated(duration: 0.4, curve: .spring))
|
|
||||||
}
|
|
||||||
|
|
||||||
self.minimizedContainer?.removeFromSupernode()
|
self.minimizedContainer?.removeFromSupernode()
|
||||||
self.minimizedContainer = minimizedContainer
|
self.minimizedContainer = minimizedContainer
|
||||||
|
|
||||||
@ -1601,7 +1609,7 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var isMaximizing = false
|
private var isMaximizing = false
|
||||||
public func maximizeViewController(_ viewController: ViewController, animated: Bool) {
|
public func maximizeViewController(_ viewController: MinimizableController, animated: Bool) {
|
||||||
guard let minimizedContainer = self.minimizedContainer else {
|
guard let minimizedContainer = self.minimizedContainer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -485,7 +485,7 @@ final class NavigationModalContainer: ASDisplayNode, ASScrollViewDelegate, ASGes
|
|||||||
let alphaTransition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .easeInOut)
|
let alphaTransition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .easeInOut)
|
||||||
let positionTransition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .easeInOut)
|
let positionTransition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .easeInOut)
|
||||||
alphaTransition.updateAlpha(node: self.dim, alpha: 0.0, beginWithCurrentState: true)
|
alphaTransition.updateAlpha(node: self.dim, alpha: 0.0, beginWithCurrentState: true)
|
||||||
if let lastController = self.container.controllers.last, lastController.isMinimized {
|
if let lastController = self.container.controllers.last as? MinimizableController, lastController.isMinimized {
|
||||||
self.dim.layer.removeAllAnimations()
|
self.dim.layer.removeAllAnimations()
|
||||||
}
|
}
|
||||||
positionTransition.updatePosition(node: self.container, position: CGPoint(x: self.container.position.x, y: self.bounds.height + self.container.bounds.height / 2.0 + self.bounds.height), beginWithCurrentState: true, completion: { [weak self] _ in
|
positionTransition.updatePosition(node: self.container, position: CGPoint(x: self.container.position.x, y: self.bounds.height + self.container.bounds.height / 2.0 + self.bounds.height), beginWithCurrentState: true, completion: { [weak self] _ in
|
||||||
|
|||||||
@ -229,11 +229,7 @@ public protocol CustomViewControllerNavigationDataSummary: AnyObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var navigationBarOrigin: CGFloat = 0.0
|
private var navigationBarOrigin: CGFloat = 0.0
|
||||||
|
|
||||||
public var minimizedTopEdgeOffset: CGFloat?
|
|
||||||
public var minimizedBounds: CGRect?
|
|
||||||
open var isMinimized: Bool = false
|
|
||||||
|
|
||||||
open var interactiveNavivationGestureEdgeWidth: InteractiveTransitionGestureRecognizerEdgeWidth? {
|
open var interactiveNavivationGestureEdgeWidth: InteractiveTransitionGestureRecognizerEdgeWidth? {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -88,6 +88,7 @@ public final class LocationPickerController: ViewController, AttachmentContainab
|
|||||||
public var cancelPanGesture: () -> Void = { }
|
public var cancelPanGesture: () -> Void = { }
|
||||||
public var isContainerPanning: () -> Bool = { return false }
|
public var isContainerPanning: () -> Bool = { return false }
|
||||||
public var isContainerExpanded: () -> Bool = { return false }
|
public var isContainerExpanded: () -> Bool = { return false }
|
||||||
|
public var isMinimized: Bool = false
|
||||||
|
|
||||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: LocationPickerMode, source: Source = .generic, initialLocation: CLLocationCoordinate2D? = nil, completion: @escaping (TelegramMediaMap, Int64?, String?, String?, String?) -> Void) {
|
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: LocationPickerMode, source: Source = .generic, initialLocation: CLLocationCoordinate2D? = nil, completion: @escaping (TelegramMediaMap, Int64?, String?, String?, String?) -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|||||||
@ -160,6 +160,7 @@ public final class MediaGroupsScreen: ViewController, AttachmentContainable {
|
|||||||
public var cancelPanGesture: () -> Void = { }
|
public var cancelPanGesture: () -> Void = { }
|
||||||
public var isContainerPanning: () -> Bool = { return false }
|
public var isContainerPanning: () -> Bool = { return false }
|
||||||
public var isContainerExpanded: () -> Bool = { return false }
|
public var isContainerExpanded: () -> Bool = { return false }
|
||||||
|
public var isMinimized: Bool = false
|
||||||
|
|
||||||
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -222,6 +222,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
|||||||
public var cancelPanGesture: () -> Void = { }
|
public var cancelPanGesture: () -> Void = { }
|
||||||
public var isContainerPanning: () -> Bool = { return false }
|
public var isContainerPanning: () -> Bool = { return false }
|
||||||
public var isContainerExpanded: () -> Bool = { return false }
|
public var isContainerExpanded: () -> Bool = { return false }
|
||||||
|
public var isMinimized: Bool = false
|
||||||
|
|
||||||
public var getCurrentSendMessageContextMediaPreview: (() -> ChatSendMessageContextScreenMediaPreview?)? = nil
|
public var getCurrentSendMessageContextMediaPreview: (() -> ChatSendMessageContextScreenMediaPreview?)? = nil
|
||||||
|
|
||||||
|
|||||||
@ -456,6 +456,7 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/PeerManagement/OwnershipTransferController",
|
"//submodules/TelegramUI/Components/PeerManagement/OwnershipTransferController",
|
||||||
"//submodules/TelegramUI/Components/PeerManagement/OldChannelsController",
|
"//submodules/TelegramUI/Components/PeerManagement/OldChannelsController",
|
||||||
"//submodules/TelegramUI/Components/Chat/ChatSendStarsScreen",
|
"//submodules/TelegramUI/Components/Chat/ChatSendStarsScreen",
|
||||||
|
"//submodules/TelegramUI/Components/MinimizedContainer",
|
||||||
] + select({
|
] + select({
|
||||||
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
|
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
|
||||||
"//build-system:ios_sim_arm64": [],
|
"//build-system:ios_sim_arm64": [],
|
||||||
|
|||||||
@ -26,10 +26,10 @@ final class ScrollViewImpl: UIScrollView {
|
|||||||
public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScrollViewDelegate, ASGestureRecognizerDelegate {
|
public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScrollViewDelegate, ASGestureRecognizerDelegate {
|
||||||
final class Item {
|
final class Item {
|
||||||
let id: AnyHashable
|
let id: AnyHashable
|
||||||
let controller: ViewController
|
let controller: MinimizableController
|
||||||
let beforeMaximize: (NavigationController, @escaping () -> Void) -> Void
|
let beforeMaximize: (NavigationController, @escaping () -> Void) -> Void
|
||||||
|
|
||||||
init(id: AnyHashable, controller: ViewController, beforeMaximize: @escaping (NavigationController, @escaping () -> Void) -> Void) {
|
init(id: AnyHashable, controller: MinimizableController, beforeMaximize: @escaping (NavigationController, @escaping () -> Void) -> Void) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.beforeMaximize = beforeMaximize
|
self.beforeMaximize = beforeMaximize
|
||||||
@ -112,7 +112,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
|||||||
|
|
||||||
Queue.mainQueue().after(0.45) {
|
Queue.mainQueue().after(0.45) {
|
||||||
self.isReady = true
|
self.isReady = true
|
||||||
if !self.isDismissed, let snapshotView = self.controllerView?.snapshotView(afterScreenUpdates: false) {
|
if !self.isDismissed, let snapshotView = self.item.controller.makeContentSnapshotView() {
|
||||||
self.containerNode.view.addSubview(self.snapshotContainerView)
|
self.containerNode.view.addSubview(self.snapshotContainerView)
|
||||||
self.snapshotView = snapshotView
|
self.snapshotView = snapshotView
|
||||||
self.controllerView?.removeFromSuperview()
|
self.controllerView?.removeFromSuperview()
|
||||||
@ -141,7 +141,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
|||||||
self.headerNode.controllers = [item.controller]
|
self.headerNode.controllers = [item.controller]
|
||||||
}
|
}
|
||||||
|
|
||||||
func setTitleControllers(_ controllers: [ViewController]?) {
|
func setTitleControllers(_ controllers: [MinimizableController]?) {
|
||||||
self.headerNode.controllers = controllers ?? [self.item.controller]
|
self.headerNode.controllers = controllers ?? [self.item.controller]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,6 +293,9 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
|||||||
public private(set) var isExpanded: Bool = false
|
public private(set) var isExpanded: Bool = false
|
||||||
public var willMaximize: (() -> Void)?
|
public var willMaximize: (() -> Void)?
|
||||||
|
|
||||||
|
public private(set) var statusBarStyle: StatusBarStyle = .White
|
||||||
|
public var statusBarStyleUpdated: (() -> Void)?
|
||||||
|
|
||||||
private let bottomEdgeView: UIImageView
|
private let bottomEdgeView: UIImageView
|
||||||
private let blurView: BlurView
|
private let blurView: BlurView
|
||||||
private let dimView: UIView
|
private let dimView: UIView
|
||||||
@ -310,7 +313,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
|||||||
private var isApplyingTransition = false
|
private var isApplyingTransition = false
|
||||||
private var validLayout: ContainerViewLayout?
|
private var validLayout: ContainerViewLayout?
|
||||||
|
|
||||||
public var controllers: [ViewController] {
|
public var controllers: [MinimizableController] {
|
||||||
return self.items.map { $0.controller }
|
return self.items.map { $0.controller }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,7 +504,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public func addController(_ viewController: ViewController, beforeMaximize: @escaping (NavigationController, @escaping () -> Void) -> Void, transition: ContainedViewLayoutTransition) {
|
public func addController(_ viewController: MinimizableController, beforeMaximize: @escaping (NavigationController, @escaping () -> Void) -> Void, transition: ContainedViewLayoutTransition) {
|
||||||
let item = Item(
|
let item = Item(
|
||||||
id: AnyHashable(Int64.random(in: Int64.min ... Int64.max)),
|
id: AnyHashable(Int64.random(in: Int64.min ... Int64.max)),
|
||||||
controller: viewController,
|
controller: viewController,
|
||||||
@ -534,7 +537,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func maximizeController(_ viewController: ViewController, animated: Bool, completion: @escaping (Bool) -> Void) {
|
public func maximizeController(_ viewController: MinimizableController, animated: Bool, completion: @escaping (Bool) -> Void) {
|
||||||
guard let item = self.items.first(where: { $0.controller === viewController }) else {
|
guard let item = self.items.first(where: { $0.controller === viewController }) else {
|
||||||
completion(self.items.count == 0)
|
completion(self.items.count == 0)
|
||||||
return
|
return
|
||||||
@ -715,14 +718,16 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
|||||||
self.navigationController?.dismissMinimizedControllers(animated: true)
|
self.navigationController?.dismissMinimizedControllers(animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemNode.tapped = { [weak self] in
|
itemNode.tapped = { [weak self, weak itemNode] in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if self.isExpanded {
|
if self.isExpanded, let itemNode {
|
||||||
if let navigationController = self.navigationController {
|
if let navigationController = self.navigationController {
|
||||||
itemNode.item.beforeMaximize(navigationController, { [weak self] in
|
itemNode.item.beforeMaximize(navigationController, { [weak self, weak itemNode] in
|
||||||
self?.navigationController?.maximizeViewController(item.controller, animated: true)
|
if let item = itemNode?.item {
|
||||||
|
self?.navigationController?.maximizeViewController(item.controller, animated: true)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -845,6 +850,21 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
|||||||
self.scrollView.isScrollEnabled = self.isExpanded
|
self.scrollView.isScrollEnabled = self.isExpanded
|
||||||
self.expandedTapGestureRecoginzer?.isEnabled = self.isExpanded
|
self.expandedTapGestureRecoginzer?.isEnabled = self.isExpanded
|
||||||
|
|
||||||
|
var resolvedStatusBarStyle: StatusBarStyle = .Ignore
|
||||||
|
if self.isExpanded {
|
||||||
|
if self.scrollView.contentOffset.y > additionalInsetTop + insets.top / 2.0 {
|
||||||
|
resolvedStatusBarStyle = .Hide
|
||||||
|
} else {
|
||||||
|
resolvedStatusBarStyle = .White
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.statusBarStyle != resolvedStatusBarStyle {
|
||||||
|
self.statusBarStyle = resolvedStatusBarStyle
|
||||||
|
Queue.mainQueue().justDispatch {
|
||||||
|
self.statusBarStyleUpdated?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let currentTransition = self.currentTransition {
|
if let currentTransition = self.currentTransition {
|
||||||
self.isApplyingTransition = true
|
self.isApplyingTransition = true
|
||||||
switch self.currentTransition {
|
switch self.currentTransition {
|
||||||
|
|||||||
@ -103,10 +103,6 @@ final class MinimizedHeaderNode: ASDisplayNode {
|
|||||||
applySmoothRoundedCorners(self.minimizedBackgroundNode.layer)
|
applySmoothRoundedCorners(self.minimizedBackgroundNode.layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
|
||||||
self.minimizedTitleDisposable?.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func didLoad() {
|
override func didLoad() {
|
||||||
super.didLoad()
|
super.didLoad()
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@ public class PremiumGiftAttachmentScreen: PremiumGiftScreen, AttachmentContainab
|
|||||||
public var cancelPanGesture: () -> Void = { }
|
public var cancelPanGesture: () -> Void = { }
|
||||||
public var isContainerPanning: () -> Bool = { return false }
|
public var isContainerPanning: () -> Bool = { return false }
|
||||||
public var isContainerExpanded: () -> Bool = { return false }
|
public var isContainerExpanded: () -> Bool = { return false }
|
||||||
|
public var isMinimized: Bool = false
|
||||||
|
|
||||||
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
||||||
return PremiumGiftContext(controller: self)
|
return PremiumGiftContext(controller: self)
|
||||||
|
|||||||
@ -1317,6 +1317,7 @@ public final class QuickReplySetupScreen: ViewControllerComponentContainer, Atta
|
|||||||
public var isContainerExpanded: () -> Bool = {
|
public var isContainerExpanded: () -> Bool = {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
public var isMinimized: Bool = false
|
||||||
public var mediaPickerContext: AttachmentMediaPickerContext?
|
public var mediaPickerContext: AttachmentMediaPickerContext?
|
||||||
|
|
||||||
public init(context: AccountContext, initialData: InitialData, mode: Mode) {
|
public init(context: AccountContext, initialData: InitialData, mode: Mode) {
|
||||||
|
|||||||
@ -345,6 +345,7 @@ public final class ThemeColorsGridController: ViewController, AttachmentContaina
|
|||||||
public var cancelPanGesture: () -> Void = { }
|
public var cancelPanGesture: () -> Void = { }
|
||||||
public var isContainerPanning: () -> Bool = { return false }
|
public var isContainerPanning: () -> Bool = { return false }
|
||||||
public var isContainerExpanded: () -> Bool = { return false }
|
public var isContainerExpanded: () -> Bool = { return false }
|
||||||
|
public var isMinimized: Bool = false
|
||||||
|
|
||||||
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
||||||
return ThemeColorsGridContext(controller: self)
|
return ThemeColorsGridContext(controller: self)
|
||||||
|
|||||||
@ -31,7 +31,8 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||||
"//submodules/TelegramUI/Components/ListSectionComponent",
|
"//submodules/TelegramUI/Components/ListSectionComponent",
|
||||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||||
"//submodules/TelegramUI/Components/Stars/StarsImageComponent",
|
"//submodules/TelegramUI/Components/Stars/StarsImageComponent",
|
||||||
|
"//submodules/ConfettiEffect",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import UndoUI
|
|||||||
import AccountContext
|
import AccountContext
|
||||||
import PresentationDataUtils
|
import PresentationDataUtils
|
||||||
import StarsImageComponent
|
import StarsImageComponent
|
||||||
|
import ConfettiEffect
|
||||||
|
|
||||||
private final class SheetContent: CombinedComponent {
|
private final class SheetContent: CombinedComponent {
|
||||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||||
@ -256,9 +257,7 @@ private final class SheetContent: CombinedComponent {
|
|||||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let theme = presentationData.theme
|
let theme = presentationData.theme
|
||||||
let strings = presentationData.strings
|
let strings = presentationData.strings
|
||||||
|
|
||||||
// let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
|
||||||
|
|
||||||
var contentSize = CGSize(width: context.availableSize.width, height: 18.0)
|
var contentSize = CGSize(width: context.availableSize.width, height: 18.0)
|
||||||
|
|
||||||
let background = background.update(
|
let background = background.update(
|
||||||
@ -658,6 +657,7 @@ private final class StarsTransferSheetComponent: CombinedComponent {
|
|||||||
|
|
||||||
public final class StarsTransferScreen: ViewControllerComponentContainer {
|
public final class StarsTransferScreen: ViewControllerComponentContainer {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
|
private let extendedMedia: [TelegramExtendedMedia]
|
||||||
private let completion: (Bool) -> Void
|
private let completion: (Bool) -> Void
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
@ -670,6 +670,7 @@ public final class StarsTransferScreen: ViewControllerComponentContainer {
|
|||||||
completion: @escaping (Bool) -> Void
|
completion: @escaping (Bool) -> Void
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
|
self.extendedMedia = extendedMedia
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
|
|
||||||
super.init(
|
super.init(
|
||||||
@ -707,6 +708,10 @@ public final class StarsTransferScreen: ViewControllerComponentContainer {
|
|||||||
}
|
}
|
||||||
self.didComplete = true
|
self.didComplete = true
|
||||||
self.completion(paid)
|
self.completion(paid)
|
||||||
|
|
||||||
|
if !self.extendedMedia.isEmpty && paid {
|
||||||
|
self.navigationController?.view.addSubview(ConfettiView(frame: self.view.bounds, customImage: UIImage(bundleImageName: "Peer Info/PremiumIcon")))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func dismissAnimated() {
|
public func dismissAnimated() {
|
||||||
|
|||||||
12
submodules/TelegramUI/Images.xcassets/Instant View/CloseIcon.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Instant View/CloseIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "cross.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
83
submodules/TelegramUI/Images.xcassets/Instant View/CloseIcon.imageset/cross.pdf
vendored
Normal file
83
submodules/TelegramUI/Images.xcassets/Instant View/CloseIcon.imageset/cross.pdf
vendored
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
|
||||||
|
1 0 obj
|
||||||
|
<< >>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
2 0 obj
|
||||||
|
<< /Length 3 0 R >>
|
||||||
|
stream
|
||||||
|
/DeviceRGB CS
|
||||||
|
/DeviceRGB cs
|
||||||
|
q
|
||||||
|
1.000000 0.000000 -0.000000 1.000000 5.100098 4.640198 cm
|
||||||
|
1.000000 1.000000 1.000000 scn
|
||||||
|
0.970226 14.230053 m
|
||||||
|
0.710527 14.489752 0.289473 14.489752 0.029774 14.230053 c
|
||||||
|
-0.229925 13.970354 -0.229925 13.549299 0.029774 13.289600 c
|
||||||
|
5.959549 7.359825 l
|
||||||
|
0.029774 1.430050 l
|
||||||
|
-0.229925 1.170351 -0.229925 0.749296 0.029774 0.489597 c
|
||||||
|
0.289473 0.229898 0.710527 0.229898 0.970226 0.489597 c
|
||||||
|
6.900002 6.419373 l
|
||||||
|
12.829774 0.489600 l
|
||||||
|
13.089473 0.229901 13.510528 0.229901 13.770226 0.489600 c
|
||||||
|
14.029925 0.749299 14.029925 1.170354 13.770226 1.430053 c
|
||||||
|
7.840454 7.359825 l
|
||||||
|
13.770226 13.289598 l
|
||||||
|
14.029925 13.549296 14.029925 13.970351 13.770226 14.230050 c
|
||||||
|
13.510528 14.489749 13.089473 14.489749 12.829774 14.230050 c
|
||||||
|
6.900002 8.300278 l
|
||||||
|
0.970226 14.230053 l
|
||||||
|
h
|
||||||
|
f*
|
||||||
|
n
|
||||||
|
Q
|
||||||
|
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj
|
||||||
|
789
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj
|
||||||
|
<< /Annots []
|
||||||
|
/Type /Page
|
||||||
|
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
|
||||||
|
/Resources 1 0 R
|
||||||
|
/Contents 2 0 R
|
||||||
|
/Parent 5 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
5 0 obj
|
||||||
|
<< /Kids [ 4 0 R ]
|
||||||
|
/Count 1
|
||||||
|
/Type /Pages
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
6 0 obj
|
||||||
|
<< /Pages 5 0 R
|
||||||
|
/Type /Catalog
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
xref
|
||||||
|
0 7
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000010 00000 n
|
||||||
|
0000000034 00000 n
|
||||||
|
0000000879 00000 n
|
||||||
|
0000000901 00000 n
|
||||||
|
0000001074 00000 n
|
||||||
|
0000001148 00000 n
|
||||||
|
trailer
|
||||||
|
<< /ID [ (some) (id) ]
|
||||||
|
/Root 6 0 R
|
||||||
|
/Size 7
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
1207
|
||||||
|
%%EOF
|
||||||
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"author" : "xcode",
|
||||||
"author" : "xcode"
|
"version" : 1
|
||||||
},
|
},
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"provides-namespace" : true
|
"provides-namespace" : true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import StoryContainerScreen
|
|||||||
import ChatMessageNotificationItem
|
import ChatMessageNotificationItem
|
||||||
import PhoneNumberFormat
|
import PhoneNumberFormat
|
||||||
import AttachmentUI
|
import AttachmentUI
|
||||||
|
import MinimizedContainer
|
||||||
|
|
||||||
final class UnauthorizedApplicationContext {
|
final class UnauthorizedApplicationContext {
|
||||||
let sharedContext: SharedAccountContextImpl
|
let sharedContext: SharedAccountContextImpl
|
||||||
@ -440,7 +441,9 @@ final class AuthorizedApplicationContext {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if let topContoller = strongSelf.rootController.topViewController as? AttachmentController {
|
if let minimizedContainer = strongSelf.rootController.minimizedContainer, minimizedContainer.isExpanded {
|
||||||
|
minimizedContainer.collapse()
|
||||||
|
} else if let topContoller = strongSelf.rootController.topViewController as? AttachmentController {
|
||||||
topContoller.minimizeIfNeeded()
|
topContoller.minimizeIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -215,6 +215,7 @@ class AttachmentFileControllerImpl: ItemListController, AttachmentFileController
|
|||||||
public var cancelPanGesture: () -> Void = { }
|
public var cancelPanGesture: () -> Void = { }
|
||||||
public var isContainerPanning: () -> Bool = { return false }
|
public var isContainerPanning: () -> Bool = { return false }
|
||||||
public var isContainerExpanded: () -> Bool = { return false }
|
public var isContainerExpanded: () -> Bool = { return false }
|
||||||
|
public var isMinimized: Bool = false
|
||||||
|
|
||||||
var delayDisappear = false
|
var delayDisappear = false
|
||||||
|
|
||||||
|
|||||||
@ -2631,7 +2631,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||||
|> deliverOnMainQueue).startStandalone(next: { message in
|
|> deliverOnMainQueue).startStandalone(next: { message in
|
||||||
guard let strongSelf = self, let message = message else {
|
guard let strongSelf = self, let message else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2670,7 +2670,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
guard let strongSelf = self, let extendedMedia = paidContent.extendedMedia.first, case let .preview(dimensions, immediateThumbnailData, _) = extendedMedia else {
|
guard let strongSelf = self, let extendedMedia = paidContent.extendedMedia.first, case let .preview(dimensions, immediateThumbnailData, _) = extendedMedia else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let invoice = TelegramMediaInvoice(title: "", description: "", photo: nil, receiptMessageId: nil, currency: "XTR", totalAmount: paidContent.amount, startParam: "", extendedMedia: .preview(dimensions:dimensions, immediateThumbnailData: immediateThumbnailData, videoDuration: nil), flags: [], version: 0)
|
var messageId = messageId
|
||||||
|
if let sourceMessageId = message.forwardInfo?.sourceMessageId {
|
||||||
|
messageId = sourceMessageId
|
||||||
|
}
|
||||||
|
let invoice = TelegramMediaInvoice(title: "", description: "", photo: nil, receiptMessageId: nil, currency: "XTR", totalAmount: paidContent.amount, startParam: "", extendedMedia: .preview(dimensions: dimensions, immediateThumbnailData: immediateThumbnailData, videoDuration: nil), flags: [], version: 0)
|
||||||
let controller = strongSelf.context.sharedContext.makeStarsTransferScreen(context: strongSelf.context, starsContext: starsContext, invoice: invoice, source: .message(messageId), extendedMedia: paidContent.extendedMedia, inputData: starsInputData, completion: { _ in })
|
let controller = strongSelf.context.sharedContext.makeStarsTransferScreen(context: strongSelf.context, starsContext: starsContext, invoice: invoice, source: .message(messageId), extendedMedia: paidContent.extendedMedia, inputData: starsInputData, completion: { _ in })
|
||||||
strongSelf.push(controller)
|
strongSelf.push(controller)
|
||||||
|
|
||||||
|
|||||||
@ -88,6 +88,7 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController
|
|||||||
var cancelPanGesture: () -> Void = { }
|
var cancelPanGesture: () -> Void = { }
|
||||||
var isContainerPanning: () -> Bool = { return false }
|
var isContainerPanning: () -> Bool = { return false }
|
||||||
var isContainerExpanded: () -> Bool = { return false }
|
var isContainerExpanded: () -> Bool = { return false }
|
||||||
|
var isMinimized: Bool = false
|
||||||
|
|
||||||
var getCurrentSendMessageContextMediaPreview: (() -> ChatSendMessageContextScreenMediaPreview?)?
|
var getCurrentSendMessageContextMediaPreview: (() -> ChatSendMessageContextScreenMediaPreview?)?
|
||||||
|
|
||||||
|
|||||||
@ -268,7 +268,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
public var cancelPanGesture: () -> Void = { }
|
public var cancelPanGesture: () -> Void = { }
|
||||||
public var isContainerPanning: () -> Bool = { return false }
|
public var isContainerPanning: () -> Bool = { return false }
|
||||||
public var isContainerExpanded: () -> Bool = { return false }
|
public var isContainerExpanded: () -> Bool = { return false }
|
||||||
|
|
||||||
fileprivate class Node: ViewControllerTracingNode, WKNavigationDelegate, WKUIDelegate, ASScrollViewDelegate {
|
fileprivate class Node: ViewControllerTracingNode, WKNavigationDelegate, WKUIDelegate, ASScrollViewDelegate {
|
||||||
private weak var controller: WebAppController?
|
private weak var controller: WebAppController?
|
||||||
|
|
||||||
@ -2171,7 +2171,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override var isMinimized: Bool {
|
public var isMinimized: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
if self.isMinimized != oldValue && self.isMinimized {
|
if self.isMinimized != oldValue && self.isMinimized {
|
||||||
self.controllerNode.webView?.hideScrollIndicators()
|
self.controllerNode.webView?.hideScrollIndicators()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user