mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-07-31 11:37:25 +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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user