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:
ichmagmaus 812
2026-02-23 23:04:32 +01:00
parent 703e291bcb
commit db53826061
1017 changed files with 62323 additions and 40545 deletions
@@ -58,36 +58,54 @@ private final class RestingBackgroundView: UIVisualEffectView {
}
public final class LiquidLensView: UIView {
public enum Kind {
case externalContainer
case builtinContainer
case noContainer
}
private struct Params: Equatable {
var size: CGSize
var selectionX: CGFloat
var selectionWidth: CGFloat
var cornerRadius: CGFloat?
var selectionOrigin: CGPoint
var selectionSize: CGSize
var inset: CGFloat
var liftedInset: CGFloat
var isDark: Bool
var isLifted: Bool
var isCollapsed: Bool
init(size: CGSize, selectionX: CGFloat, selectionWidth: CGFloat, isDark: Bool, isLifted: Bool) {
init(size: CGSize, cornerRadius: CGFloat?, selectionOrigin: CGPoint, selectionSize: CGSize, inset: CGFloat, liftedInset: CGFloat, isDark: Bool, isLifted: Bool, isCollapsed: Bool) {
self.size = size
self.selectionX = selectionX
self.selectionWidth = selectionWidth
self.cornerRadius = cornerRadius
self.selectionOrigin = selectionOrigin
self.selectionSize = selectionSize
self.inset = inset
self.liftedInset = liftedInset
self.isLifted = isLifted
self.isDark = isDark
self.isCollapsed = isCollapsed
}
}
private struct LensParams: Equatable {
var baseFrame: CGRect
var inset: CGFloat
var liftedInset: CGFloat
var isLifted: Bool
init(baseFrame: CGRect, isLifted: Bool) {
init(baseFrame: CGRect, inset: CGFloat, liftedInset: CGFloat, isLifted: Bool) {
self.baseFrame = baseFrame
self.inset = inset
self.liftedInset = liftedInset
self.isLifted = isLifted
}
}
private let containerView: UIView
private let backgroundContainerContainer: UIView
private let backgroundContainer: GlassBackgroundContainerView
private let backgroundView: GlassBackgroundView
private let backgroundContainer: GlassBackgroundContainerView?
private let genericBackgroundContainer: UIView?
private let backgroundView: GlassBackgroundView?
private var lensView: UIView?
private let liftedContainerView: UIView
public let contentView: UIView
@@ -109,34 +127,64 @@ public final class LiquidLensView: UIView {
private var liftedDisplayLink: SharedDisplayLinkDriver.Link?
public var selectionX: CGFloat? {
return self.params?.selectionX
public var selectionOrigin: CGPoint? {
return self.params?.selectionOrigin
}
public var selectionWidth: CGFloat? {
return self.params?.selectionWidth
public var selectionSize: CGSize? {
return self.params?.selectionSize
}
public private(set) var isAnimating: Bool = false {
didSet {
if self.isAnimating != oldValue {
self.onUpdatedIsAnimating?(self.isAnimating)
}
}
}
public var onUpdatedIsAnimating: ((Bool) -> Void)?
public var isLiftedAnimationCompleted: (() -> Void)?
override public init(frame: CGRect) {
public init(kind: Kind) {
self.containerView = UIView()
self.backgroundContainerContainer = UIView()
self.backgroundContainer = GlassBackgroundContainerView()
switch kind {
case .builtinContainer:
self.backgroundContainer = GlassBackgroundContainerView()
self.genericBackgroundContainer = nil
case .externalContainer, .noContainer:
self.backgroundContainer = nil
self.genericBackgroundContainer = UIView()
}
self.backgroundView = GlassBackgroundView()
if case .noContainer = kind {
self.backgroundView = nil
} else {
self.backgroundView = GlassBackgroundView()
}
self.contentView = UIView()
self.liftedContainerView = UIView()
self.restingBackgroundView = RestingBackgroundView()
super.init(frame: frame)
super.init(frame: CGRect())
self.backgroundContainerContainer.addSubview(self.backgroundContainer)
self.addSubview(self.backgroundContainerContainer)
self.backgroundContainer.contentView.addSubview(self.backgroundView)
self.backgroundView.contentView.addSubview(self.containerView)
if let backgroundContainer = self.backgroundContainer {
self.addSubview(backgroundContainer)
if let backgroundView = self.backgroundView {
backgroundContainer.contentView.addSubview(backgroundView)
backgroundView.contentView.addSubview(self.containerView)
}
} else if let genericBackgroundContainer = self.genericBackgroundContainer {
self.addSubview(genericBackgroundContainer)
if let backgroundView = self.backgroundView {
genericBackgroundContainer.addSubview(backgroundView)
backgroundView.contentView.addSubview(self.containerView)
} else {
genericBackgroundContainer.addSubview(self.containerView)
}
}
self.containerView.isUserInteractionEnabled = false
if #available(iOS 26.0, *) {
@@ -150,7 +198,11 @@ public final class LiquidLensView: UIView {
}
if let lensView = self.lensView {
self.backgroundContainer.layer.zPosition = 1
if let backgroundContainer = self.backgroundContainer {
backgroundContainer.layer.zPosition = 1
} else if let genericBackgroundContainer = self.genericBackgroundContainer{
genericBackgroundContainer.layer.zPosition = 1
}
lensView.layer.zPosition = 10.0
self.liftedContainerView.addSubview(self.restingBackgroundView)
@@ -159,7 +211,11 @@ public final class LiquidLensView: UIView {
self.containerView.addSubview(lensView)
self.containerView.addSubview(self.contentView)
lensView.perform(NSSelectorFromString("setLiftedContainerView:"), with: self.backgroundContainer.contentView)
if let backgroundContainer = self.backgroundContainer {
lensView.perform(NSSelectorFromString("setLiftedContainerView:"), with: backgroundContainer.contentView)
} else if let genericBackgroundContainer = self.genericBackgroundContainer {
lensView.perform(NSSelectorFromString("setLiftedContainerView:"), with: genericBackgroundContainer)
}
lensView.perform(NSSelectorFromString("setLiftedContentView:"), with: self.liftedContainerView)
lensView.perform(NSSelectorFromString("setOverridePunchoutView:"), with: self.contentView)
@@ -194,7 +250,11 @@ public final class LiquidLensView: UIView {
} else {
let legacySelectionView = GlassBackgroundView.ContentImageView()
self.legacySelectionView = legacySelectionView
self.backgroundView.contentView.insertSubview(legacySelectionView, at: 0)
if let backgroundView = self.backgroundView {
backgroundView.contentView.insertSubview(legacySelectionView, at: 0)
} else {
self.containerView.insertSubview(legacySelectionView, at: 0)
}
let legacyContentMaskView = UIView()
legacyContentMaskView.backgroundColor = .white
@@ -222,9 +282,16 @@ public final class LiquidLensView: UIView {
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func setLiftedContainer(view: UIView) {
guard let lensView = self.lensView else {
return
}
lensView.perform(NSSelectorFromString("setLiftedContainerView:"), with: view)
}
public func update(size: CGSize, selectionX: CGFloat, selectionWidth: CGFloat, isDark: Bool, isLifted: Bool, transition: ComponentTransition) {
let params = Params(size: size, selectionX: selectionX, selectionWidth: selectionWidth, isDark: isDark, isLifted: isLifted)
public func update(size: CGSize, cornerRadius: CGFloat? = nil, selectionOrigin: CGPoint, selectionSize: CGSize, inset: CGFloat, liftedInset: CGFloat = 4.0, isDark: Bool, isLifted: Bool, isCollapsed: Bool = false, transition: ComponentTransition) {
let params = Params(size: size, cornerRadius: cornerRadius, selectionOrigin: selectionOrigin, selectionSize: selectionSize, inset: inset, liftedInset: liftedInset, isDark: isDark, isLifted: isLifted, isCollapsed: isCollapsed)
if self.params == params {
return
}
@@ -238,7 +305,7 @@ public final class LiquidLensView: UIView {
self.update(params: params, transition: transition)
}
private func updateLens(params: LensParams, animated: Bool) {
private func updateLens(params: LensParams, transition: ComponentTransition) {
guard let lensView = self.lensView else {
return
}
@@ -249,22 +316,23 @@ public final class LiquidLensView: UIView {
}
self.isApplyingLensParams = true
let previousParams = self.appliedLensParams
let transition: ComponentTransition = animated ? .easeInOut(duration: 0.3) : .immediate
self.appliedLensParams = params
if previousParams?.isLifted != params.isLifted {
self.isAnimating = true
let selector = NSSelectorFromString("setLifted:animated:alongsideAnimations:completion:")
var shouldScheduleUpdate = false
var didProcessUpdate = false
self.pendingLensParams = params
if let lensView = self.lensView, let method = lensView.method(for: selector) {
typealias ObjCMethod = @convention(c) (AnyObject, Selector, Bool, Bool, @escaping () -> Void, AnyObject?) -> Void
typealias ObjCMethod = @convention(c) (AnyObject, Selector, Bool, Bool, @escaping () -> Void, (() -> Void)?) -> Void
let function = unsafeBitCast(method, to: ObjCMethod.self)
function(lensView, selector, params.isLifted, !transition.animation.isImmediate, { [weak self] in
guard let self else {
return
}
let liftedInset: CGFloat = params.isLifted ? 4.0 : -4.0
let liftedInset: CGFloat = params.isLifted ? params.liftedInset : (-params.inset)
lensView.bounds = CGRect(origin: CGPoint(), size: CGSize(width: params.baseFrame.width + liftedInset * 2.0, height: params.baseFrame.height + liftedInset * 2.0))
didProcessUpdate = true
if shouldScheduleUpdate {
@@ -274,10 +342,18 @@ public final class LiquidLensView: UIView {
}
self.isApplyingLensParams = false
self.pendingLensParams = nil
self.updateLens(params: pendingLensParams, animated: !transition.animation.isImmediate)
self.updateLens(params: pendingLensParams, transition: transition)
}
}
}, nil)
}, { [weak self] in
guard let self else {
return
}
if !self.isApplyingLensParams {
self.isAnimating = false
}
self.isLiftedAnimationCompleted?()
})
}
if didProcessUpdate {
transition.animateView {
@@ -289,11 +365,32 @@ public final class LiquidLensView: UIView {
shouldScheduleUpdate = true
}
} else {
let liftedInset: CGFloat = params.isLifted ? params.liftedInset : (-params.inset)
let lensBounds = CGRect(origin: CGPoint(), size: CGSize(width: params.baseFrame.width + liftedInset * 2.0, height: params.baseFrame.height + liftedInset * 2.0))
let lensCenter = CGPoint(x: params.baseFrame.midX, y: params.baseFrame.midY)
let previousBounds: CGRect = lensView.bounds
transition.animateView {
let liftedInset: CGFloat = params.isLifted ? 4.0 : -4.0
lensView.bounds = CGRect(origin: CGPoint(), size: CGSize(width: params.baseFrame.width + liftedInset * 2.0, height: params.baseFrame.height + liftedInset * 2.0))
lensView.center = CGPoint(x: params.baseFrame.midX, y: params.baseFrame.midY)
lensView.bounds = lensBounds
}
lensView.layer.removeAllAnimations()
lensView.bounds = lensBounds
if !transition.animation.isImmediate {
self.isAnimating = true
}
transition.setPosition(view: lensView, position: lensCenter, completion: { [weak self] flag in
guard let self, flag else {
return
}
if !self.isApplyingLensParams {
self.isAnimating = false
}
})
// No idea why
transition.animatePosition(layer: lensView.layer, from: CGPoint(x: (lensBounds.width - previousBounds.width) * 0.5, y: 0.0), to: CGPoint(), additive: true)
self.isApplyingLensParams = false
}
}
@@ -319,25 +416,48 @@ public final class LiquidLensView: UIView {
self.params = params
transition.setFrame(view: self.containerView, frame: CGRect(origin: CGPoint(), size: params.size))
transition.setFrame(view: self.backgroundContainerContainer, frame: CGRect(origin: CGPoint(), size: params.size))
transition.setFrame(view: self.backgroundContainer, frame: CGRect(origin: CGPoint(), size: params.size))
self.backgroundContainer.update(size: params.size, isDark: params.isDark, transition: transition)
if let backgroundContainer = self.backgroundContainer {
transition.setFrame(view: backgroundContainer, frame: CGRect(origin: CGPoint(), size: params.size))
backgroundContainer.update(size: params.size, isDark: params.isDark, transition: transition)
} else if let genericBackgroundContainer = self.genericBackgroundContainer {
transition.setFrame(view: genericBackgroundContainer, frame: CGRect(origin: CGPoint(), size: params.size))
}
transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(), size: params.size))
self.backgroundView.update(size: params.size, cornerRadius: params.size.height * 0.5, isDark: params.isDark, tintColor: GlassBackgroundView.TintColor.init(kind: .panel, color: UIColor(white: params.isDark ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, transition: transition)
if let backgroundView = self.backgroundView {
transition.setFrame(view: backgroundView, frame: CGRect(origin: CGPoint(), size: params.size))
backgroundView.update(size: params.size, cornerRadius: params.cornerRadius ?? (params.size.height * 0.5), isDark: params.isDark, tintColor: GlassBackgroundView.TintColor.init(kind: .panel, color: UIColor(white: params.isDark ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, transition: transition)
}
transition.setFrame(view: self.contentView, frame: CGRect(origin: CGPoint(), size: params.size))
transition.setFrame(view: self.liftedContainerView, frame: CGRect(origin: CGPoint(), size: params.size))
if self.contentView.bounds.size != params.size {
self.contentView.clipsToBounds = true
transition.setFrame(view: self.contentView, frame: CGRect(origin: CGPoint(), size: params.size), completion: { [weak self] completed in
guard let self, completed else {
return
}
self.contentView.clipsToBounds = false
})
transition.setCornerRadius(layer: self.contentView.layer, cornerRadius: params.cornerRadius ?? (params.size.height * 0.5))
let baseLensFrame = CGRect(origin: CGPoint(x: max(0.0, min(params.selectionX, params.size.width - params.selectionWidth)), y: 0.0), size: CGSize(width: params.selectionWidth, height: params.size.height))
self.updateLens(params: LensParams(baseFrame: baseLensFrame, isLifted: params.isLifted), animated: !transition.animation.isImmediate)
self.liftedContainerView.clipsToBounds = true
transition.setFrame(view: self.liftedContainerView, frame: CGRect(origin: CGPoint(), size: params.size), completion: { [weak self] completed in
guard let self, completed else {
return
}
self.liftedContainerView.clipsToBounds = false
})
transition.setCornerRadius(layer: self.liftedContainerView.layer, cornerRadius: params.cornerRadius ?? (params.size.height * 0.5))
}
let baseLensFrame = CGRect(origin: params.selectionOrigin, size: params.selectionSize)
self.updateLens(params: LensParams(baseFrame: baseLensFrame, inset: params.inset, liftedInset: params.liftedInset, isLifted: params.isLifted), transition: transition)
if let legacyContentMaskView = self.legacyContentMaskView {
transition.setFrame(view: legacyContentMaskView, frame: CGRect(origin: CGPoint(), size: params.size))
}
if let legacyContentMaskBlobView = self.legacyContentMaskBlobView, let legacyLiftedContentBlobMaskView = self.legacyLiftedContentBlobMaskView, let legacySelectionView = self.legacySelectionView {
let lensFrame = baseLensFrame.insetBy(dx: 4.0, dy: 4.0)
let lensFrame = baseLensFrame.insetBy(dx: params.inset, dy: params.inset)
let effectiveLensFrame = lensFrame.insetBy(dx: params.isLifted ? -2.0 : 0.0, dy: params.isLifted ? -2.0 : 0.0)
if legacyContentMaskBlobView.image?.size.height != lensFrame.height {
@@ -354,7 +474,7 @@ public final class LiquidLensView: UIView {
transition.setFrame(view: self.restingBackgroundView, frame: CGRect(origin: CGPoint(), size: params.size))
self.restingBackgroundView.update(isDark: params.isDark)
transition.setAlpha(view: self.restingBackgroundView, alpha: params.isLifted ? 0.0 : 1.0)
transition.setAlpha(view: self.restingBackgroundView, alpha: (params.isLifted || params.isCollapsed) ? 0.0 : 1.0)
if params.isLifted {
if self.liftedDisplayLink == nil {