mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-08-18 20:07:15 +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:
@@ -23,6 +23,8 @@ swift_library(
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/TelegramUI/Components/LottieComponent",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
+23
-27
@@ -14,6 +14,7 @@ import TelegramStringFormatting
|
||||
import BundleIconComponent
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import GlassBarButtonComponent
|
||||
|
||||
private final class BalanceNeededSheetContentComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
@@ -49,9 +50,7 @@ private final class BalanceNeededSheetContentComponent: Component {
|
||||
|
||||
private var component: BalanceNeededSheetContentComponent?
|
||||
private weak var state: EmptyComponentState?
|
||||
|
||||
private var cachedCloseImage: (UIImage, PresentationTheme)?
|
||||
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
@@ -71,28 +70,27 @@ private final class BalanceNeededSheetContentComponent: Component {
|
||||
|
||||
let sideInset: CGFloat = 16.0
|
||||
|
||||
let closeImage: UIImage
|
||||
if let (image, theme) = self.cachedCloseImage, theme === environment.theme {
|
||||
closeImage = image
|
||||
} else {
|
||||
closeImage = generateCloseButtonImage(backgroundColor: UIColor(rgb: 0x808084, alpha: 0.1), foregroundColor: environment.theme.actionSheet.inputClearButtonColor)!
|
||||
self.cachedCloseImage = (closeImage, environment.theme)
|
||||
}
|
||||
let closeButtonSize = self.closeButton.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(Button(
|
||||
content: AnyComponent(Image(image: closeImage)),
|
||||
action: { [weak self] in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component: AnyComponent(GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: environment.theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: environment.theme.overallDarkAppearance,
|
||||
state: .generic,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: environment.theme.chat.inputPanel.panelControlColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
component.dismiss()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 30.0, height: 30.0)
|
||||
containerSize: CGSize(width: 40.0, height: 40.0)
|
||||
)
|
||||
let closeButtonFrame = CGRect(origin: CGPoint(x: availableSize.width - closeButtonSize.width - 16.0, y: 12.0), size: closeButtonSize)
|
||||
let closeButtonFrame = CGRect(origin: CGPoint(x: 16.0, y: 16.0), size: closeButtonSize)
|
||||
if let closeButtonView = self.closeButton.view {
|
||||
if closeButtonView.superview == nil {
|
||||
self.addSubview(closeButtonView)
|
||||
@@ -164,10 +162,12 @@ private final class BalanceNeededSheetContentComponent: Component {
|
||||
contentHeight += textSize.height
|
||||
contentHeight += 24.0
|
||||
|
||||
let buttonInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
|
||||
let buttonSize = self.button.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
style: .glass,
|
||||
color: environment.theme.list.itemCheckColors.fillColor,
|
||||
foreground: environment.theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.8)
|
||||
@@ -187,9 +187,9 @@ private final class BalanceNeededSheetContentComponent: Component {
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 50.0)
|
||||
containerSize: CGSize(width: availableSize.width - buttonInsets.left - buttonInsets.right, height: 52.0)
|
||||
)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: buttonSize)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: buttonInsets.left, y: contentHeight), size: buttonSize)
|
||||
if let buttonView = self.button.view {
|
||||
if buttonView.superview == nil {
|
||||
self.addSubview(buttonView)
|
||||
@@ -197,13 +197,8 @@ private final class BalanceNeededSheetContentComponent: Component {
|
||||
transition.setFrame(view: buttonView, frame: buttonFrame)
|
||||
}
|
||||
contentHeight += buttonSize.height
|
||||
|
||||
if environment.safeInsets.bottom.isZero {
|
||||
contentHeight += 16.0
|
||||
} else {
|
||||
contentHeight += environment.safeInsets.bottom + 8.0
|
||||
}
|
||||
|
||||
contentHeight += buttonInsets.bottom
|
||||
|
||||
return CGSize(width: availableSize.width, height: contentHeight)
|
||||
}
|
||||
}
|
||||
@@ -307,6 +302,7 @@ private final class BalanceNeededScreenComponent: Component {
|
||||
})
|
||||
}
|
||||
)),
|
||||
style: .glass,
|
||||
backgroundColor: .color(environment.theme.actionSheet.opaqueItemBackgroundColor),
|
||||
animateOut: self.sheetAnimateOut
|
||||
)),
|
||||
|
||||
+31
-44
@@ -504,6 +504,7 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
let context: AccountContext
|
||||
let overNavigationContainer: UIView
|
||||
let starsContext: StarsContext
|
||||
let options: [Any]
|
||||
let purpose: StarsPurchasePurpose
|
||||
@@ -515,6 +516,7 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
overNavigationContainer: UIView,
|
||||
starsContext: StarsContext,
|
||||
options: [Any],
|
||||
purpose: StarsPurchasePurpose,
|
||||
@@ -525,6 +527,7 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
|
||||
completion: @escaping (Int64) -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.overNavigationContainer = overNavigationContainer
|
||||
self.starsContext = starsContext
|
||||
self.options = options
|
||||
self.purpose = purpose
|
||||
@@ -759,8 +762,6 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
|
||||
let scrollContent = Child(ScrollComponent<EnvironmentType>.self)
|
||||
let star = Child(PremiumStarComponent.self)
|
||||
let avatar = Child(GiftAvatarComponent.self)
|
||||
let topPanel = Child(BlurredBackgroundComponent.self)
|
||||
let topSeparator = Child(Rectangle.self)
|
||||
let title = Child(MultilineTextComponent.self)
|
||||
let balanceTitle = Child(MultilineTextComponent.self)
|
||||
let balanceValue = Child(MultilineTextComponent.self)
|
||||
@@ -816,29 +817,13 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
|
||||
UIColor(rgb: 0xfdd219)
|
||||
],
|
||||
particleColor: UIColor(rgb: 0xf9b004),
|
||||
backgroundColor: environment.theme.list.blocksBackgroundColor
|
||||
backgroundColor: nil
|
||||
),
|
||||
availableSize: CGSize(width: min(414.0, context.availableSize.width), height: 220.0),
|
||||
transition: context.transition
|
||||
)
|
||||
}
|
||||
|
||||
let topPanel = topPanel.update(
|
||||
component: BlurredBackgroundComponent(
|
||||
color: environment.theme.rootController.navigationBar.blurredBackgroundColor
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width, height: environment.navigationHeight),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let topSeparator = topSeparator.update(
|
||||
component: Rectangle(
|
||||
color: environment.theme.rootController.navigationBar.separatorColor
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width, height: UIScreenPixel),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let titleText: String
|
||||
switch context.component.purpose {
|
||||
case .generic:
|
||||
@@ -948,14 +933,12 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height / 2.0))
|
||||
)
|
||||
|
||||
let topPanelAlpha: CGFloat
|
||||
let titleOffset: CGFloat
|
||||
let titleScale: CGFloat
|
||||
let titleOffsetDelta = (topInset + 160.0) - (environment.statusBarHeight + (environment.navigationHeight - environment.statusBarHeight) / 2.0)
|
||||
let titleAlpha: CGFloat
|
||||
|
||||
if let topContentOffset = state.topContentOffset {
|
||||
topPanelAlpha = min(20.0, max(0.0, topContentOffset - 95.0)) / 20.0
|
||||
let topContentOffset = topContentOffset + max(0.0, min(1.0, topContentOffset / titleOffsetDelta)) * 10.0
|
||||
titleOffset = topContentOffset
|
||||
let fraction = max(0.0, min(1.0, titleOffset / titleOffsetDelta))
|
||||
@@ -963,42 +946,37 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
|
||||
|
||||
titleAlpha = 1.0
|
||||
} else {
|
||||
topPanelAlpha = 0.0
|
||||
titleScale = 1.0
|
||||
titleOffset = 0.0
|
||||
titleAlpha = 1.0
|
||||
}
|
||||
|
||||
context.add(header
|
||||
context.addWithExternalContainer(header
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: topInset + header.size.height / 2.0 - 30.0 - titleOffset * titleScale))
|
||||
.scale(titleScale)
|
||||
.scale(titleScale),
|
||||
container: context.component.overNavigationContainer
|
||||
)
|
||||
|
||||
context.add(topPanel
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: topPanel.size.height / 2.0))
|
||||
.opacity(topPanelAlpha)
|
||||
)
|
||||
context.add(topSeparator
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: topPanel.size.height))
|
||||
.opacity(topPanelAlpha)
|
||||
)
|
||||
|
||||
context.add(title
|
||||
context.addWithExternalContainer(title
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: max(topInset + 160.0 - titleOffset, environment.statusBarHeight + (environment.navigationHeight - environment.statusBarHeight) / 2.0)))
|
||||
.scale(titleScale)
|
||||
.opacity(titleAlpha)
|
||||
.opacity(titleAlpha),
|
||||
container: context.component.overNavigationContainer
|
||||
)
|
||||
|
||||
let navigationHeight = environment.navigationHeight - environment.statusBarHeight
|
||||
let topBalanceOriginY = environment.statusBarHeight + (navigationHeight - balanceTitle.size.height - balanceValue.size.height) / 2.0
|
||||
context.add(balanceTitle
|
||||
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.right - balanceTitle.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height / 2.0))
|
||||
context.addWithExternalContainer(balanceTitle
|
||||
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.right - balanceTitle.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height / 2.0)),
|
||||
container: context.component.overNavigationContainer
|
||||
)
|
||||
context.add(balanceValue
|
||||
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.right - balanceValue.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0))
|
||||
context.addWithExternalContainer(balanceValue
|
||||
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.right - balanceValue.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0)),
|
||||
container: context.component.overNavigationContainer
|
||||
)
|
||||
context.add(balanceIcon
|
||||
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.right - balanceValue.size.width - balanceIcon.size.width / 2.0 - 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0 - UIScreenPixel))
|
||||
context.addWithExternalContainer(balanceIcon
|
||||
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.right - balanceValue.size.width - balanceIcon.size.width / 2.0 - 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0 - UIScreenPixel)),
|
||||
container: context.component.overNavigationContainer
|
||||
)
|
||||
|
||||
return context.availableSize
|
||||
@@ -1010,6 +988,8 @@ public final class StarsPurchaseScreen: ViewControllerComponentContainer {
|
||||
fileprivate let context: AccountContext
|
||||
fileprivate let starsContext: StarsContext
|
||||
|
||||
private let overNavigationContainer: UIView
|
||||
|
||||
private var didSetReady = false
|
||||
private let _ready = Promise<Bool>()
|
||||
public override var ready: Promise<Bool> {
|
||||
@@ -1027,6 +1007,8 @@ public final class StarsPurchaseScreen: ViewControllerComponentContainer {
|
||||
) {
|
||||
self.context = context
|
||||
self.starsContext = starsContext
|
||||
|
||||
self.overNavigationContainer = SparseContainerView()
|
||||
|
||||
var openAppExamplesImpl: (() -> Void)?
|
||||
var updateInProgressImpl: ((Bool) -> Void)?
|
||||
@@ -1034,6 +1016,7 @@ public final class StarsPurchaseScreen: ViewControllerComponentContainer {
|
||||
var completionImpl: ((Int64) -> Void)?
|
||||
super.init(context: context, component: StarsPurchaseScreenComponent(
|
||||
context: context,
|
||||
overNavigationContainer: self.overNavigationContainer,
|
||||
starsContext: starsContext,
|
||||
options: options,
|
||||
purpose: purpose,
|
||||
@@ -1050,7 +1033,7 @@ public final class StarsPurchaseScreen: ViewControllerComponentContainer {
|
||||
completion: { stars in
|
||||
completionImpl?(stars)
|
||||
}
|
||||
), navigationBarAppearance: .transparent, presentationMode: .modal, theme: customTheme.flatMap { .custom($0) } ?? .default)
|
||||
), navigationBarAppearance: .default, presentationMode: .modal, theme: customTheme.flatMap { .custom($0) } ?? .default)
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
@@ -1090,6 +1073,10 @@ public final class StarsPurchaseScreen: ViewControllerComponentContainer {
|
||||
completion(stars)
|
||||
}
|
||||
}
|
||||
|
||||
if let navigationBar = self.navigationBar {
|
||||
navigationBar.customOverBackgroundContentView.insertSubview(self.overNavigationContainer, at: 0)
|
||||
}
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
@@ -1129,10 +1116,10 @@ public final class StarsPurchaseScreen: ViewControllerComponentContainer {
|
||||
super.containerLayoutUpdated(layout, transition: transition)
|
||||
|
||||
if !self.didSetReady {
|
||||
if let view = self.node.hostView.findTaggedView(tag: PremiumStarComponent.View.Tag()) as? PremiumStarComponent.View {
|
||||
if let view = findTaggedComponentViewImpl(view: self.node.view, tag: PremiumStarComponent.View.Tag()) as? PremiumStarComponent.View {
|
||||
self.didSetReady = true
|
||||
self._ready.set(view.ready)
|
||||
} else if let view = self.node.hostView.findTaggedView(tag: GiftAvatarComponent.View.Tag()) as? GiftAvatarComponent.View {
|
||||
} else if let view = findTaggedComponentViewImpl(view: self.node.view, tag: GiftAvatarComponent.View.Tag()) as? GiftAvatarComponent.View {
|
||||
self.didSetReady = true
|
||||
self._ready.set(view.ready)
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ swift_library(
|
||||
"//submodules/TelegramUI/Components/Premium/PremiumStarComponent",
|
||||
"//submodules/TelegramUI/Components/Gifts/GiftAnimationComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
"//submodules/TelegramUI/Components/Gifts/TableComponent",
|
||||
"//submodules/TelegramUI/Components/Gifts/PeerTableCellComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
+16
-243
@@ -28,6 +28,8 @@ import MiniAppListScreen
|
||||
import PremiumStarComponent
|
||||
import GiftAnimationComponent
|
||||
import GlassBarButtonComponent
|
||||
import TableComponent
|
||||
import PeerTableCellComponent
|
||||
|
||||
private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
@@ -677,7 +679,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
tintColor: theme.chat.inputPanel.panelControlColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
@@ -936,9 +938,10 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
component: AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(
|
||||
PeerCellComponent(
|
||||
PeerTableCellComponent(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
strings: strings,
|
||||
peer: nil
|
||||
)
|
||||
),
|
||||
@@ -983,9 +986,10 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
id: AnyHashable(0),
|
||||
component: AnyComponent(Button(
|
||||
content: AnyComponent(
|
||||
PeerCellComponent(
|
||||
PeerTableCellComponent(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
strings: strings,
|
||||
peer: toPeer
|
||||
)
|
||||
),
|
||||
@@ -1026,9 +1030,10 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
toComponent = AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(
|
||||
PeerCellComponent(
|
||||
PeerTableCellComponent(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
strings: strings,
|
||||
peer: toPeer
|
||||
)
|
||||
),
|
||||
@@ -1164,9 +1169,10 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
component: AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(
|
||||
PeerCellComponent(
|
||||
PeerTableCellComponent(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
strings: strings,
|
||||
peer: toPeer
|
||||
)
|
||||
),
|
||||
@@ -1196,9 +1202,10 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
component: AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(
|
||||
PeerCellComponent(
|
||||
PeerTableCellComponent(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
strings: strings,
|
||||
peer: starRefPeer
|
||||
)
|
||||
),
|
||||
@@ -1227,9 +1234,10 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
component: AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(
|
||||
PeerCellComponent(
|
||||
PeerTableCellComponent(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
strings: strings,
|
||||
peer: toPeer
|
||||
)
|
||||
),
|
||||
@@ -1638,7 +1646,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
style: .glass,
|
||||
color: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.1),
|
||||
foreground: theme.list.itemCheckColors.fillColor,
|
||||
pressedColor: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.8),
|
||||
pressedColor: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.8)
|
||||
),
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable(0),
|
||||
@@ -2146,241 +2154,6 @@ public class StarsTransactionScreen: ViewControllerComponentContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private final class TableComponent: CombinedComponent {
|
||||
class Item: Equatable {
|
||||
public let id: AnyHashable
|
||||
public let title: String
|
||||
public let component: AnyComponent<Empty>
|
||||
public let insets: UIEdgeInsets?
|
||||
|
||||
public init<IdType: Hashable>(id: IdType, title: String, component: AnyComponent<Empty>, insets: UIEdgeInsets? = nil) {
|
||||
self.id = AnyHashable(id)
|
||||
self.title = title
|
||||
self.component = component
|
||||
self.insets = insets
|
||||
}
|
||||
|
||||
public static func == (lhs: Item, rhs: Item) -> Bool {
|
||||
if lhs.id != rhs.id {
|
||||
return false
|
||||
}
|
||||
if lhs.title != rhs.title {
|
||||
return false
|
||||
}
|
||||
if lhs.component != rhs.component {
|
||||
return false
|
||||
}
|
||||
if lhs.insets != rhs.insets {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private let theme: PresentationTheme
|
||||
private let items: [Item]
|
||||
|
||||
public init(theme: PresentationTheme, items: [Item]) {
|
||||
self.theme = theme
|
||||
self.items = items
|
||||
}
|
||||
|
||||
public static func ==(lhs: TableComponent, rhs: TableComponent) -> Bool {
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
if lhs.items != rhs.items {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
final class State: ComponentState {
|
||||
var cachedLeftColumnImage: (UIImage, PresentationTheme)?
|
||||
var cachedBorderImage: (UIImage, PresentationTheme)?
|
||||
}
|
||||
|
||||
func makeState() -> State {
|
||||
return State()
|
||||
}
|
||||
|
||||
public static var body: Body {
|
||||
let leftColumnBackground = Child(Image.self)
|
||||
let verticalBorder = Child(Rectangle.self)
|
||||
let titleChildren = ChildMap(environment: Empty.self, keyedBy: AnyHashable.self)
|
||||
let valueChildren = ChildMap(environment: Empty.self, keyedBy: AnyHashable.self)
|
||||
let borderChildren = ChildMap(environment: Empty.self, keyedBy: AnyHashable.self)
|
||||
let outerBorder = Child(Image.self)
|
||||
|
||||
return { context in
|
||||
let verticalPadding: CGFloat = 11.0
|
||||
let horizontalPadding: CGFloat = 12.0
|
||||
let borderWidth: CGFloat = 1.0
|
||||
let borderRadius: CGFloat = 14.0
|
||||
|
||||
let backgroundColor = context.component.theme.actionSheet.opaqueItemBackgroundColor
|
||||
let borderColor = backgroundColor.mixedWith(context.component.theme.list.itemBlocksSeparatorColor, alpha: 0.6)
|
||||
let secondaryBackgroundColor = context.component.theme.overallDarkAppearance ? context.component.theme.list.itemModalBlocksBackgroundColor : context.component.theme.list.itemInputField.backgroundColor
|
||||
|
||||
var leftColumnWidth: CGFloat = 0.0
|
||||
|
||||
var updatedTitleChildren: [_UpdatedChildComponent] = []
|
||||
var updatedValueChildren: [(_UpdatedChildComponent, UIEdgeInsets)] = []
|
||||
var updatedBorderChildren: [_UpdatedChildComponent] = []
|
||||
|
||||
for item in context.component.items {
|
||||
let titleChild = titleChildren[item.id].update(
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: item.title, font: Font.regular(15.0), textColor: context.component.theme.list.itemPrimaryTextColor))
|
||||
)),
|
||||
availableSize: context.availableSize,
|
||||
transition: context.transition
|
||||
)
|
||||
updatedTitleChildren.append(titleChild)
|
||||
|
||||
if titleChild.size.width > leftColumnWidth {
|
||||
leftColumnWidth = titleChild.size.width
|
||||
}
|
||||
}
|
||||
|
||||
leftColumnWidth = max(100.0, leftColumnWidth + horizontalPadding * 2.0)
|
||||
let rightColumnWidth = context.availableSize.width - leftColumnWidth
|
||||
|
||||
var i = 0
|
||||
var rowHeights: [Int: CGFloat] = [:]
|
||||
var totalHeight: CGFloat = 0.0
|
||||
|
||||
for item in context.component.items {
|
||||
let titleChild = updatedTitleChildren[i]
|
||||
|
||||
let insets: UIEdgeInsets
|
||||
if let customInsets = item.insets {
|
||||
insets = customInsets
|
||||
} else {
|
||||
insets = UIEdgeInsets(top: 0.0, left: horizontalPadding, bottom: 0.0, right: horizontalPadding)
|
||||
}
|
||||
let valueChild = valueChildren[item.id].update(
|
||||
component: item.component,
|
||||
availableSize: CGSize(width: rightColumnWidth - insets.left - insets.right, height: context.availableSize.height),
|
||||
transition: context.transition
|
||||
)
|
||||
updatedValueChildren.append((valueChild, insets))
|
||||
|
||||
let rowHeight = max(40.0, max(titleChild.size.height, valueChild.size.height) + verticalPadding * 2.0)
|
||||
rowHeights[i] = rowHeight
|
||||
totalHeight += rowHeight
|
||||
|
||||
if i < context.component.items.count - 1 {
|
||||
let borderChild = borderChildren[item.id].update(
|
||||
component: AnyComponent(Rectangle(color: borderColor)),
|
||||
availableSize: CGSize(width: context.availableSize.width, height: borderWidth),
|
||||
transition: context.transition
|
||||
)
|
||||
updatedBorderChildren.append(borderChild)
|
||||
}
|
||||
|
||||
i += 1
|
||||
}
|
||||
|
||||
let leftColumnImage: UIImage
|
||||
if let (currentImage, theme) = context.state.cachedLeftColumnImage, theme === context.component.theme {
|
||||
leftColumnImage = currentImage
|
||||
} else {
|
||||
leftColumnImage = generateImage(CGSize(width: borderRadius * 2.0 + 4.0, height: borderRadius * 2.0 + 4.0), rotatedContext: { size, context in
|
||||
let bounds = CGRect(origin: .zero, size: CGSize(width: size.width + borderRadius, height: size.height))
|
||||
context.clear(bounds)
|
||||
|
||||
let path = CGPath(roundedRect: bounds.insetBy(dx: borderWidth / 2.0, dy: borderWidth / 2.0), cornerWidth: borderRadius, cornerHeight: borderRadius, transform: nil)
|
||||
context.setFillColor(secondaryBackgroundColor.cgColor)
|
||||
context.addPath(path)
|
||||
context.fillPath()
|
||||
})!.stretchableImage(withLeftCapWidth: Int(borderRadius), topCapHeight: Int(borderRadius))
|
||||
context.state.cachedLeftColumnImage = (leftColumnImage, context.component.theme)
|
||||
}
|
||||
|
||||
let leftColumnBackground = leftColumnBackground.update(
|
||||
component: Image(image: leftColumnImage),
|
||||
availableSize: CGSize(width: leftColumnWidth, height: totalHeight),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(
|
||||
leftColumnBackground
|
||||
.position(CGPoint(x: leftColumnWidth / 2.0, y: totalHeight / 2.0))
|
||||
)
|
||||
|
||||
let borderImage: UIImage
|
||||
if let (currentImage, theme) = context.state.cachedBorderImage, theme === context.component.theme {
|
||||
borderImage = currentImage
|
||||
} else {
|
||||
borderImage = generateImage(CGSize(width: borderRadius * 2.0 + 4.0, height: borderRadius * 2.0 + 4.0), rotatedContext: { size, context in
|
||||
let bounds = CGRect(origin: .zero, size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
let path = CGPath(roundedRect: bounds.insetBy(dx: borderWidth / 2.0, dy: borderWidth / 2.0), cornerWidth: borderRadius, cornerHeight: borderRadius, transform: nil)
|
||||
context.setBlendMode(.clear)
|
||||
context.addPath(path)
|
||||
context.fillPath()
|
||||
|
||||
context.setBlendMode(.normal)
|
||||
context.setStrokeColor(borderColor.cgColor)
|
||||
context.setLineWidth(borderWidth)
|
||||
context.addPath(path)
|
||||
context.strokePath()
|
||||
})!.stretchableImage(withLeftCapWidth: Int(borderRadius), topCapHeight: Int(borderRadius))
|
||||
context.state.cachedBorderImage = (borderImage, context.component.theme)
|
||||
}
|
||||
|
||||
let outerBorder = outerBorder.update(
|
||||
component: Image(image: borderImage),
|
||||
availableSize: CGSize(width: context.availableSize.width, height: totalHeight),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(outerBorder
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: totalHeight / 2.0))
|
||||
)
|
||||
|
||||
let verticalBorder = verticalBorder.update(
|
||||
component: Rectangle(color: borderColor),
|
||||
availableSize: CGSize(width: borderWidth, height: totalHeight),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(
|
||||
verticalBorder
|
||||
.position(CGPoint(x: leftColumnWidth - borderWidth / 2.0, y: totalHeight / 2.0))
|
||||
)
|
||||
|
||||
i = 0
|
||||
var originY: CGFloat = 0.0
|
||||
for (titleChild, (valueChild, valueInsets)) in zip(updatedTitleChildren, updatedValueChildren) {
|
||||
let rowHeight = rowHeights[i] ?? 0.0
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: horizontalPadding, y: originY + verticalPadding), size: titleChild.size)
|
||||
let valueFrame = CGRect(origin: CGPoint(x: leftColumnWidth + valueInsets.left, y: originY + verticalPadding), size: valueChild.size)
|
||||
|
||||
context.add(titleChild
|
||||
.position(titleFrame.center)
|
||||
)
|
||||
|
||||
context.add(valueChild
|
||||
.position(valueFrame.center)
|
||||
)
|
||||
|
||||
if i < updatedBorderChildren.count {
|
||||
let borderChild = updatedBorderChildren[i]
|
||||
context.add(borderChild
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: originY + rowHeight - borderWidth / 2.0))
|
||||
)
|
||||
}
|
||||
|
||||
originY += rowHeight
|
||||
i += 1
|
||||
}
|
||||
|
||||
return CGSize(width: context.availableSize.width, height: totalHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class PeerCellComponent: Component {
|
||||
let context: AccountContext
|
||||
let theme: PresentationTheme
|
||||
|
||||
+15
-40
@@ -26,6 +26,7 @@ final class StarsStatisticsScreenComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
let context: AccountContext
|
||||
let overNavigationContainer: UIView
|
||||
let peerId: EnginePeer.Id
|
||||
let revenueContext: StarsRevenueStatsContext
|
||||
let openTransaction: (StarsContext.State.Transaction) -> Void
|
||||
@@ -36,6 +37,7 @@ final class StarsStatisticsScreenComponent: Component {
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
overNavigationContainer: UIView,
|
||||
peerId: EnginePeer.Id,
|
||||
revenueContext: StarsRevenueStatsContext,
|
||||
openTransaction: @escaping (StarsContext.State.Transaction) -> Void,
|
||||
@@ -45,6 +47,7 @@ final class StarsStatisticsScreenComponent: Component {
|
||||
buyAds: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.overNavigationContainer = overNavigationContainer
|
||||
self.peerId = peerId
|
||||
self.revenueContext = revenueContext
|
||||
self.openTransaction = openTransaction
|
||||
@@ -125,10 +128,6 @@ final class StarsStatisticsScreenComponent: Component {
|
||||
private let scrollView: ScrollViewImpl
|
||||
|
||||
private var currentSelectedPanelId: AnyHashable?
|
||||
|
||||
private let navigationBackgroundView: BlurredBackgroundView
|
||||
private let navigationSeparatorLayer: SimpleLayer
|
||||
private let navigationSeparatorLayerContainer: SimpleLayer
|
||||
|
||||
private let headerView = ComponentView<Empty>()
|
||||
private let headerOffsetContainer: UIView
|
||||
@@ -175,14 +174,6 @@ final class StarsStatisticsScreenComponent: Component {
|
||||
self.headerOffsetContainer = UIView()
|
||||
self.headerOffsetContainer.isUserInteractionEnabled = false
|
||||
|
||||
self.navigationBackgroundView = BlurredBackgroundView(color: nil, enableBlur: true)
|
||||
self.navigationBackgroundView.alpha = 0.0
|
||||
|
||||
self.navigationSeparatorLayer = SimpleLayer()
|
||||
self.navigationSeparatorLayer.opacity = 0.0
|
||||
self.navigationSeparatorLayerContainer = SimpleLayer()
|
||||
self.navigationSeparatorLayerContainer.opacity = 0.0
|
||||
|
||||
self.scrollContainerView = UIView()
|
||||
self.scrollView = ScrollViewImpl()
|
||||
|
||||
@@ -208,11 +199,6 @@ final class StarsStatisticsScreenComponent: Component {
|
||||
self.scrollView.addSubview(self.scrollContainerView)
|
||||
self.scrollContainerView.addSubview(self.transactionsBackground)
|
||||
|
||||
self.addSubview(self.navigationBackgroundView)
|
||||
|
||||
self.navigationSeparatorLayerContainer.addSublayer(self.navigationSeparatorLayer)
|
||||
self.layer.addSublayer(self.navigationSeparatorLayerContainer)
|
||||
|
||||
self.addSubview(self.headerOffsetContainer)
|
||||
}
|
||||
|
||||
@@ -307,18 +293,10 @@ final class StarsStatisticsScreenComponent: Component {
|
||||
let isLockedAtPanels = scrollBounds.maxY == self.scrollView.contentSize.height
|
||||
|
||||
if let _ = self.navigationMetrics {
|
||||
let topContentOffset = self.scrollView.contentOffset.y
|
||||
let navigationBackgroundAlpha = min(20.0, max(0.0, topContentOffset)) / 20.0
|
||||
|
||||
let animatedTransition = ComponentTransition(animation: .curve(duration: 0.18, curve: .easeInOut))
|
||||
animatedTransition.setAlpha(view: self.navigationBackgroundView, alpha: navigationBackgroundAlpha)
|
||||
animatedTransition.setAlpha(layer: self.navigationSeparatorLayerContainer, alpha: navigationBackgroundAlpha)
|
||||
|
||||
let expansionDistance: CGFloat = 32.0
|
||||
var expansionDistanceFactor: CGFloat = abs(scrollBounds.maxY - self.scrollView.contentSize.height) / expansionDistance
|
||||
expansionDistanceFactor = max(0.0, min(1.0, expansionDistanceFactor))
|
||||
|
||||
transition.setAlpha(layer: self.navigationSeparatorLayer, alpha: expansionDistanceFactor)
|
||||
if let panelContainerView = self.panelContainer.view as? StarsTransactionsPanelContainerComponent.View {
|
||||
panelContainerView.updateNavigationMergeFactor(value: 1.0 - expansionDistanceFactor, transition: transition)
|
||||
}
|
||||
@@ -417,19 +395,7 @@ final class StarsStatisticsScreenComponent: Component {
|
||||
self.controller = environment.controller
|
||||
|
||||
self.navigationMetrics = (environment.navigationHeight, environment.statusBarHeight)
|
||||
|
||||
self.navigationSeparatorLayer.backgroundColor = environment.theme.rootController.navigationBar.separatorColor.cgColor
|
||||
|
||||
let navigationFrame = CGRect(origin: CGPoint(), size: CGSize(width: availableSize.width, height: environment.navigationHeight))
|
||||
self.navigationBackgroundView.updateColor(color: environment.theme.rootController.navigationBar.blurredBackgroundColor, transition: .immediate)
|
||||
self.navigationBackgroundView.update(size: navigationFrame.size, transition: transition.containedViewLayoutTransition)
|
||||
transition.setFrame(view: self.navigationBackgroundView, frame: navigationFrame)
|
||||
|
||||
let navigationSeparatorFrame = CGRect(origin: CGPoint(x: 0.0, y: navigationFrame.maxY), size: CGSize(width: availableSize.width, height: UIScreenPixel))
|
||||
|
||||
transition.setFrame(layer: self.navigationSeparatorLayerContainer, frame: navigationSeparatorFrame)
|
||||
transition.setFrame(layer: self.navigationSeparatorLayer, frame: CGRect(origin: CGPoint(), size: navigationSeparatorFrame.size))
|
||||
|
||||
|
||||
self.backgroundColor = environment.theme.list.blocksBackgroundColor
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
@@ -454,7 +420,7 @@ final class StarsStatisticsScreenComponent: Component {
|
||||
)
|
||||
if let titleView = self.titleView.view {
|
||||
if titleView.superview == nil {
|
||||
self.addSubview(titleView)
|
||||
component.overNavigationContainer.addSubview(titleView)
|
||||
}
|
||||
let titlePosition = CGPoint(x: availableSize.width / 2.0, y: environment.statusBarHeight + (environment.navigationHeight - environment.statusBarHeight) / 2.0)
|
||||
transition.setPosition(view: titleView, position: titlePosition)
|
||||
@@ -847,6 +813,8 @@ public final class StarsStatisticsScreen: ViewControllerComponentContainer {
|
||||
private let peerId: EnginePeer.Id
|
||||
private let revenueContext: StarsRevenueStatsContext
|
||||
|
||||
private let overNavigationContainer: UIView
|
||||
|
||||
private weak var tooltipScreen: UndoOverlayController?
|
||||
private var timer: Foundation.Timer?
|
||||
|
||||
@@ -857,6 +825,8 @@ public final class StarsStatisticsScreen: ViewControllerComponentContainer {
|
||||
self.peerId = peerId
|
||||
self.revenueContext = revenueContext
|
||||
|
||||
self.overNavigationContainer = SparseContainerView()
|
||||
|
||||
var buyImpl: (() -> Void)?
|
||||
var withdrawImpl: (() -> Void)?
|
||||
var buyAdsImpl: (() -> Void)?
|
||||
@@ -864,6 +834,7 @@ public final class StarsStatisticsScreen: ViewControllerComponentContainer {
|
||||
var openTransactionImpl: ((StarsContext.State.Transaction) -> Void)?
|
||||
super.init(context: context, component: StarsStatisticsScreenComponent(
|
||||
context: context,
|
||||
overNavigationContainer: self.overNavigationContainer,
|
||||
peerId: peerId,
|
||||
revenueContext: revenueContext,
|
||||
openTransaction: { transaction in
|
||||
@@ -881,7 +852,7 @@ public final class StarsStatisticsScreen: ViewControllerComponentContainer {
|
||||
buyAds: {
|
||||
buyAdsImpl?()
|
||||
}
|
||||
), navigationBarAppearance: .transparent)
|
||||
), navigationBarAppearance: .default)
|
||||
|
||||
self.navigationPresentation = .modalInLargeLayout
|
||||
|
||||
@@ -1060,6 +1031,10 @@ public final class StarsStatisticsScreen: ViewControllerComponentContainer {
|
||||
}
|
||||
componentView.scrollToTop()
|
||||
}
|
||||
|
||||
if let navigationBar = self.navigationBar {
|
||||
navigationBar.customOverBackgroundContentView.insertSubview(self.overNavigationContainer, at: 0)
|
||||
}
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
|
||||
+34
-43
@@ -102,10 +102,6 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
private let scrollView: ScrollViewImpl
|
||||
|
||||
private var currentSelectedPanelId: AnyHashable?
|
||||
|
||||
private let navigationBackgroundView: BlurredBackgroundView
|
||||
private let navigationSeparatorLayer: SimpleLayer
|
||||
private let navigationSeparatorLayerContainer: SimpleLayer
|
||||
|
||||
private let scrollContainerView: UIView
|
||||
|
||||
@@ -160,14 +156,6 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
private var cachedChevronImage: (UIImage, PresentationTheme)?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.navigationBackgroundView = BlurredBackgroundView(color: nil, enableBlur: true)
|
||||
self.navigationBackgroundView.alpha = 0.0
|
||||
|
||||
self.navigationSeparatorLayer = SimpleLayer()
|
||||
self.navigationSeparatorLayer.opacity = 0.0
|
||||
self.navigationSeparatorLayerContainer = SimpleLayer()
|
||||
self.navigationSeparatorLayerContainer.opacity = 0.0
|
||||
|
||||
self.scrollContainerView = UIView()
|
||||
self.scrollView = ScrollViewImpl()
|
||||
|
||||
@@ -191,11 +179,6 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
self.addSubview(self.scrollView)
|
||||
|
||||
self.scrollView.addSubview(self.scrollContainerView)
|
||||
|
||||
self.addSubview(self.navigationBackgroundView)
|
||||
|
||||
self.navigationSeparatorLayerContainer.addSublayer(self.navigationSeparatorLayer)
|
||||
self.layer.addSublayer(self.navigationSeparatorLayerContainer)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
@@ -296,7 +279,6 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
|
||||
var topContentOffset = self.scrollView.contentOffset.y
|
||||
|
||||
let navigationBackgroundAlpha = min(20.0, max(0.0, topContentOffset - 95.0)) / 20.0
|
||||
topContentOffset = topContentOffset + max(0.0, min(1.0, topContentOffset / titleOffsetDelta)) * 10.0
|
||||
titleOffset = topContentOffset
|
||||
let fraction = max(0.0, min(1.0, titleOffset / titleOffsetDelta))
|
||||
@@ -317,15 +299,10 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
headerTransition.setScale(view: titleView, scale: titleScale)
|
||||
}
|
||||
|
||||
let animatedTransition = ComponentTransition(animation: .curve(duration: 0.18, curve: .easeInOut))
|
||||
animatedTransition.setAlpha(view: self.navigationBackgroundView, alpha: navigationBackgroundAlpha)
|
||||
animatedTransition.setAlpha(layer: self.navigationSeparatorLayerContainer, alpha: navigationBackgroundAlpha)
|
||||
|
||||
let expansionDistance: CGFloat = 32.0
|
||||
var expansionDistanceFactor: CGFloat = abs(scrollBounds.maxY - self.scrollView.contentSize.height) / expansionDistance
|
||||
expansionDistanceFactor = max(0.0, min(1.0, expansionDistanceFactor))
|
||||
|
||||
transition.setAlpha(layer: self.navigationSeparatorLayer, alpha: expansionDistanceFactor)
|
||||
if let panelContainerView = self.panelContainer.view as? StarsTransactionsPanelContainerComponent.View {
|
||||
panelContainerView.updateNavigationMergeFactor(value: 1.0 - expansionDistanceFactor, transition: transition)
|
||||
}
|
||||
@@ -435,18 +412,6 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
|
||||
self.navigationMetrics = (environment.navigationHeight, environment.statusBarHeight)
|
||||
|
||||
self.navigationSeparatorLayer.backgroundColor = environment.theme.rootController.navigationBar.separatorColor.cgColor
|
||||
|
||||
let navigationFrame = CGRect(origin: CGPoint(), size: CGSize(width: availableSize.width, height: environment.navigationHeight))
|
||||
self.navigationBackgroundView.updateColor(color: environment.theme.rootController.navigationBar.blurredBackgroundColor, transition: .immediate)
|
||||
self.navigationBackgroundView.update(size: navigationFrame.size, transition: transition.containedViewLayoutTransition)
|
||||
transition.setFrame(view: self.navigationBackgroundView, frame: navigationFrame)
|
||||
|
||||
let navigationSeparatorFrame = CGRect(origin: CGPoint(x: 0.0, y: navigationFrame.maxY), size: CGSize(width: availableSize.width, height: UIScreenPixel))
|
||||
|
||||
transition.setFrame(layer: self.navigationSeparatorLayerContainer, frame: navigationSeparatorFrame)
|
||||
transition.setFrame(layer: self.navigationSeparatorLayer, frame: CGRect(origin: CGPoint(), size: navigationSeparatorFrame.size))
|
||||
|
||||
self.backgroundColor = environment.theme.list.blocksBackgroundColor
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
@@ -519,7 +484,7 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
UIColor(rgb: 0xfdd219)
|
||||
],
|
||||
particleColor: UIColor(rgb: 0xf9b004),
|
||||
backgroundColor: environment.theme.list.blocksBackgroundColor
|
||||
backgroundColor: nil
|
||||
))
|
||||
}
|
||||
|
||||
@@ -532,7 +497,13 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
let starFrame = CGRect(origin: .zero, size: starSize)
|
||||
if let starView = self.starView.view {
|
||||
if starView.superview == nil {
|
||||
self.insertSubview(starView, aboveSubview: self.scrollView)
|
||||
if let navigationBar = environment.controller()?.navigationBar {
|
||||
if let titleView = self.titleView.view, titleView.superview != nil {
|
||||
navigationBar.view.insertSubview(starView, belowSubview: titleView)
|
||||
} else {
|
||||
navigationBar.view.insertSubview(starView, aboveSubview: navigationBar.backgroundView)
|
||||
}
|
||||
}
|
||||
}
|
||||
starTransition.setBounds(view: starView, bounds: starFrame)
|
||||
}
|
||||
@@ -562,7 +533,9 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
)
|
||||
if let titleView = self.titleView.view {
|
||||
if titleView.superview == nil {
|
||||
self.addSubview(titleView)
|
||||
if let navigationBar = environment.controller()?.navigationBar {
|
||||
navigationBar.view.insertSubview(titleView, aboveSubview: navigationBar.backgroundView)
|
||||
}
|
||||
}
|
||||
starTransition.setBounds(view: titleView, bounds: CGRect(origin: .zero, size: titleSize))
|
||||
}
|
||||
@@ -617,7 +590,13 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
if let topBalanceTitleView = self.topBalanceTitleView.view {
|
||||
if topBalanceTitleView.superview == nil {
|
||||
topBalanceTitleView.alpha = 0.0
|
||||
self.addSubview(topBalanceTitleView)
|
||||
if let navigationBar = environment.controller()?.navigationBar {
|
||||
if let titleView = self.titleView.view, titleView.superview != nil {
|
||||
navigationBar.view.insertSubview(topBalanceTitleView, aboveSubview: titleView)
|
||||
} else {
|
||||
navigationBar.view.insertSubview(topBalanceTitleView, aboveSubview: navigationBar.backgroundView)
|
||||
}
|
||||
}
|
||||
}
|
||||
starTransition.setFrame(view: topBalanceTitleView, frame: topBalanceTitleFrame)
|
||||
}
|
||||
@@ -626,7 +605,13 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
if let topBalanceValueView = self.topBalanceValueView.view {
|
||||
if topBalanceValueView.superview == nil {
|
||||
topBalanceValueView.alpha = 0.0
|
||||
self.addSubview(topBalanceValueView)
|
||||
if let navigationBar = environment.controller()?.navigationBar {
|
||||
if let titleView = self.titleView.view, titleView.superview != nil {
|
||||
navigationBar.view.insertSubview(topBalanceValueView, aboveSubview: titleView)
|
||||
} else {
|
||||
navigationBar.view.insertSubview(topBalanceValueView, aboveSubview: navigationBar.backgroundView)
|
||||
}
|
||||
}
|
||||
}
|
||||
starTransition.setFrame(view: topBalanceValueView, frame: topBalanceValueFrame)
|
||||
}
|
||||
@@ -638,7 +623,13 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
if let topBalanceIconView = self.topBalanceIconView.view {
|
||||
if topBalanceIconView.superview == nil {
|
||||
topBalanceIconView.alpha = 0.0
|
||||
self.addSubview(topBalanceIconView)
|
||||
if let navigationBar = environment.controller()?.navigationBar {
|
||||
if let titleView = self.titleView.view, titleView.superview != nil {
|
||||
navigationBar.view.insertSubview(topBalanceIconView, aboveSubview: titleView)
|
||||
} else {
|
||||
navigationBar.view.insertSubview(topBalanceIconView, aboveSubview: navigationBar.backgroundView)
|
||||
}
|
||||
}
|
||||
}
|
||||
starTransition.setFrame(view: topBalanceIconView, frame: topBalanceIconFrame)
|
||||
}
|
||||
@@ -844,7 +835,7 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
footer: nil,
|
||||
items: [
|
||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListItemComponentAdaptor(
|
||||
itemGenerator: ItemListDisclosureItem(presentationData: ItemListPresentationData(presentationData), icon: PresentationResourcesSettings.earnStars, title: environment.strings.Monetization_EarnStarsInfo_Title, titleBadge: presentationData.strings.Settings_New, label: environment.strings.Monetization_EarnStarsInfo_Text, labelStyle: .multilineDetailText, sectionId: 0, style: .blocks, action: {
|
||||
itemGenerator: ItemListDisclosureItem(presentationData: ItemListPresentationData(presentationData), icon: PresentationResourcesSettings.earnStars, title: environment.strings.Monetization_EarnStarsInfo_Title, titleBadge: nil, label: environment.strings.Monetization_EarnStarsInfo_Text, labelStyle: .multilineDetailText, sectionId: 0, style: .blocks, action: {
|
||||
}),
|
||||
params: ListViewItemLayoutParams(width: availableSize.width, leftInset: 0.0, rightInset: 0.0, availableHeight: 10000.0, isStandalone: true),
|
||||
action: { [weak self] in
|
||||
@@ -1261,7 +1252,7 @@ public final class StarsTransactionsScreen: ViewControllerComponentContainer {
|
||||
gift: {
|
||||
giftImpl?()
|
||||
}
|
||||
), navigationBarAppearance: .transparent)
|
||||
), navigationBarAppearance: .default)
|
||||
|
||||
self.navigationPresentation = .modalInLargeLayout
|
||||
|
||||
|
||||
+4
-2
@@ -348,7 +348,7 @@ private final class SheetContent: CombinedComponent {
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
tintColor: theme.chat.inputPanel.panelControlColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
@@ -655,7 +655,9 @@ private final class SheetContent: CombinedComponent {
|
||||
controller?.complete(paid: success)
|
||||
controller?.dismissAnimated()
|
||||
|
||||
starsContext.load(force: true)
|
||||
Queue.mainQueue().after(2.5) {
|
||||
starsContext.load(force: true)
|
||||
}
|
||||
})
|
||||
}
|
||||
),
|
||||
|
||||
@@ -42,6 +42,8 @@ swift_library(
|
||||
"//submodules/TelegramUI/Components/Stars/BalanceNeededScreen",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBackgroundComponent",
|
||||
"//submodules/TelegramUI/Components/AlertComponent",
|
||||
"//submodules/TelegramUI/Components/AlertComponent/AlertInputFieldComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
+108
-73
@@ -6,106 +6,141 @@ import TelegramPresentationData
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
import PasswordSetupUI
|
||||
import Markdown
|
||||
import OwnershipTransferController
|
||||
import ComponentFlow
|
||||
import AlertComponent
|
||||
import AlertInputFieldComponent
|
||||
|
||||
public func confirmStarsRevenueWithdrawalController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, amount: Int64, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (String) -> Void) -> ViewController {
|
||||
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let strings = presentationData.strings
|
||||
|
||||
let inputState = AlertInputFieldComponent.ExternalState()
|
||||
|
||||
let doneIsEnabled: Signal<Bool, NoError> = inputState.valueSignal
|
||||
|> map { value in
|
||||
return !value.isEmpty
|
||||
}
|
||||
|
||||
let doneInProgressPromise = ValuePromise<Bool>(false)
|
||||
|
||||
var content: [AnyComponentWithIdentity<AlertComponentEnvironment>] = []
|
||||
content.append(AnyComponentWithIdentity(
|
||||
id: "title",
|
||||
component: AnyComponent(
|
||||
AlertTitleComponent(title: strings.Monetization_Withdraw_EnterPassword_Title)
|
||||
)
|
||||
))
|
||||
content.append(AnyComponentWithIdentity(
|
||||
id: "text",
|
||||
component: AnyComponent(
|
||||
AlertTextComponent(content: .plain(strings.Monetization_Withdraw_EnterPassword_Text))
|
||||
)
|
||||
))
|
||||
|
||||
var applyImpl: (() -> Void)?
|
||||
content.append(AnyComponentWithIdentity(
|
||||
id: "input",
|
||||
component: AnyComponent(
|
||||
AlertInputFieldComponent(
|
||||
context: context,
|
||||
placeholder: strings.Channel_OwnershipTransfer_PasswordPlaceholder,
|
||||
isSecureTextEntry: true,
|
||||
isInitiallyFocused: true,
|
||||
externalState: inputState,
|
||||
returnKeyAction: {
|
||||
applyImpl?()
|
||||
}
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
var effectiveUpdatedPresentationData: (PresentationData, Signal<PresentationData, NoError>)
|
||||
if let updatedPresentationData {
|
||||
effectiveUpdatedPresentationData = updatedPresentationData
|
||||
} else {
|
||||
effectiveUpdatedPresentationData = (presentationData, context.sharedContext.presentationData)
|
||||
}
|
||||
|
||||
var dismissImpl: (() -> Void)?
|
||||
var proceedImpl: (() -> Void)?
|
||||
|
||||
let disposable = MetaDisposable()
|
||||
|
||||
let contentNode = ChannelOwnershipTransferAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: presentationData.theme, strings: presentationData.strings, title: presentationData.strings.Monetization_Withdraw_EnterPassword_Title, text: presentationData.strings.Monetization_Withdraw_EnterPassword_Text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||
dismissImpl?()
|
||||
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Monetization_Withdraw_EnterPassword_Done, action: {
|
||||
proceedImpl?()
|
||||
})])
|
||||
|
||||
contentNode.complete = {
|
||||
proceedImpl?()
|
||||
}
|
||||
|
||||
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
|
||||
let presentationDataDisposable = (updatedPresentationData?.signal ?? context.sharedContext.presentationData).start(next: { [weak controller, weak contentNode] presentationData in
|
||||
controller?.theme = AlertControllerTheme(presentationData: presentationData)
|
||||
contentNode?.theme = presentationData.theme
|
||||
})
|
||||
controller.dismissed = { _ in
|
||||
presentationDataDisposable.dispose()
|
||||
disposable.dispose()
|
||||
}
|
||||
dismissImpl = { [weak controller, weak contentNode] in
|
||||
contentNode?.dismissInput()
|
||||
controller?.dismissAnimated()
|
||||
}
|
||||
proceedImpl = { [weak contentNode] in
|
||||
guard let contentNode = contentNode else {
|
||||
return
|
||||
}
|
||||
contentNode.updateIsChecking(true)
|
||||
|
||||
let signal = context.engine.peers.requestStarsRevenueWithdrawalUrl(peerId: peerId, ton: false, amount: amount, password: contentNode.password)
|
||||
disposable.set((signal |> deliverOnMainQueue).start(next: { url in
|
||||
let alertController = AlertScreen(
|
||||
configuration: AlertScreen.Configuration(allowInputInset: true),
|
||||
content: content,
|
||||
actions: [
|
||||
.init(title: strings.Common_Cancel),
|
||||
.init(title: strings.Monetization_Withdraw_EnterPassword_Done, type: .default, action: {
|
||||
applyImpl?()
|
||||
}, autoDismiss: false, isEnabled: doneIsEnabled, progress: doneInProgressPromise.get())
|
||||
],
|
||||
updatedPresentationData: effectiveUpdatedPresentationData
|
||||
)
|
||||
applyImpl = {
|
||||
doneInProgressPromise.set(true)
|
||||
|
||||
let _ = (context.engine.peers.requestStarsRevenueWithdrawalUrl(peerId: peerId, ton: false, amount: amount, password: inputState.value)
|
||||
|> deliverOnMainQueue).start(next: { url in
|
||||
dismissImpl?()
|
||||
completion(url)
|
||||
}, error: { [weak contentNode] error in
|
||||
}, error: { error in
|
||||
var errorTextAndActions: (String, [TextAlertAction])?
|
||||
switch error {
|
||||
case .invalidPassword:
|
||||
contentNode?.animateError()
|
||||
case .limitExceeded:
|
||||
errorTextAndActions = (presentationData.strings.TwoStepAuth_FloodError, [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
|
||||
default:
|
||||
errorTextAndActions = (presentationData.strings.Login_UnknownError, [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
|
||||
case .invalidPassword:
|
||||
inputState.animateError()
|
||||
case .limitExceeded:
|
||||
errorTextAndActions = (strings.TwoStepAuth_FloodError, [TextAlertAction(type: .defaultAction, title: strings.Common_OK, action: {})])
|
||||
default:
|
||||
errorTextAndActions = (strings.Login_UnknownError, [TextAlertAction(type: .defaultAction, title: strings.Common_OK, action: {})])
|
||||
}
|
||||
contentNode?.updateIsChecking(false)
|
||||
|
||||
doneInProgressPromise.set(false)
|
||||
|
||||
if let (text, actions) = errorTextAndActions {
|
||||
dismissImpl?()
|
||||
present(textAlertController(context: context, title: nil, text: text, actions: actions), nil)
|
||||
}
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
return controller
|
||||
dismissImpl = { [weak alertController] in
|
||||
alertController?.dismiss(completion: nil)
|
||||
}
|
||||
return alertController
|
||||
}
|
||||
|
||||
public func starsRevenueWithdrawalController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, amount: Int64, initialError: RequestStarsRevenueWithdrawalError, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (String) -> Void) -> ViewController {
|
||||
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
let theme = AlertControllerTheme(presentationData: presentationData)
|
||||
let strings = presentationData.strings
|
||||
|
||||
var title: NSAttributedString? = NSAttributedString(string: presentationData.strings.OwnershipTransfer_SecurityCheck, font: Font.semibold(presentationData.listsFontSize.itemListBaseFontSize), textColor: theme.primaryColor, paragraphAlignment: .center)
|
||||
|
||||
var text = presentationData.strings.Monetization_Withdraw_SecurityRequirements
|
||||
let textFontSize = presentationData.listsFontSize.baseDisplaySize * 13.0 / 17.0
|
||||
|
||||
var actions: [TextAlertAction] = []
|
||||
var title: String? = strings.OwnershipTransfer_SecurityCheck
|
||||
var text = strings.Monetization_Withdraw_SecurityRequirements
|
||||
|
||||
var actions: [AlertScreen.Action] = [
|
||||
.init(title: strings.Common_OK, type: .default)
|
||||
]
|
||||
switch initialError {
|
||||
case .requestPassword:
|
||||
case .requestPassword:
|
||||
return confirmStarsRevenueWithdrawalController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, amount: amount, present: present, completion: completion)
|
||||
case .twoStepAuthTooFresh, .authSessionTooFresh:
|
||||
text = text + presentationData.strings.Monetization_Withdraw_ComeBackLater
|
||||
actions = [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]
|
||||
case .twoStepAuthMissing:
|
||||
actions = [TextAlertAction(type: .genericAction, title: presentationData.strings.OwnershipTransfer_SetupTwoStepAuth, action: {
|
||||
case .twoStepAuthTooFresh, .authSessionTooFresh:
|
||||
text = text + strings.Monetization_Withdraw_ComeBackLater
|
||||
case .twoStepAuthMissing:
|
||||
actions = [
|
||||
.init(title: strings.OwnershipTransfer_SetupTwoStepAuth, type: .default, action: {
|
||||
let controller = SetupTwoStepVerificationController(context: context, initialState: .automatic, stateUpdated: { update, shouldDismiss, controller in
|
||||
if shouldDismiss {
|
||||
controller.dismiss()
|
||||
}
|
||||
})
|
||||
present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {})]
|
||||
default:
|
||||
title = nil
|
||||
text = presentationData.strings.Login_UnknownError
|
||||
actions = [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]
|
||||
}),
|
||||
.init(title: strings.Common_Cancel)
|
||||
]
|
||||
default:
|
||||
title = nil
|
||||
text = strings.Login_UnknownError
|
||||
}
|
||||
|
||||
let body = MarkdownAttributeSet(font: Font.regular(textFontSize), textColor: theme.primaryColor)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(textFontSize), textColor: theme.primaryColor)
|
||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in return nil }), textAlignment: .center)
|
||||
|
||||
return richTextAlertController(context: context, title: title, text: attributedText, actions: actions)
|
||||
return AlertScreen(
|
||||
context: context,
|
||||
configuration: AlertScreen.Configuration(actionAlignment: .vertical),
|
||||
title: title,
|
||||
text: text,
|
||||
actions: actions
|
||||
)
|
||||
}
|
||||
|
||||
+51
-8
@@ -95,7 +95,7 @@ private final class SheetContent: CombinedComponent {
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
tintColor: theme.chat.inputPanel.panelControlColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
@@ -167,7 +167,11 @@ private final class SheetContent: CombinedComponent {
|
||||
maxAmount = StarsAmount(value: resaleConfiguration.starGiftResaleMaxStarsAmount, nanos: 0)
|
||||
case .ton:
|
||||
amountTitle = environment.strings.Stars_SellGift_TonAmountTitle
|
||||
#if DEBUG
|
||||
minAmount = StarsAmount(value: 48000000000, nanos: 0)
|
||||
#else
|
||||
minAmount = StarsAmount(value: resaleConfiguration.starGiftResaleMinTonAmount, nanos: 0)
|
||||
#endif
|
||||
maxAmount = StarsAmount(value: resaleConfiguration.starGiftResaleMaxTonAmount, nanos: 0)
|
||||
}
|
||||
case let .paidMessages(_, minAmountValue, _, _, _):
|
||||
@@ -618,7 +622,14 @@ private final class SheetContent: CombinedComponent {
|
||||
}
|
||||
if state.currency == .stars {
|
||||
if let amount = state.amount, let tonUsdRate = withdrawConfiguration.tonUsdRate, let usdWithdrawRate = withdrawConfiguration.usdWithdrawRate {
|
||||
state.amount = StarsAmount(value: max(min(convertStarsToTon(amount, tonUsdRate: tonUsdRate, starsUsdRate: usdWithdrawRate), resaleConfiguration.starGiftResaleMaxTonAmount), resaleConfiguration.starGiftResaleMinTonAmount), nanos: 0)
|
||||
var convertedValue = min(convertStarsToTon(amount, tonUsdRate: tonUsdRate, starsUsdRate: usdWithdrawRate), resaleConfiguration.starGiftResaleMaxTonAmount)
|
||||
if convertedValue < resaleConfiguration.starGiftResaleMinTonAmount {
|
||||
convertedValue = resaleConfiguration.starGiftResaleMinTonAmount
|
||||
if case .starGiftResell = component.mode, let controller = controller() as? StarsWithdrawScreen {
|
||||
controller.presentMinAmountTooltip(convertedValue, currency: .ton)
|
||||
}
|
||||
}
|
||||
state.amount = StarsAmount(value: convertedValue, nanos: 0)
|
||||
} else {
|
||||
state.amount = StarsAmount(value: 0, nanos: 0)
|
||||
}
|
||||
@@ -1255,6 +1266,8 @@ private final class StarsWithdrawSheetComponent: CombinedComponent {
|
||||
let sheet = Child(SheetComponent<(EnvironmentType)>.self)
|
||||
let animateOut = StoredActionSlot(Action<Void>.self)
|
||||
|
||||
let sheetExternalState = SheetComponent<EnvironmentType>.ExternalState()
|
||||
|
||||
return { context in
|
||||
let environment = context.environment[EnvironmentType.self]
|
||||
|
||||
@@ -1281,6 +1294,7 @@ private final class StarsWithdrawSheetComponent: CombinedComponent {
|
||||
followContentSizeChanges: false,
|
||||
clipsContent: true,
|
||||
isScrollEnabled: false,
|
||||
externalState: sheetExternalState,
|
||||
animateOut: animateOut
|
||||
),
|
||||
environment: {
|
||||
@@ -1313,6 +1327,29 @@ private final class StarsWithdrawSheetComponent: CombinedComponent {
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height / 2.0))
|
||||
)
|
||||
|
||||
if let controller = controller(), !controller.automaticallyControlPresentationContextLayout {
|
||||
var sideInset: CGFloat = 0.0
|
||||
var bottomInset: CGFloat = max(environment.safeInsets.bottom, sheetExternalState.contentHeight)
|
||||
if case .regular = environment.metrics.widthClass {
|
||||
sideInset = floor((context.availableSize.width - 430.0) / 2.0) - 12.0
|
||||
bottomInset = (context.availableSize.height - sheetExternalState.contentHeight) / 2.0 + sheetExternalState.contentHeight
|
||||
}
|
||||
|
||||
let layout = ContainerViewLayout(
|
||||
size: context.availableSize,
|
||||
metrics: environment.metrics,
|
||||
deviceMetrics: environment.deviceMetrics,
|
||||
intrinsicInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: bottomInset, right: 0.0),
|
||||
safeInsets: UIEdgeInsets(top: 0.0, left: max(sideInset, environment.safeInsets.left), bottom: 0.0, right: max(sideInset, environment.safeInsets.right)),
|
||||
additionalInsets: .zero,
|
||||
statusBarHeight: environment.statusBarHeight,
|
||||
inputHeight: nil,
|
||||
inputHeightIsInteractivellyChanging: false,
|
||||
inVoiceOver: false
|
||||
)
|
||||
controller.presentationContext.containerLayoutUpdated(layout, transition: context.transition.containedViewLayoutTransition)
|
||||
}
|
||||
|
||||
return context.availableSize
|
||||
}
|
||||
}
|
||||
@@ -1357,6 +1394,7 @@ public final class StarsWithdrawScreen: ViewControllerComponentContainer {
|
||||
)
|
||||
|
||||
self.navigationPresentation = .flatModal
|
||||
self.automaticallyControlPresentationContextLayout = false
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
@@ -1422,10 +1460,8 @@ public final class StarsWithdrawScreen: ViewControllerComponentContainer {
|
||||
round: false,
|
||||
undoText: nil
|
||||
),
|
||||
elevatedLayout: false,
|
||||
position: .top,
|
||||
action: { _ in return true})
|
||||
self.present(resultController, in: .window(.root))
|
||||
self.present(resultController, in: .current)
|
||||
|
||||
if let view = self.node.hostView.findTaggedView(tag: amountTag) as? AmountFieldComponent.View {
|
||||
view.animateError()
|
||||
@@ -1769,8 +1805,15 @@ public final class AmountFieldComponent: Component {
|
||||
guard let component = self.component, let value = component.value else {
|
||||
return
|
||||
}
|
||||
self.textField.text = "\(value)"
|
||||
self.placeholderView.view?.isHidden = self.textField.text?.isEmpty ?? false
|
||||
var text = ""
|
||||
switch component.currency {
|
||||
case .stars:
|
||||
text = "\(value)"
|
||||
case .ton:
|
||||
text = "\(formatTonAmountText(value, dateTimeFormat: PresentationDateTimeFormat(timeFormat: component.dateTimeFormat.timeFormat, dateFormat: component.dateTimeFormat.dateFormat, dateSeparator: "", dateSuffix: "", requiresFullYear: false, decimalSeparator: ".", groupingSeparator: ""), maxDecimalPositions: nil))"
|
||||
}
|
||||
self.textField.text = text
|
||||
self.placeholderView.view?.isHidden = !(self.textField.text ?? "").isEmpty
|
||||
}
|
||||
|
||||
func update(component: AmountFieldComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
@@ -1790,7 +1833,7 @@ public final class AmountFieldComponent: Component {
|
||||
text = "\(formatTonAmountText(value, dateTimeFormat: PresentationDateTimeFormat(timeFormat: component.dateTimeFormat.timeFormat, dateFormat: component.dateTimeFormat.dateFormat, dateSeparator: "", dateSuffix: "", requiresFullYear: false, decimalSeparator: ".", groupingSeparator: ""), maxDecimalPositions: nil))"
|
||||
}
|
||||
self.textField.text = text
|
||||
self.placeholderView.view?.isHidden = text.isEmpty
|
||||
self.placeholderView.view?.isHidden = !text.isEmpty
|
||||
} else {
|
||||
self.textField.text = ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user