mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-07-10 18:07:04 +02:00
chore: migrate to new version + fixed several critical bugs
- Migrated project to latest Telegram iOS base (v12.3.2+) - Fixed circular dependency between GhostModeManager and MiscSettingsManager - Fixed multiple Bazel build configuration errors (select() default conditions) - Fixed duplicate type definitions in PeerInfoScreen - Fixed swiftmodule directory resolution in build scripts - Added Ghostgram Settings tab in main Settings menu with all 5 features - Cleared sensitive credentials from config.json (template-only now) - Excluded bazel-cache from version control
This commit is contained in:
@@ -6,27 +6,25 @@ import TelegramPresentationData
|
||||
import ComponentFlow
|
||||
import ComponentDisplayAdapters
|
||||
import TabBarComponent
|
||||
|
||||
private extension ToolbarTheme {
|
||||
convenience init(theme: PresentationTheme) {
|
||||
self.init(barBackgroundColor: theme.rootController.tabBar.backgroundColor, barSeparatorColor: .clear, barTextColor: theme.rootController.tabBar.textColor, barSelectedTextColor: theme.rootController.tabBar.selectedTextColor)
|
||||
}
|
||||
}
|
||||
import GlassControls
|
||||
|
||||
final class TabBarControllerNode: ASDisplayNode {
|
||||
private struct Params: Equatable {
|
||||
let layout: ContainerViewLayout
|
||||
let toolbar: Toolbar?
|
||||
let isTabBarHidden: Bool
|
||||
let currentControllerSearchState: ViewController.TabBarSearchState?
|
||||
|
||||
init(
|
||||
layout: ContainerViewLayout,
|
||||
toolbar: Toolbar?,
|
||||
isTabBarHidden: Bool
|
||||
isTabBarHidden: Bool,
|
||||
currentControllerSearchState: ViewController.TabBarSearchState?
|
||||
) {
|
||||
self.layout = layout
|
||||
self.toolbar = toolbar
|
||||
self.isTabBarHidden = isTabBarHidden
|
||||
self.currentControllerSearchState = currentControllerSearchState
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,33 +49,36 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
private var theme: PresentationTheme
|
||||
private var strings: PresentationStrings
|
||||
private let itemSelected: (Int, Bool, [ASDisplayNode]) -> Void
|
||||
private let contextAction: (Int, ContextExtractedContentContainingView, ContextGesture) -> Void
|
||||
|
||||
private let tabBarView = ComponentView<Empty>()
|
||||
|
||||
private let disabledOverlayNode: ASDisplayNode
|
||||
private var toolbarNode: ToolbarNode?
|
||||
private var toolbar: ComponentView<Empty>?
|
||||
private let toolbarActionSelected: (ToolbarActionOption) -> Void
|
||||
private let disabledPressed: () -> Void
|
||||
private let activateSearch: () -> Void
|
||||
private let deactivateSearch: () -> Void
|
||||
|
||||
private(set) var tabBarItems: [TabBarNodeItem] = []
|
||||
private(set) var selectedIndex: Int = 0
|
||||
|
||||
private(set) var currentControllerNode: ASDisplayNode?
|
||||
private weak var currentController: ViewController?
|
||||
|
||||
private var layoutResult: LayoutResult?
|
||||
private var isUpdateRequested: Bool = false
|
||||
private var isChangingSelectedIndex: Bool = false
|
||||
|
||||
func setCurrentControllerNode(_ node: ASDisplayNode?) -> () -> Void {
|
||||
guard node !== self.currentControllerNode else {
|
||||
func setCurrentController(_ controller: ViewController?) -> () -> Void {
|
||||
guard controller !== self.currentController else {
|
||||
return {}
|
||||
}
|
||||
|
||||
let previousNode = self.currentControllerNode
|
||||
self.currentControllerNode = node
|
||||
if let currentControllerNode = self.currentControllerNode {
|
||||
let previousNode = self.currentController?.displayNode
|
||||
self.currentController = controller
|
||||
if let currentControllerNode = self.currentController?.displayNode {
|
||||
if let previousNode {
|
||||
self.insertSubnode(currentControllerNode, aboveSubnode: previousNode)
|
||||
} else {
|
||||
@@ -89,14 +90,22 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
return { [weak self, weak previousNode] in
|
||||
if previousNode !== self?.currentControllerNode {
|
||||
if previousNode !== self?.currentController?.displayNode {
|
||||
previousNode?.removeFromSupernode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var currentSearchNode: ASDisplayNode? {
|
||||
if let tabBarComponentView = self.tabBarView.view as? TabBarComponent.View {
|
||||
return tabBarComponentView.currentSearchNode
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
init(theme: PresentationTheme, itemSelected: @escaping (Int, Bool, [ASDisplayNode]) -> Void, contextAction: @escaping (Int, ContextExtractedContentContainingView, ContextGesture) -> Void, swipeAction: @escaping (Int, TabBarItemSwipeDirection) -> Void, toolbarActionSelected: @escaping (ToolbarActionOption) -> Void, disabledPressed: @escaping () -> Void) {
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, itemSelected: @escaping (Int, Bool, [ASDisplayNode]) -> Void, contextAction: @escaping (Int, ContextExtractedContentContainingView, ContextGesture) -> Void, swipeAction: @escaping (Int, TabBarItemSwipeDirection) -> Void, toolbarActionSelected: @escaping (ToolbarActionOption) -> Void, disabledPressed: @escaping () -> Void, activateSearch: @escaping () -> Void, deactivateSearch: @escaping () -> Void) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.itemSelected = itemSelected
|
||||
self.contextAction = contextAction
|
||||
self.disabledOverlayNode = ASDisplayNode()
|
||||
@@ -104,7 +113,9 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
self.disabledOverlayNode.alpha = 0.0
|
||||
self.toolbarActionSelected = toolbarActionSelected
|
||||
self.disabledPressed = disabledPressed
|
||||
|
||||
self.activateSearch = activateSearch
|
||||
self.deactivateSearch = deactivateSearch
|
||||
|
||||
super.init()
|
||||
|
||||
self.setViewBlock({
|
||||
@@ -146,7 +157,6 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
self.backgroundColor = theme.list.plainBackgroundColor
|
||||
|
||||
self.disabledOverlayNode.backgroundColor = theme.rootController.tabBar.backgroundColor.withAlphaComponent(0.5)
|
||||
self.toolbarNode?.updateTheme(ToolbarTheme(theme: theme))
|
||||
self.requestUpdate()
|
||||
}
|
||||
|
||||
@@ -163,7 +173,7 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
func containerLayoutUpdated(_ layout: ContainerViewLayout, toolbar: Toolbar?, transition: ContainedViewLayoutTransition) -> CGFloat {
|
||||
let params = Params(layout: layout, toolbar: toolbar, isTabBarHidden: self.tabBarHidden)
|
||||
let params = Params(layout: layout, toolbar: toolbar, isTabBarHidden: self.tabBarHidden, currentControllerSearchState: self.currentController?.tabBarSearchState)
|
||||
if let layoutResult = self.layoutResult, layoutResult.params == params {
|
||||
return layoutResult.bottomInset
|
||||
} else {
|
||||
@@ -179,18 +189,27 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
private func updateImpl(params: Params, transition: ContainedViewLayoutTransition) -> CGFloat {
|
||||
var options: ContainerViewLayoutInsetOptions = []
|
||||
if params.layout.metrics.widthClass == .regular {
|
||||
options.insert(.input)
|
||||
var panelsBottomInset: CGFloat = params.layout.insets(options: []).bottom
|
||||
if params.layout.metrics.widthClass == .regular, let inputHeight = params.layout.inputHeight, inputHeight != 0.0 {
|
||||
panelsBottomInset = inputHeight + 8.0
|
||||
}
|
||||
|
||||
var bottomInset: CGFloat = params.layout.insets(options: options).bottom
|
||||
if bottomInset == 0.0 {
|
||||
bottomInset = 8.0
|
||||
if panelsBottomInset == 0.0 {
|
||||
panelsBottomInset = 8.0
|
||||
} else {
|
||||
bottomInset = max(bottomInset, 8.0)
|
||||
panelsBottomInset = max(panelsBottomInset, 8.0)
|
||||
}
|
||||
|
||||
var tabBarBottomInset: CGFloat = panelsBottomInset
|
||||
if let currentController = self.currentController {
|
||||
if let tabBarSearchState = currentController.tabBarSearchState, tabBarSearchState.isActive, let inputHeight = params.layout.inputHeight, inputHeight != 0.0 {
|
||||
tabBarBottomInset = max(tabBarBottomInset, inputHeight + 8.0)
|
||||
}
|
||||
}
|
||||
|
||||
var sideInset: CGFloat = 12.0
|
||||
if tabBarBottomInset <= 28.0 {
|
||||
sideInset = 20.0
|
||||
}
|
||||
let sideInset: CGFloat = 20.0
|
||||
|
||||
var selectedId: AnyHashable?
|
||||
if self.selectedIndex < self.tabBarItems.count {
|
||||
@@ -208,6 +227,7 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
transition: tabBarTransition,
|
||||
component: AnyComponent(TabBarComponent(
|
||||
theme: self.theme,
|
||||
strings: self.strings,
|
||||
items: self.tabBarItems.map { item in
|
||||
let itemId = AnyHashable(ObjectIdentifier(item.item))
|
||||
return TabBarComponent.Item(
|
||||
@@ -230,13 +250,30 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
}
|
||||
)
|
||||
},
|
||||
search: self.currentController?.tabBarSearchState.flatMap { tabBarSearchState in
|
||||
return TabBarComponent.Search(
|
||||
isActive: tabBarSearchState.isActive,
|
||||
activate: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.activateSearch()
|
||||
},
|
||||
deactivate: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.deactivateSearch()
|
||||
}
|
||||
)
|
||||
},
|
||||
selectedId: selectedId,
|
||||
isTablet: params.layout.metrics.isTablet
|
||||
outerInsets: UIEdgeInsets(top: 0.0, left: sideInset, bottom: tabBarBottomInset, right: sideInset)
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: params.layout.size.width - sideInset * 2.0, height: 100.0)
|
||||
)
|
||||
let tabBarFrame = CGRect(origin: CGPoint(x: floor((params.layout.size.width - tabBarSize.width) * 0.5), y: params.layout.size.height - (self.tabBarHidden ? 0.0 : (tabBarSize.height + bottomInset))), size: tabBarSize)
|
||||
let tabBarFrame = CGRect(origin: CGPoint(x: floor((params.layout.size.width - tabBarSize.width) * 0.5), y: params.layout.size.height - (self.tabBarHidden ? 0.0 : (tabBarSize.height + tabBarBottomInset))), size: tabBarSize)
|
||||
|
||||
if let tabBarComponentView = self.tabBarView.view {
|
||||
if tabBarComponentView.superview == nil {
|
||||
@@ -248,34 +285,90 @@ final class TabBarControllerNode: ASDisplayNode {
|
||||
|
||||
transition.updateFrame(node: self.disabledOverlayNode, frame: tabBarFrame)
|
||||
|
||||
let toolbarHeight = 50.0 + params.layout.insets(options: options).bottom
|
||||
let toolbarFrame = CGRect(origin: CGPoint(x: 0.0, y: params.layout.size.height - toolbarHeight), size: CGSize(width: params.layout.size.width, height: toolbarHeight))
|
||||
let toolbarHeight = 44.0
|
||||
let toolbarFrame = CGRect(origin: CGPoint(x: sideInset, y: params.layout.size.height - panelsBottomInset - toolbarHeight), size: CGSize(width: params.layout.size.width - sideInset * 2.0, height: toolbarHeight))
|
||||
|
||||
if let toolbar = params.toolbar {
|
||||
if let toolbarNode = self.toolbarNode {
|
||||
transition.updateFrame(node: toolbarNode, frame: toolbarFrame)
|
||||
toolbarNode.updateLayout(size: toolbarFrame.size, leftInset: params.layout.safeInsets.left, rightInset: params.layout.safeInsets.right, additionalSideInsets: params.layout.additionalInsets, bottomInset: bottomInset, toolbar: toolbar, transition: transition)
|
||||
if let toolbarData = params.toolbar {
|
||||
let toolbar: ComponentView<Empty>
|
||||
var toolbarTransition = ComponentTransition(transition)
|
||||
if let current = self.toolbar {
|
||||
toolbar = current
|
||||
} else {
|
||||
let toolbarNode = ToolbarNode(theme: ToolbarTheme(theme: self.theme), displaySeparator: true, left: { [weak self] in
|
||||
self?.toolbarActionSelected(.left)
|
||||
}, right: { [weak self] in
|
||||
self?.toolbarActionSelected(.right)
|
||||
}, middle: { [weak self] in
|
||||
self?.toolbarActionSelected(.middle)
|
||||
})
|
||||
toolbarNode.frame = toolbarFrame
|
||||
toolbarNode.updateLayout(size: toolbarFrame.size, leftInset: params.layout.safeInsets.left, rightInset: params.layout.safeInsets.right, additionalSideInsets: params.layout.additionalInsets, bottomInset: bottomInset, toolbar: toolbar, transition: .immediate)
|
||||
self.addSubnode(toolbarNode)
|
||||
self.toolbarNode = toolbarNode
|
||||
if transition.isAnimated {
|
||||
toolbarNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
toolbar = ComponentView()
|
||||
self.toolbar = toolbar
|
||||
toolbarTransition = .immediate
|
||||
}
|
||||
|
||||
let _ = toolbar.update(
|
||||
transition: toolbarTransition,
|
||||
component: AnyComponent(GlassControlPanelComponent(
|
||||
theme: self.theme,
|
||||
leftItem: toolbarData.leftAction.flatMap { value in
|
||||
return GlassControlPanelComponent.Item(
|
||||
items: [GlassControlGroupComponent.Item(
|
||||
id: "left_" + value.title,
|
||||
content: .text(value.title),
|
||||
action: value.isEnabled ? { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.toolbarActionSelected(.left)
|
||||
} : nil
|
||||
)],
|
||||
background: .panel
|
||||
)
|
||||
},
|
||||
centralItem: toolbarData.middleAction.flatMap { value in
|
||||
return GlassControlPanelComponent.Item(
|
||||
items: [GlassControlGroupComponent.Item(
|
||||
id: "right_" + value.title,
|
||||
content: .text(value.title),
|
||||
action: value.isEnabled ? { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.toolbarActionSelected(.middle)
|
||||
} : nil
|
||||
)],
|
||||
background: .panel
|
||||
)
|
||||
},
|
||||
rightItem: toolbarData.rightAction.flatMap { value in
|
||||
return GlassControlPanelComponent.Item(
|
||||
items: [GlassControlGroupComponent.Item(
|
||||
id: "right_" + value.title,
|
||||
content: .text(value.title),
|
||||
action: value.isEnabled ? { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.toolbarActionSelected(.right)
|
||||
} : nil
|
||||
)],
|
||||
background: .panel
|
||||
)
|
||||
},
|
||||
centerAlignmentIfPossible: true
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: toolbarFrame.size
|
||||
)
|
||||
|
||||
if let toolbarView = toolbar.view {
|
||||
if toolbarView.superview == nil {
|
||||
self.view.addSubview(toolbarView)
|
||||
toolbarView.alpha = 0.0
|
||||
}
|
||||
toolbarTransition.setFrame(view: toolbarView, frame: toolbarFrame)
|
||||
ComponentTransition(transition).setAlpha(view: toolbarView, alpha: 1.0)
|
||||
}
|
||||
} else if let toolbar = self.toolbar {
|
||||
self.toolbar = nil
|
||||
if let toolbarView = toolbar.view {
|
||||
ComponentTransition(transition).setAlpha(view: toolbarView, alpha: 0.0, completion: { [weak toolbarView] _ in
|
||||
toolbarView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
} else if let toolbarNode = self.toolbarNode {
|
||||
self.toolbarNode = nil
|
||||
transition.updateAlpha(node: toolbarNode, alpha: 0.0, completion: { [weak toolbarNode] _ in
|
||||
toolbarNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
|
||||
return params.layout.size.height - tabBarFrame.minY
|
||||
|
||||
@@ -93,9 +93,11 @@ open class TabBarControllerImpl: ViewController, TabBarController {
|
||||
private let pendingControllerDisposable = MetaDisposable()
|
||||
|
||||
private var theme: PresentationTheme
|
||||
private var strings: PresentationStrings
|
||||
|
||||
public init(theme: PresentationTheme) {
|
||||
public init(theme: PresentationTheme, strings: PresentationStrings) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
|
||||
super.init(navigationBarPresentationData: nil)
|
||||
|
||||
@@ -152,7 +154,7 @@ open class TabBarControllerImpl: ViewController, TabBarController {
|
||||
}
|
||||
|
||||
override open func loadDisplayNode() {
|
||||
self.displayNode = TabBarControllerNode(theme: self.theme, itemSelected: { [weak self] index, longTap, itemNodes in
|
||||
self.displayNode = TabBarControllerNode(theme: self.theme, strings: self.strings, itemSelected: { [weak self] index, longTap, itemNodes in
|
||||
if let strongSelf = self {
|
||||
if longTap, let controller = strongSelf.controllers[index] as? TabBarContainedController {
|
||||
controller.presentTabBarPreviewingController(sourceNodes: itemNodes)
|
||||
@@ -235,6 +237,16 @@ open class TabBarControllerImpl: ViewController, TabBarController {
|
||||
self?.currentController?.toolbarActionSelected(action: action)
|
||||
}, disabledPressed: { [weak self] in
|
||||
self?.currentController?.tabBarDisabledAction()
|
||||
}, activateSearch: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.currentController?.tabBarActivateSearch()
|
||||
}, deactivateSearch: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.currentController?.tabBarDeactivateSearch()
|
||||
})
|
||||
|
||||
self.updateSelectedIndex()
|
||||
@@ -263,7 +275,8 @@ open class TabBarControllerImpl: ViewController, TabBarController {
|
||||
}
|
||||
if let currentController = self.currentController {
|
||||
currentController.willMove(toParent: nil)
|
||||
//self.tabBarControllerNode.currentControllerNode = nil
|
||||
currentController.tabBarSearchStateUpdated = nil
|
||||
currentController.currentTabBarSearchNode = nil
|
||||
|
||||
if animated {
|
||||
currentController.view.layer.animateScale(from: 1.0, to: transitionScale, duration: 0.12, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { completed in
|
||||
@@ -286,7 +299,7 @@ open class TabBarControllerImpl: ViewController, TabBarController {
|
||||
currentController.willMove(toParent: self)
|
||||
self.addChild(currentController)
|
||||
|
||||
let commit = self.tabBarControllerNode.setCurrentControllerNode(currentController.displayNode)
|
||||
let commit = self.tabBarControllerNode.setCurrentController(currentController)
|
||||
if animated {
|
||||
currentController.view.layer.animateScale(from: transitionScale, to: 1.0, duration: 0.15, delay: 0.1, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
currentController.view.layer.allowsGroupOpacity = true
|
||||
@@ -303,6 +316,22 @@ open class TabBarControllerImpl: ViewController, TabBarController {
|
||||
|
||||
currentController.displayNode.recursivelyEnsureDisplaySynchronously(true)
|
||||
self.statusBar.statusBarStyle = currentController.statusBar.statusBarStyle
|
||||
|
||||
currentController.tabBarSearchStateUpdated = { [weak self] transition in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let layout = self.validLayout {
|
||||
self.containerLayoutUpdated(layout, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
currentController.currentTabBarSearchNode = { [weak self] in
|
||||
guard let self else {
|
||||
return nil
|
||||
}
|
||||
return self.tabBarControllerNode.currentSearchNode
|
||||
}
|
||||
}
|
||||
|
||||
if let layout = self.validLayout {
|
||||
|
||||
Reference in New Issue
Block a user