mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-06-08 11:03:55 +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:
@@ -149,7 +149,7 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
||||
case .back:
|
||||
text = presentationData.strings.Common_Back
|
||||
accessibilityText = presentationData.strings.Common_Back
|
||||
icon = NavigationBar.backArrowImage(color: .white)
|
||||
icon = navigationBarBackArrowImage(color: .white)
|
||||
case .edit:
|
||||
text = presentationData.strings.Common_Edit
|
||||
accessibilityText = text
|
||||
|
||||
@@ -76,7 +76,7 @@ class IncreaseLimitHeaderItemNode: ListViewItemNode {
|
||||
private var item: BoostLevelHeaderItem?
|
||||
|
||||
init() {
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
super.init(layerBacked: false)
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
|
||||
@@ -111,7 +111,7 @@ private final class BoostsTabsItemNode: ListViewItemNode {
|
||||
self.selectionNode = ASImageNode()
|
||||
self.selectionNode.displaysAsynchronously = false
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
super.init(layerBacked: false)
|
||||
|
||||
self.addSubnode(self.boostsTextNode)
|
||||
self.addSubnode(self.giftsTextNode)
|
||||
|
||||
@@ -1229,7 +1229,7 @@ private enum StatsEntry: ItemListNodeEntry {
|
||||
arguments.presentCpmLocked()
|
||||
})
|
||||
case .earnStarsInfo:
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: PresentationResourcesSettings.earnStars, title: presentationData.strings.Monetization_EarnStarsInfo_Title, titleBadge: presentationData.strings.Settings_New, label: presentationData.strings.Monetization_EarnStarsInfo_Text, labelStyle: .multilineDetailText, sectionId: self.section, style: .blocks, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: PresentationResourcesSettings.earnStars, title: presentationData.strings.Monetization_EarnStarsInfo_Title, titleBadge: nil, label: presentationData.strings.Monetization_EarnStarsInfo_Text, labelStyle: .multilineDetailText, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openEarnStars()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ final class MonetizationBalanceItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
self.activateArea = AccessibilityAreaNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
super.init(layerBacked: false)
|
||||
|
||||
self.addSubnode(self.iconNode)
|
||||
self.addSubnode(self.balanceTextNode)
|
||||
|
||||
@@ -12,7 +12,7 @@ import SheetComponent
|
||||
import BundleIconComponent
|
||||
import BalancedTextComponent
|
||||
import MultilineTextComponent
|
||||
import SolidRoundedButtonComponent
|
||||
import ButtonComponent
|
||||
import LottieComponent
|
||||
import AccountContext
|
||||
|
||||
@@ -73,7 +73,7 @@ private final class SheetContent: CombinedComponent {
|
||||
|
||||
let title = Child(BalancedTextComponent.self)
|
||||
let list = Child(List<Empty>.self)
|
||||
let actionButton = Child(SolidRoundedButtonComponent.self)
|
||||
let actionButton = Child(ButtonComponent.self)
|
||||
|
||||
let infoBackground = Child(RoundedRectangle.self)
|
||||
let infoTitle = Child(MultilineTextComponent.self)
|
||||
@@ -284,7 +284,7 @@ private final class SheetContent: CombinedComponent {
|
||||
let infoBackground = infoBackground.update(
|
||||
component: RoundedRectangle(
|
||||
color: theme.list.blocksBackgroundColor,
|
||||
cornerRadius: 10.0
|
||||
cornerRadius: 26.0
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: totalInfoHeight),
|
||||
transition: .immediate
|
||||
@@ -307,37 +307,48 @@ private final class SheetContent: CombinedComponent {
|
||||
contentSize.height += infoPadding
|
||||
contentSize.height += spacing
|
||||
|
||||
var buttonTitle: [AnyComponentWithIdentity<Empty>] = []
|
||||
buttonTitle.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(LottieComponent(
|
||||
content: LottieComponent.AppBundleContent(name: "anim_ok"),
|
||||
color: theme.list.itemCheckColors.foregroundColor,
|
||||
startingPosition: .begin,
|
||||
size: CGSize(width: 28.0, height: 28.0),
|
||||
playOnce: state.playOnce
|
||||
))))
|
||||
buttonTitle.append(AnyComponentWithIdentity(id: 1, component: AnyComponent(ButtonTextContentComponent(
|
||||
text: strings.Monetization_Intro_Understood,
|
||||
badge: 0,
|
||||
textColor: theme.list.itemCheckColors.foregroundColor,
|
||||
badgeBackground: theme.list.itemCheckColors.foregroundColor,
|
||||
badgeForeground: theme.list.itemCheckColors.fillColor
|
||||
))))
|
||||
|
||||
let buttonInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
|
||||
let actionButton = actionButton.update(
|
||||
component: SolidRoundedButtonComponent(
|
||||
title: strings.Monetization_Intro_Understood,
|
||||
theme: SolidRoundedButtonComponent.Theme(
|
||||
backgroundColor: theme.list.itemCheckColors.fillColor,
|
||||
backgroundColors: [],
|
||||
foregroundColor: theme.list.itemCheckColors.foregroundColor
|
||||
component: ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
style: .glass,
|
||||
color: theme.list.itemCheckColors.fillColor,
|
||||
foreground: theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9)
|
||||
),
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable(0),
|
||||
component: AnyComponent(HStack(buttonTitle, spacing: 2.0))
|
||||
),
|
||||
font: .bold,
|
||||
fontSize: 17.0,
|
||||
height: 50.0,
|
||||
cornerRadius: 10.0,
|
||||
gloss: false,
|
||||
iconName: nil,
|
||||
animationName: nil,
|
||||
iconPosition: .left,
|
||||
action: {
|
||||
component.dismiss()
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0),
|
||||
availableSize: CGSize(width: context.availableSize.width - buttonInsets.left - buttonInsets.right, height: 52.0),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(actionButton
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + actionButton.size.height / 2.0))
|
||||
)
|
||||
contentSize.height += actionButton.size.height
|
||||
contentSize.height += 22.0
|
||||
|
||||
contentSize.height += environment.safeInsets.bottom
|
||||
|
||||
contentSize.height += buttonInsets.bottom
|
||||
|
||||
state.playAnimationIfNeeded()
|
||||
|
||||
return contentSize
|
||||
@@ -397,6 +408,7 @@ private final class SheetContainerComponent: CombinedComponent {
|
||||
})
|
||||
}
|
||||
)),
|
||||
style: .glass,
|
||||
backgroundColor: .color(environment.theme.actionSheet.opaqueItemBackgroundColor),
|
||||
followContentSizeChanges: true,
|
||||
externalState: sheetExternalState,
|
||||
|
||||
@@ -6,107 +6,148 @@ import TelegramPresentationData
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
import PasswordSetupUI
|
||||
import Markdown
|
||||
import OwnershipTransferController
|
||||
import ComponentFlow
|
||||
import AlertComponent
|
||||
import AlertInputFieldComponent
|
||||
|
||||
func confirmRevenueWithdrawalController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (String) -> Void) -> ViewController {
|
||||
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
func confirmRevenueWithdrawalController(
|
||||
context: AccountContext,
|
||||
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil,
|
||||
peerId: EnginePeer.Id,
|
||||
present: @escaping (ViewController, Any?) -> Void,
|
||||
completion: @escaping (String) -> Void
|
||||
) -> ViewController {
|
||||
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: true, amount: nil, 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: true, amount: nil, 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 revenueWithdrawalController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, 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 title: String? = strings.OwnershipTransfer_SecurityCheck
|
||||
var text = strings.Monetization_Withdraw_SecurityRequirements
|
||||
|
||||
var text = presentationData.strings.Monetization_Withdraw_SecurityRequirements
|
||||
let textFontSize = presentationData.listsFontSize.baseDisplaySize * 13.0 / 17.0
|
||||
|
||||
var actions: [TextAlertAction] = []
|
||||
var actions: [AlertScreen.Action] = [
|
||||
.init(title: strings.Common_OK, type: .default)
|
||||
]
|
||||
switch initialError {
|
||||
case .requestPassword:
|
||||
return confirmRevenueWithdrawalController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, 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 .requestPassword:
|
||||
return confirmRevenueWithdrawalController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, present: present, completion: completion)
|
||||
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
|
||||
)
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ final class StarsTransactionItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
self.activateArea = AccessibilityAreaNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
super.init(layerBacked: false)
|
||||
}
|
||||
|
||||
func asyncLayout() -> (_ item: StarsTransactionItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||
|
||||
@@ -133,7 +133,7 @@ public final class StatsGraphItemNode: ListViewItemNode {
|
||||
self.activityIndicator = ActivityIndicator(type: ActivityIndicatorType.custom(.black, 16.0, 2.0, false))
|
||||
self.activityIndicator.isHidden = true
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
super.init(layerBacked: false)
|
||||
|
||||
self.chartContainerNode.addSubnode(self.chartNode)
|
||||
self.chartContainerNode.addSubnode(self.activityIndicator)
|
||||
|
||||
@@ -184,7 +184,7 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
self.activateArea = AccessibilityAreaNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
super.init(layerBacked: false)
|
||||
|
||||
self.containerNode.addSubnode(self.contextSourceNode)
|
||||
self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode
|
||||
|
||||
@@ -327,7 +327,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
||||
self.bottomLeftItem = ValueItemNode()
|
||||
self.bottomRightItem = ValueItemNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
super.init(layerBacked: false)
|
||||
|
||||
self.clipsToBounds = true
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@ import SheetComponent
|
||||
import BundleIconComponent
|
||||
import BalancedTextComponent
|
||||
import MultilineTextComponent
|
||||
import SolidRoundedButtonComponent
|
||||
import LottieComponent
|
||||
import ButtonComponent
|
||||
import AccountContext
|
||||
import TelegramStringFormatting
|
||||
import PremiumPeerShortcutComponent
|
||||
import GlassBarButtonComponent
|
||||
|
||||
private final class SheetContent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
@@ -55,18 +55,6 @@ private final class SheetContent: CombinedComponent {
|
||||
}
|
||||
|
||||
final class State: ComponentState {
|
||||
var cachedCloseImage: (UIImage, PresentationTheme)?
|
||||
|
||||
let playOnce = ActionSlot<Void>()
|
||||
private var didPlayAnimation = false
|
||||
|
||||
func playAnimationIfNeeded() {
|
||||
guard !self.didPlayAnimation else {
|
||||
return
|
||||
}
|
||||
self.didPlayAnimation = true
|
||||
self.playOnce.invoke(Void())
|
||||
}
|
||||
}
|
||||
|
||||
func makeState() -> State {
|
||||
@@ -74,25 +62,23 @@ private final class SheetContent: CombinedComponent {
|
||||
}
|
||||
|
||||
static var body: Body {
|
||||
let closeButton = Child(Button.self)
|
||||
let closeButton = Child(GlassBarButtonComponent.self)
|
||||
|
||||
let amount = Child(MultilineTextComponent.self)
|
||||
let title = Child(MultilineTextComponent.self)
|
||||
let date = Child(MultilineTextComponent.self)
|
||||
let peerShortcut = Child(PremiumPeerShortcutComponent.self)
|
||||
|
||||
let actionButton = Child(SolidRoundedButtonComponent.self)
|
||||
let actionButton = Child(ButtonComponent.self)
|
||||
|
||||
return { context in
|
||||
let environment = context.environment[EnvironmentType.self]
|
||||
let component = context.component
|
||||
let state = context.state
|
||||
|
||||
let theme = environment.theme
|
||||
let strings = environment.strings
|
||||
let dateTimeFormat = component.context.sharedContext.currentPresentationData.with { $0 }.dateTimeFormat
|
||||
|
||||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||
let textSideInset: CGFloat = 32.0 + environment.safeInsets.left
|
||||
|
||||
let titleFont = Font.semibold(17.0)
|
||||
@@ -103,26 +89,27 @@ private final class SheetContent: CombinedComponent {
|
||||
|
||||
var contentSize = CGSize(width: context.availableSize.width, height: 45.0)
|
||||
|
||||
let closeImage: UIImage
|
||||
if let (image, theme) = state.cachedCloseImage, theme === environment.theme {
|
||||
closeImage = image
|
||||
} else {
|
||||
closeImage = generateCloseButtonImage(backgroundColor: UIColor(rgb: 0x808084, alpha: 0.1), foregroundColor: theme.actionSheet.inputClearButtonColor)!
|
||||
state.cachedCloseImage = (closeImage, theme)
|
||||
}
|
||||
|
||||
let closeButton = closeButton.update(
|
||||
component: Button(
|
||||
content: AnyComponent(Image(image: closeImage)),
|
||||
action: { [weak component] in
|
||||
component?.dismiss()
|
||||
component: GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: theme.overallDarkAppearance,
|
||||
state: .generic,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: theme.chat.inputPanel.panelControlColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
component.dismiss()
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: 30.0, height: 30.0),
|
||||
availableSize: CGSize(width: 40.0, height: 40.0),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(closeButton
|
||||
.position(CGPoint(x: context.availableSize.width - environment.safeInsets.left - closeButton.size.width, y: 28.0))
|
||||
.position(CGPoint(x: 16.0 + closeButton.size.width / 2.0, y: 16.0 + closeButton.size.height / 2.0))
|
||||
)
|
||||
|
||||
let amountString: NSMutableAttributedString
|
||||
@@ -255,27 +242,30 @@ private final class SheetContent: CombinedComponent {
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + peerShortcut.size.height / 2.0))
|
||||
)
|
||||
contentSize.height += peerShortcut.size.height
|
||||
contentSize.height += 50.0
|
||||
contentSize.height += 32.0
|
||||
} else {
|
||||
contentSize.height += 45.0
|
||||
contentSize.height += 27.0
|
||||
}
|
||||
|
||||
let buttonInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
|
||||
let actionButton = actionButton.update(
|
||||
component: SolidRoundedButtonComponent(
|
||||
title: buttonTitle,
|
||||
theme: SolidRoundedButtonComponent.Theme(
|
||||
backgroundColor: theme.list.itemCheckColors.fillColor,
|
||||
backgroundColors: [],
|
||||
foregroundColor: theme.list.itemCheckColors.foregroundColor
|
||||
component: ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
style: .glass,
|
||||
color: theme.list.itemCheckColors.fillColor,
|
||||
foreground: theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9)
|
||||
),
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable(0),
|
||||
component: AnyComponent(ButtonTextContentComponent(
|
||||
text: buttonTitle,
|
||||
badge: 0,
|
||||
textColor: theme.list.itemCheckColors.foregroundColor,
|
||||
badgeBackground: theme.list.itemCheckColors.foregroundColor,
|
||||
badgeForeground: theme.list.itemCheckColors.fillColor
|
||||
))
|
||||
),
|
||||
font: .bold,
|
||||
fontSize: 17.0,
|
||||
height: 50.0,
|
||||
cornerRadius: 10.0,
|
||||
gloss: false,
|
||||
iconName: nil,
|
||||
animationName: nil,
|
||||
iconPosition: .left,
|
||||
action: {
|
||||
component.dismiss()
|
||||
if let explorerUrl {
|
||||
@@ -283,18 +273,14 @@ private final class SheetContent: CombinedComponent {
|
||||
}
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0),
|
||||
availableSize: CGSize(width: context.availableSize.width - buttonInsets.left - buttonInsets.right, height: 52.0),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(actionButton
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + actionButton.size.height / 2.0))
|
||||
)
|
||||
contentSize.height += actionButton.size.height
|
||||
contentSize.height += 22.0
|
||||
|
||||
contentSize.height += environment.safeInsets.bottom
|
||||
|
||||
state.playAnimationIfNeeded()
|
||||
contentSize.height += buttonInsets.bottom
|
||||
|
||||
return contentSize
|
||||
}
|
||||
@@ -360,6 +346,7 @@ private final class SheetContainerComponent: CombinedComponent {
|
||||
})
|
||||
}
|
||||
)),
|
||||
style: .glass,
|
||||
backgroundColor: .color(environment.theme.actionSheet.opaqueItemBackgroundColor),
|
||||
followContentSizeChanges: true,
|
||||
externalState: sheetExternalState,
|
||||
|
||||
Reference in New Issue
Block a user