mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-07-25 17:00:50 +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:
@@ -95,6 +95,8 @@ swift_library(
|
||||
"//submodules/TelegramCallsUI",
|
||||
"//submodules/TelegramUI/Components/Stories/StoryContainerScreen",
|
||||
"//submodules/TelegramUI/Components/ChatEntityKeyboardInputNode",
|
||||
"//submodules/TelegramUI/Components/LiquidLens",
|
||||
"//submodules/TelegramUI/Components/TabSelectionRecognizer",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
@@ -2097,7 +2097,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
if !isSticker, case .none = component.cameraState.recording, component.cameraState.isStreaming == .none && !state.isTransitioning && hasAllRequiredAccess && component.cameraState.collageProgress < 1.0 - .ulpOfOne {
|
||||
let availableModeControlSize: CGSize
|
||||
if isTablet {
|
||||
availableModeControlSize = CGSize(width: panelWidth, height: 120.0)
|
||||
availableModeControlSize = CGSize(width: floor(panelWidth), height: 120.0)
|
||||
} else {
|
||||
availableModeControlSize = availableSize
|
||||
}
|
||||
@@ -2131,7 +2131,6 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
modeControlPosition = CGPoint(x: availableSize.width / 2.0, y: availableSize.height - environment.safeInsets.bottom + modeControl.size.height / 2.0 + controlsBottomInset + 16.0)
|
||||
}
|
||||
context.add(modeControl
|
||||
.clipsToBounds(true)
|
||||
.position(modeControlPosition)
|
||||
.appear(.default(alpha: true))
|
||||
.disappear(.default(alpha: true))
|
||||
|
||||
@@ -5,6 +5,8 @@ import ComponentFlow
|
||||
import MultilineTextComponent
|
||||
import TelegramPresentationData
|
||||
import GlassBackgroundComponent
|
||||
import LiquidLens
|
||||
import TabSelectionRecognizer
|
||||
|
||||
extension CameraMode {
|
||||
func title(strings: PresentationStrings) -> String {
|
||||
@@ -70,28 +72,17 @@ final class ModeComponent: Component {
|
||||
|
||||
final class View: UIView, ComponentTaggedView {
|
||||
private var component: ModeComponent?
|
||||
private var state: EmptyComponentState?
|
||||
|
||||
final class ItemView: HighlightTrackingButton {
|
||||
var pressed: () -> Void = {
|
||||
|
||||
}
|
||||
|
||||
init() {
|
||||
super.init(frame: .zero)
|
||||
|
||||
self.isExclusiveTouch = true
|
||||
|
||||
self.addTarget(self, action: #selector(self.buttonPressed), for: .touchUpInside)
|
||||
}
|
||||
|
||||
required init(coder: NSCoder) {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
self.pressed()
|
||||
}
|
||||
|
||||
func update(isTablet: Bool, value: String, selected: Bool, tintColor: UIColor) -> CGSize {
|
||||
let accentColor: UIColor
|
||||
let normalColor: UIColor
|
||||
@@ -113,9 +104,15 @@ final class ModeComponent: Component {
|
||||
}
|
||||
|
||||
private var backgroundView = UIView()
|
||||
private var glassContainerView = GlassBackgroundContainerView()
|
||||
private var selectionView = GlassBackgroundView()
|
||||
private var itemViews: [Int32: ItemView] = [:]
|
||||
private var backgroundContainer = GlassBackgroundContainerView()
|
||||
|
||||
private var liquidLensView: LiquidLensView?
|
||||
|
||||
private var itemViews: [AnyHashable: ItemView] = [:]
|
||||
private var selectedItemViews: [AnyHashable: ItemView] = [:]
|
||||
|
||||
private var tabSelectionRecognizer: TabSelectionRecognizer?
|
||||
private var selectionGestureState: (startX: CGFloat, currentX: CGFloat, itemId: AnyHashable)?
|
||||
|
||||
public func matches(tag: Any) -> Bool {
|
||||
if let component = self.component, let componentTag = component.tag {
|
||||
@@ -132,12 +129,11 @@ final class ModeComponent: Component {
|
||||
|
||||
self.backgroundView.backgroundColor = UIColor(rgb: 0xffffff, alpha: 0.11)
|
||||
self.backgroundView.layer.cornerRadius = 24.0
|
||||
|
||||
|
||||
self.layer.allowsGroupOpacity = true
|
||||
|
||||
self.addSubview(self.backgroundView)
|
||||
self.backgroundView.addSubview(self.glassContainerView)
|
||||
self.glassContainerView.contentView.addSubview(self.selectionView)
|
||||
self.backgroundView.addSubview(self.backgroundContainer)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
@@ -162,14 +158,82 @@ final class ModeComponent: Component {
|
||||
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||
return self.backgroundView.frame.contains(point)
|
||||
}
|
||||
|
||||
func update(component: ModeComponent, availableSize: CGSize, transition: ComponentTransition) -> CGSize {
|
||||
self.component = component
|
||||
|
||||
let isTablet = component.isTablet
|
||||
let updatedMode = component.updatedMode
|
||||
private func item(at point: CGPoint) -> AnyHashable? {
|
||||
var closestItem: (AnyHashable, CGFloat)?
|
||||
for (id, itemView) in self.itemViews {
|
||||
if itemView.frame.contains(point) {
|
||||
return id
|
||||
} else {
|
||||
let distance = abs(point.x - itemView.center.x)
|
||||
if let closestItemValue = closestItem {
|
||||
if closestItemValue.1 > distance {
|
||||
closestItem = (id, distance)
|
||||
}
|
||||
} else {
|
||||
closestItem = (id, distance)
|
||||
}
|
||||
}
|
||||
}
|
||||
return closestItem?.0
|
||||
}
|
||||
|
||||
@objc private func onTabSelectionGesture(_ recognizer: TabSelectionRecognizer) {
|
||||
guard let component = self.component, let liquidLensView = self.liquidLensView else {
|
||||
return
|
||||
}
|
||||
let location = recognizer.location(in: liquidLensView.contentView)
|
||||
switch recognizer.state {
|
||||
case .began:
|
||||
if let itemId = self.item(at: location), let itemView = self.itemViews[itemId] {
|
||||
let startX = itemView.frame.minX - 4.0
|
||||
self.selectionGestureState = (startX, startX, itemId)
|
||||
self.state?.updated(transition: .spring(duration: 0.4), isLocal: true)
|
||||
}
|
||||
case .changed:
|
||||
if var selectionGestureState = self.selectionGestureState {
|
||||
selectionGestureState.currentX = selectionGestureState.startX + recognizer.translation(in: self).x
|
||||
if let itemId = self.item(at: location) {
|
||||
selectionGestureState.itemId = itemId
|
||||
}
|
||||
self.selectionGestureState = selectionGestureState
|
||||
self.state?.updated(transition: .immediate, isLocal: true)
|
||||
}
|
||||
case .ended, .cancelled:
|
||||
if let selectionGestureState = self.selectionGestureState {
|
||||
self.selectionGestureState = nil
|
||||
if case .ended = recognizer.state {
|
||||
guard let item = component.availableModes.first(where: { AnyHashable($0.rawValue) == selectionGestureState.itemId }) else {
|
||||
return
|
||||
}
|
||||
component.updatedMode(item)
|
||||
}
|
||||
self.state?.updated(transition: .spring(duration: 0.4), isLocal: true)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func update(component: ModeComponent, availableSize: CGSize, state: EmptyComponentState, transition: ComponentTransition) -> CGSize {
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
let isTablet = component.isTablet
|
||||
|
||||
let liquidLensView: LiquidLensView
|
||||
if let current = self.liquidLensView {
|
||||
liquidLensView = current
|
||||
} else {
|
||||
liquidLensView = LiquidLensView(kind: isTablet ? .noContainer : .externalContainer)
|
||||
self.liquidLensView = liquidLensView
|
||||
self.backgroundContainer.contentView.addSubview(liquidLensView)
|
||||
|
||||
let tabSelectionRecognizer = TabSelectionRecognizer(target: self, action: #selector(self.onTabSelectionGesture(_:)))
|
||||
self.tabSelectionRecognizer = tabSelectionRecognizer
|
||||
liquidLensView.addGestureRecognizer(tabSelectionRecognizer)
|
||||
}
|
||||
|
||||
self.glassContainerView.isHidden = component.isTablet
|
||||
self.backgroundView.backgroundColor = component.isTablet ? .clear : UIColor(rgb: 0xffffff, alpha: 0.11)
|
||||
|
||||
let inset: CGFloat = 23.0
|
||||
@@ -177,28 +241,36 @@ final class ModeComponent: Component {
|
||||
|
||||
var i = 0
|
||||
var itemFrame = CGRect(origin: isTablet ? .zero : CGPoint(x: inset, y: 0.0), size: buttonSize)
|
||||
var selectedCenter = itemFrame.minX
|
||||
var selectedFrame = itemFrame
|
||||
|
||||
var validKeys: Set<Int32> = Set()
|
||||
var validKeys: Set<AnyHashable> = Set()
|
||||
for mode in component.availableModes.reversed() {
|
||||
let id = mode.rawValue
|
||||
validKeys.insert(id)
|
||||
|
||||
let itemView: ItemView
|
||||
if let current = self.itemViews[id] {
|
||||
let selectedItemView: ItemView
|
||||
if let current = self.itemViews[id], let currentSelected = self.selectedItemViews[id] {
|
||||
itemView = current
|
||||
selectedItemView = currentSelected
|
||||
} else {
|
||||
itemView = ItemView()
|
||||
self.backgroundView.addSubview(itemView)
|
||||
itemView.isUserInteractionEnabled = false
|
||||
self.itemViews[id] = itemView
|
||||
}
|
||||
itemView.pressed = {
|
||||
updatedMode(mode)
|
||||
liquidLensView.contentView.addSubview(itemView)
|
||||
|
||||
selectedItemView = ItemView()
|
||||
selectedItemView.isUserInteractionEnabled = false
|
||||
self.selectedItemViews[id] = selectedItemView
|
||||
liquidLensView.selectedContentView.addSubview(selectedItemView)
|
||||
}
|
||||
|
||||
let itemSize = itemView.update(isTablet: component.isTablet, value: mode.title(strings: component.strings), selected: mode == component.currentMode, tintColor: component.tintColor)
|
||||
let itemSize = itemView.update(isTablet: component.isTablet, value: mode.title(strings: component.strings), selected: false, tintColor: component.tintColor)
|
||||
itemView.bounds = CGRect(origin: .zero, size: itemSize)
|
||||
|
||||
let _ = selectedItemView.update(isTablet: component.isTablet, value: mode.title(strings: component.strings), selected: true, tintColor: component.tintColor)
|
||||
selectedItemView.bounds = CGRect(origin: .zero, size: itemSize)
|
||||
|
||||
itemFrame = CGRect(origin: itemFrame.origin, size: itemSize)
|
||||
|
||||
if mode == component.currentMode {
|
||||
@@ -207,21 +279,17 @@ final class ModeComponent: Component {
|
||||
|
||||
if isTablet {
|
||||
itemView.center = CGPoint(x: availableSize.width / 2.0, y: itemFrame.midY)
|
||||
if mode == component.currentMode {
|
||||
selectedCenter = itemFrame.midY
|
||||
}
|
||||
selectedItemView.center = itemView.center
|
||||
itemFrame = itemFrame.offsetBy(dx: 0.0, dy: tabletButtonSize.height + spacing)
|
||||
} else {
|
||||
itemView.center = CGPoint(x: itemFrame.midX, y: itemFrame.midY)
|
||||
if mode == component.currentMode {
|
||||
selectedCenter = itemFrame.midX
|
||||
}
|
||||
selectedItemView.center = itemView.center
|
||||
itemFrame = itemFrame.offsetBy(dx: itemFrame.width + spacing, dy: 0.0)
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
|
||||
var removeKeys: [Int32] = []
|
||||
var removeKeys: [AnyHashable] = []
|
||||
for (id, itemView) in self.itemViews {
|
||||
if !validKeys.contains(id) {
|
||||
removeKeys.append(id)
|
||||
@@ -237,10 +305,12 @@ final class ModeComponent: Component {
|
||||
|
||||
let totalSize: CGSize
|
||||
let size: CGSize
|
||||
var cornerRadius: CGFloat?
|
||||
if isTablet {
|
||||
totalSize = CGSize(width: availableSize.width, height: tabletButtonSize.height * CGFloat(component.availableModes.count) + spacing * CGFloat(component.availableModes.count - 1))
|
||||
size = CGSize(width: availableSize.width, height: availableSize.height)
|
||||
transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(x: 0.0, y: availableSize.height / 2.0 - selectedCenter), size: totalSize))
|
||||
transition.setFrame(view: self.backgroundView, frame: CGRect(origin: .zero, size: totalSize))
|
||||
cornerRadius = 20.0
|
||||
} else {
|
||||
size = CGSize(width: availableSize.width, height: buttonSize.height)
|
||||
totalSize = CGSize(width: itemFrame.minX - spacing + inset, height: buttonSize.height)
|
||||
@@ -248,12 +318,26 @@ final class ModeComponent: Component {
|
||||
}
|
||||
|
||||
let containerFrame = CGRect(origin: .zero, size: self.backgroundView.frame.size)
|
||||
transition.setFrame(view: self.glassContainerView, frame: containerFrame)
|
||||
transition.setFrame(view: self.backgroundContainer, frame: containerFrame)
|
||||
|
||||
let selectionFrame = selectedFrame.insetBy(dx: -20.0, dy: 3.0)
|
||||
self.glassContainerView.update(size: containerFrame.size, isDark: true, transition: .immediate)
|
||||
self.selectionView.update(size: selectionFrame.size, cornerRadius: selectionFrame.height * 0.5, isDark: true, tintColor: .init(kind: .custom, color: UIColor(rgb: 0xffffff, alpha: 0.16)), transition: transition)
|
||||
transition.setFrame(view: self.selectionView, frame: selectionFrame)
|
||||
let selectionFrame = selectedFrame.insetBy(dx: -23.0, dy: 3.0)
|
||||
var lensSelection: (origin: CGPoint, size: CGSize)
|
||||
if let selectionGestureState = self.selectionGestureState, !isTablet {
|
||||
lensSelection = (CGPoint(x: selectionGestureState.currentX, y: 0.0), selectionFrame.size)
|
||||
} else {
|
||||
lensSelection = (CGPoint(x: selectionFrame.minX, y: selectionFrame.minY), selectionFrame.size)
|
||||
}
|
||||
|
||||
if isTablet {
|
||||
lensSelection.size.width = size.width
|
||||
} else {
|
||||
lensSelection.size.height = containerFrame.size.height
|
||||
lensSelection.origin.y = 0.0
|
||||
}
|
||||
|
||||
transition.setFrame(view: liquidLensView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: containerFrame.size))
|
||||
liquidLensView.update(size: containerFrame.size, cornerRadius: cornerRadius, selectionOrigin: CGPoint(x: max(0.0, min(lensSelection.origin.x, containerFrame.size.width - lensSelection.size.width)), y: lensSelection.origin.y), selectionSize: lensSelection.size, inset: 3.0, isDark: true, isLifted: self.selectionGestureState != nil && !isTablet, isCollapsed: false, transition: transition)
|
||||
self.backgroundContainer.update(size: containerFrame.size, isDark: true, transition: .immediate)
|
||||
|
||||
return size
|
||||
}
|
||||
@@ -264,7 +348,7 @@ final class ModeComponent: Component {
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, transition: transition)
|
||||
return view.update(component: self, availableSize: availableSize, state: state, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user