mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-05 19:28:46 +02:00
Various improvements
This commit is contained in:
parent
d58757ca3c
commit
85092482f3
69 changed files with 476 additions and 303 deletions
|
|
@ -1048,7 +1048,10 @@ public class AttachmentController: ViewController, MinimizableController {
|
|||
ContainedViewLayoutTransition.animated(duration: 0.3, curve: .linear).updateAlpha(node: self.dim, alpha: 1.0)
|
||||
|
||||
if case .glass = controller.style, let attachmentButton = controller.attachmentButton {
|
||||
let transition = ContainedViewLayoutTransition.animated(duration: 0.4, curve: .customSpring(damping: 115.0, initialVelocity: 0.0))
|
||||
let positionTransition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .customSpring(damping: 110.0, initialVelocity: 1.1))
|
||||
let cornersTransition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .easeInOut)
|
||||
let scaleTransition: ContainedViewLayoutTransition = .animated(duration: 0.45, curve: .customSpring(damping: 110.0, initialVelocity: 0.0))
|
||||
|
||||
let buttonTransition = ContainedViewLayoutTransition.animated(duration: 0.15, curve: .easeInOut)
|
||||
|
||||
let targetFrame = self.container.clipNode.view.convert(self.container.clipNode.view.bounds, to: self.view)
|
||||
|
|
@ -1080,11 +1083,13 @@ public class AttachmentController: ViewController, MinimizableController {
|
|||
|
||||
let initialContainerBounds = self.container.bounds
|
||||
let initialContainerFrame = self.container.frame
|
||||
let initialBottomClipRadius = self.container.bottomClipNode.cornerRadius
|
||||
|
||||
let clipInnerFrame = self.container.container.view.convert(self.container.container.view.bounds, to: self.container.view)
|
||||
self.container.bounds = CGRect(origin: .zero, size: self.container.bounds.size)
|
||||
self.container.frame = CGRect(origin: CGPoint(x: floorToScreenPixels ((targetFrame.width - self.container.frame.width) / 2.0), y: -clipInnerFrame.minY), size: self.container.frame.size)
|
||||
self.container.view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
self.container.bottomClipNode.cornerRadius = 0.0
|
||||
containerView.addSubnode(self.container)
|
||||
|
||||
let buttonIcon = GlassBackgroundView.ContentImageView()
|
||||
|
|
@ -1099,16 +1104,17 @@ public class AttachmentController: ViewController, MinimizableController {
|
|||
localGlassView.contentView.addSubview(buttonIcon)
|
||||
ComponentTransition(buttonTransition).animateBlur(layer: buttonIcon.layer, fromRadius: 0.0, toRadius: 10.0)
|
||||
|
||||
transition.animateBounds(layer: containerView.layer, from: CGRect(origin: CGPoint(x: 0.0, y: (targetFrame.height - targetFrame.width) * 0.5), size: CGSize(width: targetFrame.width, height: targetFrame.width)))
|
||||
ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut).animateView {
|
||||
scaleTransition.animateBounds(layer: containerView.layer, from: CGRect(origin: CGPoint(x: 0.0, y: (targetFrame.height - targetFrame.width) * 0.5), size: CGSize(width: targetFrame.width, height: targetFrame.width)))
|
||||
cornersTransition.animateView {
|
||||
if #available(iOS 26.0, *) {
|
||||
containerView.cornerConfiguration = .corners(topLeftRadius: 38.0, topRightRadius: 38.0, bottomLeftRadius: .fixed(layout.deviceMetrics.screenCornerRadius - 2.0), bottomRightRadius: .fixed(layout.deviceMetrics.screenCornerRadius - 2.0))
|
||||
} else {
|
||||
containerView.layer.cornerRadius = layout.deviceMetrics.screenCornerRadius - 2.0
|
||||
}
|
||||
}
|
||||
transition.animateTransformScale(view: containerView, from: sourceButtonScale)
|
||||
transition.animatePosition(layer: containerView.layer, from: sourceButtonFrame.center, to: containerView.center, completion: { _ in
|
||||
scaleTransition.animateTransformScale(view: containerView, from: sourceButtonScale)
|
||||
positionTransition.animatePosition(layer: containerView.layer, from: sourceButtonFrame.center, to: containerView.center, completion: { _ in
|
||||
self.container.bottomClipNode.cornerRadius = initialBottomClipRadius
|
||||
self.container.bounds = initialContainerBounds
|
||||
self.container.frame = initialContainerFrame
|
||||
self.wrapperNode.addSubnode(self.container)
|
||||
|
|
@ -1158,8 +1164,11 @@ public class AttachmentController: ViewController, MinimizableController {
|
|||
alphaTransition.updateAlpha(node: self.dim, alpha: 0.0)
|
||||
|
||||
if case .glass = controller.style, let attachmentButton = controller.attachmentButton {
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .customSpring(damping: damping ?? 124.0, initialVelocity: initialVelocity ?? 0.0))
|
||||
let buttonTransition = ContainedViewLayoutTransition.animated(duration: 0.3, curve: .easeInOut)
|
||||
let positionTransition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .customSpring(damping: 110.0, initialVelocity: initialVelocity ?? 0.0))
|
||||
let cornersTransition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .customSpring(damping: 124.0, initialVelocity: initialVelocity ?? 0.0))
|
||||
let scaleTransition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .customSpring(damping: 124.0, initialVelocity: initialVelocity ?? 0.0))
|
||||
|
||||
let buttonTransition = ContainedViewLayoutTransition.animated(duration: 0.22, curve: .easeInOut)
|
||||
|
||||
let initialFrame = self.container.clipNode.view.convert(self.container.clipNode.view.bounds, to: self.view)
|
||||
|
||||
|
|
@ -1192,7 +1201,7 @@ public class AttachmentController: ViewController, MinimizableController {
|
|||
self.container.bounds = CGRect(origin: .zero, size: self.container.bounds.size)
|
||||
self.container.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((initialFrame.width - self.container.frame.width) / 2.0), y: -clipInnerFrame.minY), size: self.container.frame.size)
|
||||
self.container.isUserInteractionEnabled = false
|
||||
self.container.view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false)
|
||||
self.container.view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.12, removeOnCompletion: false)
|
||||
containerView.addSubnode(self.container)
|
||||
|
||||
let buttonIcon = GlassBackgroundView.ContentImageView()
|
||||
|
|
@ -1206,23 +1215,27 @@ public class AttachmentController: ViewController, MinimizableController {
|
|||
}
|
||||
localGlassView.contentView.addSubview(buttonIcon)
|
||||
ComponentTransition(buttonTransition).animateBlur(layer: buttonIcon.layer, fromRadius: 10.0, toRadius: 0.0)
|
||||
ComponentTransition(buttonTransition).animateBlur(layer: sourceGlassView.contentView.layer, fromRadius: 10.0, toRadius: 0.0)
|
||||
|
||||
transition.updateBounds(layer: containerView.layer, bounds: CGRect(origin: CGPoint(x: 0.0, y: (initialFrame.height - initialFrame.width) * 0.5), size: CGSize(width: initialFrame.width, height: initialFrame.width)))
|
||||
transition.animateView {
|
||||
scaleTransition.updateBounds(layer: containerView.layer, bounds: CGRect(origin: CGPoint(x: 0.0, y: (initialFrame.height - initialFrame.width) * 0.5), size: CGSize(width: initialFrame.width, height: initialFrame.width)))
|
||||
cornersTransition.animateView {
|
||||
if #available(iOS 26.0, *) {
|
||||
containerView.cornerConfiguration = .uniformCorners(radius: .fixed(containerView.bounds.width * 0.5))
|
||||
} else {
|
||||
containerView.layer.cornerRadius = containerView.bounds.width * 0.5
|
||||
}
|
||||
}
|
||||
transition.updateTransformScale(layer: containerView.layer, scale: targetButtonScale)
|
||||
transition.updatePosition(layer: containerView.layer, position: targetButtonFrame.center, completion: { [weak self] _ in
|
||||
sourceGlassView.isHidden = false
|
||||
scaleTransition.updateTransformScale(layer: containerView.layer, scale: targetButtonScale)
|
||||
positionTransition.updatePosition(layer: containerView.layer, position: targetButtonFrame.center, completion: { [weak self] _ in
|
||||
let _ = self?.container.dismiss(transition: .immediate, completion: completion)
|
||||
self?.isAnimating = false
|
||||
})
|
||||
|
||||
sourceGlassView.isHidden = true
|
||||
localGlassView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, delay: 0.2, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false)
|
||||
//sourceGlassView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, delay: 0.27, timingFunction: CAMediaTimingFunctionName.linear.rawValue)
|
||||
scaleTransition.animateTransformScale(view: sourceGlassView, from: 1.0 / targetButtonScale)
|
||||
|
||||
positionTransition.animatePosition(layer: sourceGlassView.layer, from: self.view.convert(initialFrame.center, to: sourceGlassView.superview), to: sourceGlassView.center)
|
||||
}
|
||||
} else {
|
||||
let positionTransition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .easeInOut)
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ private final class AttachButtonComponent: CombinedComponent {
|
|||
let context: AccountContext
|
||||
let style: Style
|
||||
let type: AttachmentButtonType
|
||||
let isFirstOrLast: Bool
|
||||
let isSelected: Bool
|
||||
let strings: PresentationStrings
|
||||
let theme: PresentationTheme
|
||||
|
|
@ -144,6 +145,7 @@ private final class AttachButtonComponent: CombinedComponent {
|
|||
context: AccountContext,
|
||||
style: Style,
|
||||
type: AttachmentButtonType,
|
||||
isFirstOrLast: Bool,
|
||||
isSelected: Bool,
|
||||
strings: PresentationStrings,
|
||||
theme: PresentationTheme,
|
||||
|
|
@ -153,6 +155,7 @@ private final class AttachButtonComponent: CombinedComponent {
|
|||
self.context = context
|
||||
self.style = style
|
||||
self.type = type
|
||||
self.isFirstOrLast = isFirstOrLast
|
||||
self.isSelected = isSelected
|
||||
self.strings = strings
|
||||
self.theme = theme
|
||||
|
|
@ -170,6 +173,9 @@ private final class AttachButtonComponent: CombinedComponent {
|
|||
if lhs.type != rhs.type {
|
||||
return false
|
||||
}
|
||||
if lhs.isFirstOrLast != rhs.isFirstOrLast {
|
||||
return false
|
||||
}
|
||||
if lhs.isSelected != rhs.isSelected {
|
||||
return false
|
||||
}
|
||||
|
|
@ -321,7 +327,7 @@ private final class AttachButtonComponent: CombinedComponent {
|
|||
transition: .immediate
|
||||
)
|
||||
|
||||
let size = CGSize(width: max(context.availableSize.width, title.size.width + 24.0), height: context.availableSize.height)
|
||||
let size = CGSize(width: max(component.isFirstOrLast ? context.availableSize.width : 64.0, title.size.width + 24.0), height: context.availableSize.height)
|
||||
|
||||
let button = button.update(
|
||||
component: Rectangle(
|
||||
|
|
@ -1571,6 +1577,7 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate {
|
|||
context: self.context,
|
||||
style: self.panelStyle == .glass ? .glass : .legacy,
|
||||
type: type,
|
||||
isFirstOrLast: i == 0 || i == self.buttons.count - 1,
|
||||
isSelected: i == self.selectedIndex,
|
||||
strings: self.presentationData.strings,
|
||||
theme: self.presentationData.theme,
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||
self.signInWithAppleButton?.isHidden = true
|
||||
(self.signInWithAppleButton as? ASAuthorizationAppleIDButton)?.cornerRadius = 11
|
||||
}
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0)
|
||||
self.proceedNode.progressType = .embedded
|
||||
self.proceedNode.isHidden = true
|
||||
self.proceedNode.iconSpacing = 4.0
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ final class AuthorizationSequenceEmailEntryControllerNode: ASDisplayNode, UIText
|
|||
(self.signInWithAppleButton as? ASAuthorizationAppleIDButton)?.cornerRadius = 11
|
||||
}
|
||||
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0)
|
||||
self.proceedNode.progressType = .embedded
|
||||
|
||||
self.codeSeparatorNode = ASDisplayNode()
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT
|
|||
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
||||
self.codeField.textField.accessibilityHint = self.strings.Login_VoiceOver_Password
|
||||
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0)
|
||||
self.proceedNode.progressType = .embedded
|
||||
self.proceedNode.isEnabled = false
|
||||
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||
|
||||
self.phoneAndCountryNode = PhoneAndCountryNode(strings: strings, theme: theme)
|
||||
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0)
|
||||
self.proceedNode.progressType = .embedded
|
||||
self.proceedNode.isEnabled = false
|
||||
|
||||
|
|
@ -816,7 +816,7 @@ final class PhoneConfirmationController: ViewController {
|
|||
self.cancelButton.accessibilityTraits = [.button]
|
||||
self.cancelButton.accessibilityLabel = strings.Login_Edit
|
||||
|
||||
self.proceedNode = SolidRoundedButtonNode(title: strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.proceedNode = SolidRoundedButtonNode(title: strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: theme), height: 50.0, cornerRadius: 11.0)
|
||||
self.proceedNode.progressType = .embedded
|
||||
|
||||
let font = Font.with(size: 20.0, design: .regular, traits: [.monospacedNumbers])
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
|||
self.addPhotoButton.addSubnode(self.currentPhotoNode)
|
||||
self.addPhotoButton.allowsGroupOpacity = true
|
||||
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0)
|
||||
self.proceedNode.progressType = .embedded
|
||||
|
||||
super.init()
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ public final class AuthorizationSequenceSplashController: ViewController {
|
|||
|
||||
self.controller = RMIntroViewController(backgroundColor: theme.list.plainBackgroundColor, primaryColor: theme.list.itemPrimaryTextColor, buttonColor: theme.intro.startButtonColor, accentColor: theme.list.itemAccentColor, regularDotColor: theme.intro.dotColor, highlightedDotColor: theme.list.itemAccentColor, suggestedLocalizationSignal: localizationSignal)
|
||||
|
||||
self.startButton = SolidRoundedButtonNode(title: "Start Messaging", theme: SolidRoundedButtonTheme(theme: theme), height: 50.0, cornerRadius: 13.0, gloss: true)
|
||||
self.startButton = SolidRoundedButtonNode(title: "Start Messaging", theme: SolidRoundedButtonTheme(theme: theme), height: 50.0, cornerRadius: 13.0, isShimmering: true)
|
||||
|
||||
super.init(navigationBarPresentationData: nil)
|
||||
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ public final class ChatImportActivityScreen: ViewController {
|
|||
|
||||
self.statusButton = HighlightableButtonNode()
|
||||
|
||||
self.doneButton = SolidRoundedButtonNode(title: self.presentationData.strings.ChatImportActivity_OpenApp, theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: self.presentationData.theme.list.itemCheckColors.foregroundColor), height: 50.0, cornerRadius: 10.0, gloss: false)
|
||||
self.doneButton = SolidRoundedButtonNode(title: self.presentationData.strings.ChatImportActivity_OpenApp, theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: self.presentationData.theme.list.itemCheckColors.foregroundColor), height: 50.0, cornerRadius: 10.0, isShimmering: false)
|
||||
|
||||
super.init()
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ final class ChatListEmptyNode: ASDisplayNode {
|
|||
gloss = false
|
||||
}
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: theme), cornerRadius: 11.0, gloss: gloss)
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: theme), cornerRadius: 11.0, isShimmering: gloss)
|
||||
|
||||
self.secondaryButtonNode = HighlightableButtonNode()
|
||||
|
||||
|
|
|
|||
|
|
@ -66,10 +66,16 @@ public func isRoundEqualCorners(_ corners: ImageCorners) -> Bool {
|
|||
}
|
||||
|
||||
public struct ImageCorners: Equatable {
|
||||
public enum Curve {
|
||||
case circular
|
||||
case continuous
|
||||
}
|
||||
|
||||
public let topLeft: ImageCorner
|
||||
public let topRight: ImageCorner
|
||||
public let bottomLeft: ImageCorner
|
||||
public let bottomRight: ImageCorner
|
||||
public let curve: Curve
|
||||
|
||||
public var isEmpty: Bool {
|
||||
if self.topLeft != .Corner(0.0) {
|
||||
|
|
@ -87,22 +93,24 @@ public struct ImageCorners: Equatable {
|
|||
return true
|
||||
}
|
||||
|
||||
public init(radius: CGFloat) {
|
||||
public init(radius: CGFloat, curve: Curve = .circular) {
|
||||
self.topLeft = .Corner(radius)
|
||||
self.topRight = .Corner(radius)
|
||||
self.bottomLeft = .Corner(radius)
|
||||
self.bottomRight = .Corner(radius)
|
||||
self.curve = curve
|
||||
}
|
||||
|
||||
public init(topLeft: ImageCorner, topRight: ImageCorner, bottomLeft: ImageCorner, bottomRight: ImageCorner) {
|
||||
public init(topLeft: ImageCorner, topRight: ImageCorner, bottomLeft: ImageCorner, bottomRight: ImageCorner, curve: Curve = .circular) {
|
||||
self.topLeft = topLeft
|
||||
self.topRight = topRight
|
||||
self.bottomLeft = bottomLeft
|
||||
self.bottomRight = bottomRight
|
||||
self.curve = curve
|
||||
}
|
||||
|
||||
public init() {
|
||||
self.init(topLeft: .Corner(0.0), topRight: .Corner(0.0), bottomLeft: .Corner(0.0), bottomRight: .Corner(0.0))
|
||||
self.init(topLeft: .Corner(0.0), topRight: .Corner(0.0), bottomLeft: .Corner(0.0), bottomRight: .Corner(0.0), curve: .circular)
|
||||
}
|
||||
|
||||
public var extendedEdges: UIEdgeInsets {
|
||||
|
|
@ -113,12 +121,12 @@ public struct ImageCorners: Equatable {
|
|||
}
|
||||
|
||||
public func withRemovedTails() -> ImageCorners {
|
||||
return ImageCorners(topLeft: self.topLeft.withoutTail, topRight: self.topRight.withoutTail, bottomLeft: self.bottomLeft.withoutTail, bottomRight: self.bottomRight.withoutTail)
|
||||
return ImageCorners(topLeft: self.topLeft.withoutTail, topRight: self.topRight.withoutTail, bottomLeft: self.bottomLeft.withoutTail, bottomRight: self.bottomRight.withoutTail, curve: self.curve)
|
||||
}
|
||||
}
|
||||
|
||||
public func ==(lhs: ImageCorners, rhs: ImageCorners) -> Bool {
|
||||
return lhs.topLeft == rhs.topLeft && lhs.topRight == rhs.topRight && lhs.bottomLeft == rhs.bottomLeft && lhs.bottomRight == rhs.bottomRight
|
||||
return lhs.topLeft == rhs.topLeft && lhs.topRight == rhs.topRight && lhs.bottomLeft == rhs.bottomLeft && lhs.bottomRight == rhs.bottomRight && lhs.curve == rhs.curve
|
||||
}
|
||||
|
||||
public class ImageNode: ASDisplayNode {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import TelegramCore
|
|||
|
||||
public class AdditionalLinkItem: ListViewItem, ItemListItem {
|
||||
let presentationData: ItemListPresentationData
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let username: TelegramPeerUsername?
|
||||
public let sectionId: ItemListSectionId
|
||||
let style: ItemListStyle
|
||||
|
|
@ -18,6 +19,7 @@ public class AdditionalLinkItem: ListViewItem, ItemListItem {
|
|||
|
||||
public init(
|
||||
presentationData: ItemListPresentationData,
|
||||
systemStyle: ItemListSystemStyle = .legacy,
|
||||
username: TelegramPeerUsername?,
|
||||
sectionId: ItemListSectionId,
|
||||
style: ItemListStyle,
|
||||
|
|
@ -25,6 +27,7 @@ public class AdditionalLinkItem: ListViewItem, ItemListItem {
|
|||
tag: ItemListItemTag? = nil
|
||||
) {
|
||||
self.presentationData = presentationData
|
||||
self.systemStyle = systemStyle
|
||||
self.username = username
|
||||
self.sectionId = sectionId
|
||||
self.style = style
|
||||
|
|
@ -243,7 +246,13 @@ public class AdditionalLinkItemNode: ListViewItemNode, ItemListItemNode {
|
|||
|
||||
let leftInset: CGFloat = 65.0 + params.leftInset
|
||||
let rightInset: CGFloat = 16.0 + params.rightInset
|
||||
let verticalInset: CGFloat = subtitleAttributedString.string.isEmpty ? 14.0 : 8.0
|
||||
let verticalInset: CGFloat
|
||||
switch item.systemStyle {
|
||||
case .glass:
|
||||
verticalInset = subtitleAttributedString.string.isEmpty ? 18.0 : 12.0
|
||||
case .legacy:
|
||||
verticalInset = subtitleAttributedString.string.isEmpty ? 14.0 : 8.0
|
||||
}
|
||||
|
||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset - reorderInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: subtitleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset - reorderInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
|
@ -271,6 +280,7 @@ public class AdditionalLinkItemNode: ListViewItemNode, ItemListItemNode {
|
|||
|
||||
let contentSize = CGSize(width: params.width, height: max(minHeight, rawHeight))
|
||||
let separatorHeight = UIScreenPixel
|
||||
let separatorRightInset: CGFloat = item.systemStyle == .glass ? 16.0 : 0.0
|
||||
|
||||
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||
|
||||
|
|
@ -377,12 +387,12 @@ public class AdditionalLinkItemNode: ListViewItemNode, ItemListItemNode {
|
|||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: item.systemStyle == .glass) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - bottomStripeInset, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - bottomStripeInset - params.rightInset - separatorRightInset, height: separatorHeight))
|
||||
}
|
||||
|
||||
let iconSize: CGSize = CGSize(width: 40.0, height: 40.0)
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
|
|||
case let .mainLinkHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .mainLink(_, invite, peers, importersCount, isPublic):
|
||||
return ItemListPermanentInviteLinkItem(context: arguments.context, presentationData: presentationData, invite: invite, count: importersCount, peers: peers, displayButton: true, separateButtons: true, displayImporters: !isPublic, buttonColor: nil, sectionId: self.section, style: .blocks, copyAction: {
|
||||
return ItemListPermanentInviteLinkItem(context: arguments.context, presentationData: presentationData, systemStyle: .glass, invite: invite, count: importersCount, peers: peers, displayButton: true, separateButtons: true, displayImporters: !isPublic, buttonColor: nil, sectionId: self.section, style: .blocks, copyAction: {
|
||||
if let invite = invite {
|
||||
arguments.copyLink(invite)
|
||||
}
|
||||
|
|
@ -236,11 +236,11 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
|
|||
case let .linksHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .linksCreate(theme, text):
|
||||
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.plusIconImage(theme), title: text, sectionId: self.section, editing: false, action: {
|
||||
return ItemListPeerActionItem(presentationData: presentationData, systemStyle: .glass, icon: PresentationResourcesItemList.plusIconImage(theme), title: text, sectionId: self.section, editing: false, action: {
|
||||
arguments.createLink()
|
||||
})
|
||||
case let .link(_, _, invite, canEdit, _):
|
||||
return ItemListInviteLinkItem(context: arguments.context, presentationData: presentationData, invite: invite, share: false, sectionId: self.section, style: .blocks) { invite in
|
||||
return ItemListInviteLinkItem(context: arguments.context, presentationData: presentationData, systemStyle: .glass, invite: invite, share: false, sectionId: self.section, style: .blocks) { invite in
|
||||
arguments.openLink(invite)
|
||||
} contextAction: { invite, node, gesture in
|
||||
arguments.linkContextAction(invite, canEdit, node, gesture)
|
||||
|
|
@ -250,11 +250,11 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
|
|||
case let .revokedLinksHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .revokedLinksDeleteAll(theme, text):
|
||||
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.deleteIconImage(theme), title: text, sectionId: self.section, color: .destructive, editing: false, action: {
|
||||
return ItemListPeerActionItem(presentationData: presentationData, systemStyle: .glass, icon: PresentationResourcesItemList.deleteIconImage(theme), title: text, sectionId: self.section, color: .destructive, editing: false, action: {
|
||||
arguments.deleteAllRevokedLinks()
|
||||
})
|
||||
case let .revokedLink(_, _, invite):
|
||||
return ItemListInviteLinkItem(context: arguments.context, presentationData: presentationData, invite: invite, share: false, sectionId: self.section, style: .blocks) { invite in
|
||||
return ItemListInviteLinkItem(context: arguments.context, presentationData: presentationData, systemStyle: .glass, invite: invite, share: false, sectionId: self.section, style: .blocks) { invite in
|
||||
arguments.openLink(invite)
|
||||
} contextAction: { invite, node, gesture in
|
||||
arguments.linkContextAction(invite, false, node, gesture)
|
||||
|
|
@ -262,7 +262,7 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
|
|||
case let .adminsHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .admin(_, _, creator):
|
||||
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(), nameDisplayOrder: .firstLast, context: arguments.context, peer: EnginePeer(creator.peer.peer!), height: .peerList, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .none, label: creator.count > 1 ? .disclosure("\(creator.count)") : .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: nil), revealOptions: nil, switchValue: nil, enabled: true, highlighted: false, selectable: true, sectionId: self.section, action: {
|
||||
return ItemListPeerItem(presentationData: presentationData, systemStyle: .glass, dateTimeFormat: PresentationDateTimeFormat(), nameDisplayOrder: .firstLast, context: arguments.context, peer: EnginePeer(creator.peer.peer!), height: .peerList, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .none, label: creator.count > 1 ? .disclosure("\(creator.count)") : .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: nil), revealOptions: nil, switchValue: nil, enabled: true, highlighted: false, selectable: true, sectionId: self.section, action: {
|
||||
arguments.openAdmin(creator)
|
||||
}, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, contextAction: nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ private enum ItemBackgroundColor: Equatable {
|
|||
public class ItemListInviteLinkItem: ListViewItem, ItemListItem {
|
||||
let context: AccountContext
|
||||
let presentationData: ItemListPresentationData
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let invite: ExportedInvitation?
|
||||
let share: Bool
|
||||
public let sectionId: ItemListSectionId
|
||||
|
|
@ -70,6 +71,7 @@ public class ItemListInviteLinkItem: ListViewItem, ItemListItem {
|
|||
public init(
|
||||
context: AccountContext,
|
||||
presentationData: ItemListPresentationData,
|
||||
systemStyle: ItemListSystemStyle = .legacy,
|
||||
invite: ExportedInvitation?,
|
||||
share: Bool,
|
||||
sectionId: ItemListSectionId,
|
||||
|
|
@ -80,6 +82,7 @@ public class ItemListInviteLinkItem: ListViewItem, ItemListItem {
|
|||
) {
|
||||
self.context = context
|
||||
self.presentationData = presentationData
|
||||
self.systemStyle = systemStyle
|
||||
self.invite = invite
|
||||
self.share = share
|
||||
self.sectionId = sectionId
|
||||
|
|
@ -479,7 +482,13 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode {
|
|||
|
||||
let leftInset: CGFloat = 65.0 + params.leftInset
|
||||
let rightInset: CGFloat = 16.0 + params.rightInset
|
||||
let verticalInset: CGFloat = subtitleAttributedString.string.isEmpty ? 14.0 : 8.0
|
||||
let verticalInset: CGFloat
|
||||
switch item.systemStyle {
|
||||
case .glass:
|
||||
verticalInset = subtitleAttributedString.string.isEmpty ? 18.0 : 12.0
|
||||
case .legacy:
|
||||
verticalInset = subtitleAttributedString.string.isEmpty ? 14.0 : 8.0
|
||||
}
|
||||
|
||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: subtitleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
|
@ -508,6 +517,7 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode {
|
|||
|
||||
let contentSize = CGSize(width: params.width, height: max(minHeight, rawHeight))
|
||||
let separatorHeight = UIScreenPixel
|
||||
let separatorRightInset: CGFloat = item.systemStyle == .glass ? 16.0 : 0.0
|
||||
|
||||
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||
|
||||
|
|
@ -624,12 +634,12 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode {
|
|||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: item.systemStyle == .glass) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - bottomStripeInset, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - bottomStripeInset - params.rightInset - separatorRightInset, height: separatorHeight))
|
||||
}
|
||||
|
||||
let iconSize: CGSize = CGSize(width: 40.0, height: 40.0)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ private func actionButtonImage(color: UIColor) -> UIImage? {
|
|||
public class ItemListPermanentInviteLinkItem: ListViewItem, ItemListItem {
|
||||
let context: AccountContext
|
||||
let presentationData: ItemListPresentationData
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let invite: ExportedInvitation?
|
||||
let count: Int32
|
||||
let peers: [EnginePeer]
|
||||
|
|
@ -53,6 +54,7 @@ public class ItemListPermanentInviteLinkItem: ListViewItem, ItemListItem {
|
|||
public init(
|
||||
context: AccountContext,
|
||||
presentationData: ItemListPresentationData,
|
||||
systemStyle: ItemListSystemStyle = .legacy,
|
||||
invite: ExportedInvitation?,
|
||||
count: Int32,
|
||||
peers: [EnginePeer],
|
||||
|
|
@ -72,6 +74,7 @@ public class ItemListPermanentInviteLinkItem: ListViewItem, ItemListItem {
|
|||
) {
|
||||
self.context = context
|
||||
self.presentationData = presentationData
|
||||
self.systemStyle = systemStyle
|
||||
self.invite = invite
|
||||
self.count = count
|
||||
self.peers = peers
|
||||
|
|
@ -323,6 +326,8 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
|||
let contentSize: CGSize
|
||||
let insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
let separatorRightInset: CGFloat = item.systemStyle == .glass ? 16.0 : 0.0
|
||||
|
||||
let itemBackgroundColor: UIColor
|
||||
let itemSeparatorColor: UIColor
|
||||
|
||||
|
|
@ -389,7 +394,14 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
|||
|
||||
let avatarsContent = avatarsContext.update(peers: item.peers, animated: false)
|
||||
|
||||
let verticalInset: CGFloat = 16.0
|
||||
let verticalInset: CGFloat
|
||||
switch item.systemStyle {
|
||||
case .glass:
|
||||
verticalInset = 16.0
|
||||
case .legacy:
|
||||
verticalInset = 16.0
|
||||
}
|
||||
|
||||
let fieldHeight: CGFloat = 52.0
|
||||
let fieldSpacing: CGFloat = 16.0
|
||||
let buttonHeight: CGFloat = 50.0
|
||||
|
|
@ -439,7 +451,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
|||
strongSelf.topStripeNode.backgroundColor = itemSeparatorColor
|
||||
strongSelf.bottomStripeNode.backgroundColor = itemSeparatorColor
|
||||
strongSelf.backgroundNode.backgroundColor = itemBackgroundColor
|
||||
strongSelf.fieldNode.image = generateStretchableFilledCircleImage(diameter: 18.0, color: item.presentationData.theme.list.itemInputField.backgroundColor)
|
||||
strongSelf.fieldNode.image = generateStretchableFilledCircleImage(diameter: item.systemStyle == .glass ? 52.0 : 18.0, color: item.presentationData.theme.list.itemInputField.backgroundColor)
|
||||
strongSelf.addressButtonIconNode.image = actionButtonImage(color: item.presentationData.theme.list.itemInputField.controlColor)
|
||||
}
|
||||
|
||||
|
|
@ -496,12 +508,12 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
|||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: item.systemStyle == .glass) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - bottomStripeInset, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - bottomStripeInset - params.rightInset - separatorRightInset, height: separatorHeight))
|
||||
}
|
||||
|
||||
let fieldFrame = CGRect(origin: CGPoint(x: leftInset, y: verticalInset), size: CGSize(width: params.width - leftInset - rightInset, height: fieldHeight))
|
||||
|
|
@ -533,7 +545,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
|||
} else {
|
||||
buttonTheme = SolidRoundedButtonTheme(theme: item.presentationData.theme)
|
||||
}
|
||||
copyButtonNode = SolidRoundedButtonNode(theme: buttonTheme, height: 50.0, cornerRadius: 11.0)
|
||||
copyButtonNode = SolidRoundedButtonNode(theme: buttonTheme, glass: item.systemStyle == .glass, height: 52.0, cornerRadius: item.systemStyle == .glass ? 26.0 : 11.0)
|
||||
copyButtonNode.title = item.presentationData.strings.InviteLink_CopyShort
|
||||
copyButtonNode.pressed = { [weak self] in
|
||||
self?.item?.copyAction?()
|
||||
|
|
@ -552,7 +564,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
|||
} else {
|
||||
buttonTheme = SolidRoundedButtonTheme(theme: item.presentationData.theme)
|
||||
}
|
||||
shareButtonNode = SolidRoundedButtonNode(theme: buttonTheme, height: 50.0, cornerRadius: 11.0)
|
||||
shareButtonNode = SolidRoundedButtonNode(theme: buttonTheme, glass: item.systemStyle == .glass, height: 52.0, cornerRadius: item.systemStyle == .glass ? 26.0 : 11.0)
|
||||
if let invite = item.invite, invitationAvailability(invite).isZero {
|
||||
shareButtonNode.title = item.presentationData.strings.InviteLink_ReactivateLink
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public class ItemListExpandableSwitchItem: ListViewItem, ItemListItem {
|
|||
}
|
||||
|
||||
let presentationData: ItemListPresentationData
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let icon: UIImage?
|
||||
let title: String
|
||||
let value: Bool
|
||||
|
|
@ -56,8 +57,9 @@ public class ItemListExpandableSwitchItem: ListViewItem, ItemListItem {
|
|||
|
||||
public let selectable: Bool = true
|
||||
|
||||
public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, title: String, value: Bool, isExpanded: Bool, subItems: [SubItem], type: ItemListExpandableSwitchItemNodeType = .regular, enableInteractiveChanges: Bool = true, enabled: Bool = true, displayLocked: Bool = false, disableLeadingInset: Bool = false, maximumNumberOfLines: Int = 1, noCorners: Bool = false, sectionId: ItemListSectionId, style: ItemListStyle, updated: @escaping (Bool) -> Void, activatedWhileDisabled: @escaping () -> Void = {}, selectAction: @escaping () -> Void, subAction: @escaping (SubItem) -> Void, tag: ItemListItemTag? = nil) {
|
||||
public init(presentationData: ItemListPresentationData, systemStyle: ItemListSystemStyle = .legacy, icon: UIImage? = nil, title: String, value: Bool, isExpanded: Bool, subItems: [SubItem], type: ItemListExpandableSwitchItemNodeType = .regular, enableInteractiveChanges: Bool = true, enabled: Bool = true, displayLocked: Bool = false, disableLeadingInset: Bool = false, maximumNumberOfLines: Int = 1, noCorners: Bool = false, sectionId: ItemListSectionId, style: ItemListStyle, updated: @escaping (Bool) -> Void, activatedWhileDisabled: @escaping () -> Void = {}, selectAction: @escaping () -> Void, subAction: @escaping (SubItem) -> Void, tag: ItemListItemTag? = nil) {
|
||||
self.presentationData = presentationData
|
||||
self.systemStyle = systemStyle
|
||||
self.icon = icon
|
||||
self.title = title
|
||||
self.value = value
|
||||
|
|
@ -156,6 +158,7 @@ private final class SubItemNode: HighlightTrackingButtonNode {
|
|||
self.action = action
|
||||
|
||||
let leftInset: CGFloat = 60.0
|
||||
let separatorRightInset: CGFloat = 16.0
|
||||
|
||||
if themeUpdated {
|
||||
self.separatorNode.backgroundColor = presentationData.theme.list.itemBlocksSeparatorColor
|
||||
|
|
@ -179,7 +182,7 @@ private final class SubItemNode: HighlightTrackingButtonNode {
|
|||
|
||||
checkNode.setSelected(item.isSelected, animated: transition.isAnimated)
|
||||
|
||||
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: leftInset, y: size.height - UIScreenPixel), size: CGSize(width: size.width - leftInset, height: UIScreenPixel)))
|
||||
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: leftInset, y: size.height - UIScreenPixel), size: CGSize(width: size.width - leftInset - separatorRightInset, height: UIScreenPixel)))
|
||||
|
||||
self.textNode.attributedText = NSAttributedString(string: item.title, font: Font.regular(17.0), textColor: presentationData.theme.list.itemPrimaryTextColor)
|
||||
let titleSize = self.textNode.updateLayout(CGSize(width: size.width - leftInset, height: 100.0))
|
||||
|
|
@ -305,6 +308,8 @@ public class ItemListExpandableSwitchItemNode: ListViewItemNode, ItemListItemNod
|
|||
var contentSize: CGSize
|
||||
var insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
let separatorRightInset: CGFloat = item.systemStyle == .glass ? 16.0 : 0.0
|
||||
|
||||
let itemBackgroundColor: UIColor
|
||||
let itemSeparatorColor: UIColor
|
||||
|
||||
|
|
@ -324,12 +329,12 @@ public class ItemListExpandableSwitchItemNode: ListViewItemNode, ItemListItemNod
|
|||
case .plain:
|
||||
itemBackgroundColor = item.presentationData.theme.list.plainBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemPlainSeparatorColor
|
||||
contentSize = CGSize(width: params.width, height: 44.0)
|
||||
contentSize = CGSize(width: params.width, height: item.systemStyle == .glass ? 52.0 : 44.0)
|
||||
insets = itemListNeighborsPlainInsets(neighbors)
|
||||
case .blocks:
|
||||
itemBackgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemBlocksSeparatorColor
|
||||
contentSize = CGSize(width: params.width, height: 44.0)
|
||||
contentSize = CGSize(width: params.width, height: item.systemStyle == .glass ? 52.0 : 44.0)
|
||||
insets = itemListNeighborsGroupedInsets(neighbors, params)
|
||||
}
|
||||
|
||||
|
|
@ -347,13 +352,21 @@ public class ItemListExpandableSwitchItemNode: ListViewItemNode, ItemListItemNod
|
|||
|
||||
let titleValue = "\(item.subItems.filter(\.isSelected).count)/\(item.subItems.count)"
|
||||
let (titleValueLayout, titleValueApply) = makeTitleValueLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: titleValue, font: Font.bold(14.0), textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - params.rightInset - 64.0 - titleLayout.size.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let verticalInset: CGFloat
|
||||
switch item.systemStyle {
|
||||
case .glass:
|
||||
verticalInset = 15.0
|
||||
case .legacy:
|
||||
verticalInset = 11.0
|
||||
}
|
||||
|
||||
contentSize.height = max(contentSize.height, titleLayout.size.height + 22.0)
|
||||
contentSize.height = max(contentSize.height, titleLayout.size.height + verticalInset * 2.0)
|
||||
|
||||
let mainContentHeight = contentSize.height
|
||||
var effectiveSubItemsHeight: CGFloat = 0.0
|
||||
if item.isExpanded {
|
||||
effectiveSubItemsHeight = CGFloat(item.subItems.count) * 44.0
|
||||
effectiveSubItemsHeight = CGFloat(item.subItems.count) * (item.systemStyle == .glass ? 52.0 : 44.0)
|
||||
}
|
||||
contentSize.height += effectiveSubItemsHeight
|
||||
|
||||
|
|
@ -494,14 +507,14 @@ public class ItemListExpandableSwitchItemNode: ListViewItemNode, ItemListItemNod
|
|||
strongSelf.bottomTopStripeNode.isHidden = false
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: item.systemStyle == .glass) : nil
|
||||
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
animation.animator.updateFrame(layer: strongSelf.backgroundNode.layer, frame: backgroundFrame, completion: nil)
|
||||
animation.animator.updateFrame(layer: strongSelf.maskNode.layer, frame: backgroundFrame.insetBy(dx: params.leftInset, dy: 0.0), completion: nil)
|
||||
animation.animator.updateFrame(layer: strongSelf.topStripeNode.layer, frame: CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight)), completion: nil)
|
||||
animation.animator.updateFrame(layer: strongSelf.bottomTopStripeNode.layer, frame: CGRect(origin: CGPoint(x: bottomStripeInset, y: mainContentHeight - separatorHeight), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight)), completion: nil)
|
||||
animation.animator.updateFrame(layer: strongSelf.bottomStripeNode.layer, frame: CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight)), completion: nil)
|
||||
animation.animator.updateFrame(layer: strongSelf.bottomStripeNode.layer, frame: CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: layoutSize.width - bottomStripeInset - params.rightInset - separatorRightInset, height: separatorHeight)), completion: nil)
|
||||
}
|
||||
|
||||
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: floorToScreenPixels((mainContentHeight - titleLayout.size.height) / 2.0)), size: titleLayout.size)
|
||||
|
|
@ -564,12 +577,12 @@ public class ItemListExpandableSwitchItemNode: ListViewItemNode, ItemListItemNod
|
|||
lockedIconNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: 44.0 + UIScreenPixel + UIScreenPixel))
|
||||
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: (item.systemStyle == .glass ? 52.0 : 44.0) + UIScreenPixel + UIScreenPixel))
|
||||
|
||||
animation.animator.updateFrame(layer: strongSelf.subItemContainer.layer, frame: CGRect(origin: CGPoint(x: 0.0, y: mainContentHeight), size: CGSize(width: params.width, height: effectiveSubItemsHeight)), completion: nil)
|
||||
|
||||
var validIds: [AnyHashable] = []
|
||||
let subItemSize = CGSize(width: params.width - params.leftInset - params.rightInset, height: 44.0)
|
||||
let subItemSize = CGSize(width: params.width - params.leftInset - params.rightInset, height: item.systemStyle == .glass ? 52.0 : 44.0)
|
||||
var nextSubItemPosition = CGPoint(x: params.leftInset, y: 0.0)
|
||||
for subItem in item.subItems {
|
||||
validIds.append(subItem.id)
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ final class JoinLinkPreviewPeerContentNode: ASDisplayNode, ShareContentContainer
|
|||
self.peersScrollNode = ASScrollNode()
|
||||
self.peersScrollNode.view.showsHorizontalScrollIndicator = false
|
||||
|
||||
self.actionButtonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: theme), height: 52.0, cornerRadius: 11.0, gloss: false)
|
||||
self.actionButtonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: theme), height: 52.0, cornerRadius: 11.0)
|
||||
|
||||
let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: .green, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.opaqueItemBackgroundColor, avatarPlaceholderColor: theme.list.mediaPlaceholderColor)
|
||||
|
||||
|
|
|
|||
|
|
@ -1022,7 +1022,7 @@ public final class ListMessageFileItemNode: ListMessageNode {
|
|||
switch iconImage {
|
||||
case let .imageRepresentation(_, representation):
|
||||
let iconSize = CGSize(width: 40.0, height: 40.0)
|
||||
let imageCorners = ImageCorners(radius: iconCornerRadius)
|
||||
let imageCorners = ImageCorners(radius: iconCornerRadius, curve: item.systemStyle == .glass ? .continuous : .circular)
|
||||
let arguments = TransformImageArguments(corners: imageCorners, imageSize: representation.dimensions.cgSize.aspectFilled(iconSize), boundingSize: iconSize, intrinsicInsets: UIEdgeInsets(), emptyColor: item.presentationData.theme.theme.list.mediaPlaceholderColor)
|
||||
iconImageApply = iconImageLayout(arguments)
|
||||
case .albumArt:
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, ASScrollViewD
|
|||
self.cancelButton = HighlightableButtonNode()
|
||||
self.cancelButton.setTitle(self.presentationData.strings.Common_Cancel, with: Font.regular(17.0), with: accentColor, for: .normal)
|
||||
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, gloss: false)
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0)
|
||||
self.doneButton.title = self.presentationData.strings.Conversation_Timer_Send
|
||||
|
||||
self.unitLabelNode = ImmediateTextNode()
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ final class LocationPlaceholderNode: ASDisplayNode {
|
|||
self.textNode.textAlignment = .center
|
||||
self.textNode.maximumNumberOfLines = 0
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0, gloss: true)
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0, isShimmering: true)
|
||||
|
||||
self.cameraTextNode = ImmediateTextNode()
|
||||
self.cameraTextNode.isUserInteractionEnabled = false
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ final class MediaPickerPlaceholderNode: ASDisplayNode {
|
|||
self.textNode.textAlignment = .center
|
||||
self.textNode.maximumNumberOfLines = 0
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0, gloss: true)
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0, isShimmering: true)
|
||||
|
||||
self.cameraButtonNode = HighlightTrackingButtonNode()
|
||||
self.cameraButtonNode.alpha = 0.0
|
||||
|
|
|
|||
|
|
@ -2510,7 +2510,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||
let title: String
|
||||
let isEnabled: Bool
|
||||
if self.controllerNode.currentDisplayMode == .selected {
|
||||
title = self.presentationData.strings.Attachment_SelectedMedia(count)
|
||||
title = "" // self.presentationData.strings.Attachment_SelectedMedia(count)
|
||||
isEnabled = false
|
||||
} else {
|
||||
title = self.selectedCollectionValue?.localizedTitle ?? self.presentationData.strings.MediaPicker_Recents
|
||||
|
|
|
|||
|
|
@ -1562,7 +1562,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, ASS
|
|||
|
||||
self.inputNodes = inputNodes
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(title: buttonText, theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: self.presentationData.theme.list.itemCheckColors.foregroundColor), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.buttonNode = SolidRoundedButtonNode(title: buttonText, theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: self.presentationData.theme.list.itemCheckColors.foregroundColor), height: 50.0, cornerRadius: 11.0, isShimmering: false)
|
||||
|
||||
super.init()
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ private final class TwoFactorAuthSplashScreenNode: ViewControllerTracingNode {
|
|||
return iconNode
|
||||
}
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(title: buttonText, theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: self.presentationData.theme.list.itemCheckColors.foregroundColor), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.buttonNode = SolidRoundedButtonNode(title: buttonText, theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: self.presentationData.theme.list.itemCheckColors.foregroundColor), height: 50.0, cornerRadius: 11.0, isShimmering: false)
|
||||
self.buttonNode.isHidden = buttonText.isEmpty
|
||||
|
||||
super.init()
|
||||
|
|
|
|||
|
|
@ -10,21 +10,22 @@ swift_library(
|
|||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||
"//submodules/Display:Display",
|
||||
"//submodules/Postbox:Postbox",
|
||||
"//submodules/TelegramCore:TelegramCore",
|
||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||
"//submodules/AccountContext:AccountContext",
|
||||
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
||||
"//submodules/ComponentFlow:ComponentFlow",
|
||||
"//submodules/Components/ViewControllerComponent:ViewControllerComponent",
|
||||
"//submodules/Components/MultilineTextComponent:MultilineTextComponent",
|
||||
"//submodules/Components/SolidRoundedButtonComponent:SolidRoundedButtonComponent",
|
||||
"//submodules/Components/BundleIconComponent:BundleIconComponent",
|
||||
"//submodules/Components/AnimatedStickerComponent:AnimatedStickerComponent",
|
||||
"//submodules/Components/ActivityIndicatorComponent:ActivityIndicatorComponent",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/PresentationDataUtils",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/Components/ViewControllerComponent",
|
||||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
"//submodules/Components/AnimatedStickerComponent",
|
||||
"//submodules/Components/ActivityIndicatorComponent",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -9,10 +9,11 @@ import AccountContext
|
|||
import ComponentFlow
|
||||
import ViewControllerComponent
|
||||
import MultilineTextComponent
|
||||
import SolidRoundedButtonComponent
|
||||
import ButtonComponent
|
||||
import BundleIconComponent
|
||||
import AnimatedStickerComponent
|
||||
import ActivityIndicatorComponent
|
||||
import GlassBarButtonComponent
|
||||
|
||||
private final class CreateExternalMediaStreamScreenComponent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
|
@ -165,10 +166,13 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
static var body: Body {
|
||||
let background = Child(Rectangle.self)
|
||||
|
||||
let closeButton = Child(GlassBarButtonComponent.self)
|
||||
let title = Child(Text.self)
|
||||
|
||||
let animation = Child(AnimatedStickerComponent.self)
|
||||
let text = Child(MultilineTextComponent.self)
|
||||
let bottomText = Child(MultilineTextComponent.self)
|
||||
let button = Child(SolidRoundedButtonComponent.self)
|
||||
let button = Child(ButtonComponent.self)
|
||||
|
||||
let activityIndicator = Child(ActivityIndicatorComponent.self)
|
||||
|
||||
|
|
@ -187,12 +191,16 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
return { context in
|
||||
let topInset: CGFloat = 16.0
|
||||
let sideInset: CGFloat = 16.0
|
||||
let buttonSideInset: CGFloat = 36.0
|
||||
let credentialsSideInset: CGFloat = 16.0
|
||||
let credentialsTopInset: CGFloat = 9.0
|
||||
let credentialsTopInset: CGFloat = 12.0
|
||||
let credentialsTitleSpacing: CGFloat = 5.0
|
||||
|
||||
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
|
||||
let state = context.state
|
||||
|
||||
let theme = environment.theme.withModalBlocksBackground()
|
||||
|
||||
let mode = context.component.mode
|
||||
let controller = environment.controller
|
||||
|
||||
|
|
@ -200,14 +208,65 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
if environment.safeInsets.bottom.isZero {
|
||||
bottomInset = 16.0
|
||||
} else {
|
||||
bottomInset = 42.0
|
||||
bottomInset = 34.0
|
||||
}
|
||||
|
||||
let background = background.update(
|
||||
component: Rectangle(color: environment.theme.list.blocksBackgroundColor),
|
||||
component: Rectangle(color: theme.list.blocksBackgroundColor),
|
||||
availableSize: context.availableSize,
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(background
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height / 2.0))
|
||||
)
|
||||
|
||||
if case .create = context.component.mode {
|
||||
let closeButton = closeButton.update(
|
||||
component: GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: theme.overallDarkAppearance,
|
||||
state: .tintedGlass,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
guard let controller = controller() else {
|
||||
return
|
||||
}
|
||||
controller.dismiss()
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: 40.0, height: 40.0),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(closeButton
|
||||
.position(CGPoint(x: 16.0 + closeButton.size.width * 0.5, y: 16.0 + closeButton.size.height * 0.5))
|
||||
)
|
||||
}
|
||||
|
||||
let titleString: String
|
||||
switch context.component.mode {
|
||||
case .create:
|
||||
titleString = environment.strings.CreateExternalStream_Title
|
||||
case .view:
|
||||
titleString = environment.strings.CreateExternalStream_StreamKeyTitle
|
||||
}
|
||||
let title = title.update(
|
||||
component: Text(
|
||||
text: titleString,
|
||||
font: Font.semibold(17.0),
|
||||
color: theme.list.itemPrimaryTextColor
|
||||
),
|
||||
availableSize: context.availableSize,
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(title
|
||||
.position(CGPoint(x: context.availableSize.width * 0.5, y: 26.0 + title.size.height * 0.5))
|
||||
)
|
||||
|
||||
let animation = animation.update(
|
||||
component: AnimatedStickerComponent(
|
||||
|
|
@ -224,10 +283,10 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
|
||||
let text = text.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_Text, font: Font.regular(15.0), textColor: environment.theme.list.itemSecondaryTextColor, paragraphAlignment: .center)),
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_Text, font: Font.regular(13.0), textColor: theme.list.itemSecondaryTextColor, paragraphAlignment: .center)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.1
|
||||
lineSpacing: 0.2
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: context.availableSize.height),
|
||||
transition: context.transition
|
||||
|
|
@ -236,25 +295,32 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
let bottomText = Condition(mode == .create) {
|
||||
bottomText.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_StartStreamingInfo, font: Font.regular(15.0), textColor: environment.theme.list.itemSecondaryTextColor, paragraphAlignment: .center)),
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_StartStreamingInfo, font: Font.regular(13.0), textColor: theme.list.itemSecondaryTextColor, paragraphAlignment: .center)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.1
|
||||
lineSpacing: 0.2
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: context.availableSize.height),
|
||||
transition: context.transition
|
||||
)
|
||||
}
|
||||
|
||||
let buttonAttributedString = NSMutableAttributedString(string: mode == .create ? environment.strings.CreateExternalStream_StartStreaming : environment.strings.Common_Close, font: Font.semibold(17.0), textColor: theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center)
|
||||
let button = button.update(
|
||||
component: SolidRoundedButtonComponent(
|
||||
title: mode == .create ? environment.strings.CreateExternalStream_StartStreaming : environment.strings.Common_Close,
|
||||
theme: SolidRoundedButtonComponent.Theme(theme: environment.theme),
|
||||
font: .bold,
|
||||
fontSize: 17.0,
|
||||
height: 50.0,
|
||||
cornerRadius: 10.0,
|
||||
gloss: true,
|
||||
component: ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
style: .glass,
|
||||
color: mode == .create ? UIColor(rgb: 0xfa325a) : theme.list.itemCheckColors.fillColor,
|
||||
foreground: mode == .create ? .white : theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: mode == .create ? UIColor(rgb: 0xfa325a) : theme.list.itemCheckColors.fillColor,
|
||||
isShimmering: mode == .create
|
||||
),
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable(0),
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(buttonAttributedString)))
|
||||
),
|
||||
isEnabled: true,
|
||||
displaysProgress: false,
|
||||
action: { [weak state] in
|
||||
guard let state = state, let controller = controller() else {
|
||||
return
|
||||
|
|
@ -270,24 +336,20 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
}
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0),
|
||||
availableSize: CGSize(width: context.availableSize.width - buttonSideInset * 2.0, height: 52.0),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let credentialsItemHeight: CGFloat = 60.0
|
||||
let credentialsItemHeight: CGFloat = 64.0
|
||||
let credentialsAreaSize = CGSize(width: context.availableSize.width - sideInset * 2.0, height: credentialsItemHeight * 2.0)
|
||||
|
||||
context.add(background
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height / 2.0))
|
||||
)
|
||||
|
||||
let animationFrame = CGRect(origin: CGPoint(x: floor((context.availableSize.width - animation.size.width) / 2.0), y: environment.navigationHeight + topInset), size: animation.size)
|
||||
|
||||
context.add(animation
|
||||
.position(CGPoint(x: animationFrame.midX, y: animationFrame.midY))
|
||||
)
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: floor((context.availableSize.width - text.size.width) / 2.0), y: animationFrame.maxY + 16.0), size: text.size)
|
||||
let textFrame = CGRect(origin: CGPoint(x: floor((context.availableSize.width - text.size.width) / 2.0), y: animationFrame.maxY + 18.0), size: text.size)
|
||||
|
||||
context.add(text
|
||||
.position(CGPoint(x: textFrame.midX, y: textFrame.midY))
|
||||
|
|
@ -298,7 +360,7 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
if let credentials = context.state.credentials {
|
||||
let credentialsURLTitle = credentialsURLTitle.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_ServerUrl, font: Font.regular(14.0), textColor: environment.theme.list.itemPrimaryTextColor, paragraphAlignment: .left)),
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_ServerUrl, font: Font.regular(15.0), textColor: theme.list.itemPrimaryTextColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
|
|
@ -308,7 +370,7 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
|
||||
let credentialsKeyTitle = credentialsKeyTitle.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_StreamKey, font: Font.regular(14.0), textColor: environment.theme.list.itemPrimaryTextColor, paragraphAlignment: .left)),
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_StreamKey, font: Font.regular(15.0), textColor: theme.list.itemPrimaryTextColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
|
|
@ -318,7 +380,7 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
|
||||
let credentialsURLText = credentialsURLText.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: credentials.url, font: Font.regular(16.0), textColor: environment.theme.list.itemAccentColor, paragraphAlignment: .left)),
|
||||
text: .plain(NSAttributedString(string: credentials.url, font: Font.regular(17.0), textColor: theme.list.itemAccentColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
truncationType: .middle,
|
||||
maximumNumberOfLines: 1
|
||||
|
|
@ -329,30 +391,30 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
|
||||
let credentialsKeyText = credentialsKeyText.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: credentials.streamKey, font: Font.regular(16.0), textColor: environment.theme.list.itemAccentColor, paragraphAlignment: .left)),
|
||||
text: .plain(NSAttributedString(string: credentials.streamKey, font: Font.regular(17.0), textColor: theme.list.itemAccentColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
truncationType: .middle,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: CGSize(width: credentialsAreaSize.width - credentialsSideInset * 2.0 - 22.0, height: credentialsAreaSize.height),
|
||||
availableSize: CGSize(width: credentialsAreaSize.width - credentialsSideInset * 2.0 - 48.0, height: credentialsAreaSize.height),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let credentialsBackground = credentialsBackground.update(
|
||||
component: RoundedRectangle(color: environment.theme.list.itemBlocksBackgroundColor, cornerRadius: 10.0),
|
||||
component: RoundedRectangle(color: theme.list.itemBlocksBackgroundColor, cornerRadius: 26.0),
|
||||
availableSize: credentialsAreaSize,
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let credentialsStripe = credentialsStripe.update(
|
||||
component: Rectangle(color: environment.theme.list.itemPlainSeparatorColor),
|
||||
availableSize: CGSize(width: credentialsAreaSize.width - credentialsSideInset, height: UIScreenPixel),
|
||||
component: Rectangle(color: theme.list.itemPlainSeparatorColor),
|
||||
availableSize: CGSize(width: credentialsAreaSize.width - credentialsSideInset * 2.0, height: UIScreenPixel),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let credentialsCopyURLButton = credentialsCopyURLButton.update(
|
||||
component: Button(
|
||||
content: AnyComponent(BundleIconComponent(name: "Chat/Context Menu/Copy", tintColor: environment.theme.list.itemAccentColor)),
|
||||
content: AnyComponent(BundleIconComponent(name: "Chat/Context Menu/Copy", tintColor: theme.list.itemAccentColor)),
|
||||
action: { [weak state] in
|
||||
guard let state = state else {
|
||||
return
|
||||
|
|
@ -366,7 +428,7 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
|
||||
let credentialsCopyKeyButton = credentialsCopyKeyButton.update(
|
||||
component: Button(
|
||||
content: AnyComponent(BundleIconComponent(name: "Chat/Context Menu/Copy", tintColor: environment.theme.list.itemAccentColor)),
|
||||
content: AnyComponent(BundleIconComponent(name: "Chat/Context Menu/Copy", tintColor: theme.list.itemAccentColor)),
|
||||
action: { [weak state] in
|
||||
guard let state = state else {
|
||||
return
|
||||
|
|
@ -393,7 +455,7 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
.position(CGPoint(x: credentialsFrame.minX + credentialsSideInset + credentialsURLText.size.width / 2.0, y: credentialsFrame.minY + credentialsTopInset + credentialsTitleSpacing + credentialsURLTitle.size.height + credentialsURLText.size.height / 2.0))
|
||||
)
|
||||
context.add(credentialsCopyURLButton
|
||||
.position(CGPoint(x: credentialsFrame.maxX - 12.0 - credentialsCopyURLButton.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight / 2.0))
|
||||
.position(CGPoint(x: credentialsFrame.maxX - 4.0 - credentialsCopyURLButton.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight / 2.0))
|
||||
)
|
||||
|
||||
context.add(credentialsKeyTitle
|
||||
|
|
@ -403,11 +465,11 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
.position(CGPoint(x: credentialsFrame.minX + credentialsSideInset + credentialsKeyText.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight + credentialsTopInset + credentialsTitleSpacing + credentialsKeyTitle.size.height + credentialsKeyText.size.height / 2.0))
|
||||
)
|
||||
context.add(credentialsCopyKeyButton
|
||||
.position(CGPoint(x: credentialsFrame.maxX - 12.0 - credentialsCopyKeyButton.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight + credentialsItemHeight / 2.0))
|
||||
.position(CGPoint(x: credentialsFrame.maxX - 4.0 - credentialsCopyKeyButton.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight + credentialsItemHeight / 2.0))
|
||||
)
|
||||
} else if !context.state.isDelayingLoadingIndication {
|
||||
let activityIndicator = activityIndicator.update(
|
||||
component: ActivityIndicatorComponent(color: environment.theme.list.controlSecondaryColor),
|
||||
component: ActivityIndicatorComponent(color: theme.list.controlSecondaryColor),
|
||||
availableSize: CGSize(width: 100.0, height: 100.0),
|
||||
transition: context.transition
|
||||
)
|
||||
|
|
@ -416,11 +478,11 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
)
|
||||
}
|
||||
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: context.availableSize.height - bottomInset - button.size.height), size: button.size)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: buttonSideInset, y: context.availableSize.height - bottomInset - button.size.height), size: button.size)
|
||||
|
||||
if let bottomText = bottomText {
|
||||
context.add(bottomText
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: buttonFrame.minY - 14.0 - bottomText.size.height / 2.0))
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: buttonFrame.minY - 12.0 - bottomText.size.height / 2.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -448,19 +510,13 @@ public final class CreateExternalMediaStreamScreen: ViewControllerComponentConta
|
|||
self.peerId = peerId
|
||||
self.mode = mode
|
||||
|
||||
super.init(context: context, component: CreateExternalMediaStreamScreenComponent(context: context, peerId: peerId, mode: mode, credentialsPromise: credentialsPromise), navigationBarAppearance: .transparent, theme: .dark)
|
||||
super.init(context: context, component: CreateExternalMediaStreamScreenComponent(context: context, peerId: peerId, mode: mode, credentialsPromise: credentialsPromise), navigationBarAppearance: .none, theme: .dark)
|
||||
|
||||
self._hasGlassStyle = true
|
||||
|
||||
self.navigationPresentation = .modal
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
switch mode {
|
||||
case .create:
|
||||
self.title = presentationData.strings.CreateExternalStream_Title
|
||||
case .view:
|
||||
self.title = presentationData.strings.CreateExternalStream_StreamKeyTitle
|
||||
}
|
||||
|
||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed))
|
||||
|
||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: UIView())
|
||||
|
||||
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
|||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .permission(_, _, title, value, rights, enabled, subPermissions, isExpanded):
|
||||
if !subPermissions.isEmpty {
|
||||
return ItemListExpandableSwitchItem(presentationData: presentationData, title: title, value: value, isExpanded: isExpanded, subItems: subPermissions.map { item in
|
||||
return ItemListExpandableSwitchItem(presentationData: presentationData, systemStyle: .glass, title: title, value: value, isExpanded: isExpanded, subItems: subPermissions.map { item in
|
||||
return ItemListExpandableSwitchItem.SubItem(
|
||||
id: AnyHashable(item.flags.rawValue),
|
||||
title: item.title,
|
||||
|
|
@ -390,7 +390,7 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
|||
}
|
||||
})
|
||||
} else {
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: title, value: value, type: .icon, enableInteractiveChanges: enabled != nil, enabled: enabled ?? true, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: title, value: value, type: .icon, enableInteractiveChanges: enabled != nil, enabled: enabled ?? true, sectionId: self.section, style: .blocks, updated: { value in
|
||||
if let _ = enabled {
|
||||
arguments.updatePermission(rights, value)
|
||||
} else {
|
||||
|
|
@ -403,7 +403,7 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
|||
case let .slowmodeHeader(_, value):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: value, sectionId: self.section)
|
||||
case let .slowmode(theme, strings, value):
|
||||
return ChatSlowmodeItem(theme: theme, strings: strings, value: value, enabled: true, sectionId: self.section, updated: { value in
|
||||
return ChatSlowmodeItem(theme: theme, strings: strings, systemStyle: .glass, value: value, enabled: true, sectionId: self.section, updated: { value in
|
||||
arguments.updateSlowmode(value)
|
||||
})
|
||||
case let .slowmodeInfo(_, value):
|
||||
|
|
@ -411,7 +411,7 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
|||
case let .conversionHeader(_, value):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: value, sectionId: self.section)
|
||||
case let .conversion(_, text):
|
||||
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks) {
|
||||
return ItemListActionItem(presentationData: presentationData, systemStyle: .glass, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks) {
|
||||
arguments.presentConversionToBroadcastGroup()
|
||||
}
|
||||
case let .conversionInfo(_, value):
|
||||
|
|
@ -419,7 +419,7 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
|||
arguments.openChannelExample()
|
||||
}
|
||||
case let .chargeForMessages(_, title, value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: title, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: title, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateStarsAmount(value ? StarsAmount(value: 400, nanos: 0) : nil, true)
|
||||
})
|
||||
case let .chargeForMessagesInfo(_, value):
|
||||
|
|
@ -427,29 +427,29 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
|||
case let .messagePriceHeader(_, value):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: value, sectionId: self.section)
|
||||
case let .messagePrice(_, value, maxValue, price):
|
||||
return MessagePriceItem(theme: presentationData.theme, strings: presentationData.strings, isEnabled: true, minValue: 1, maxValue: maxValue, value: value, price: price, sectionId: self.section, updated: { value, apply in
|
||||
return MessagePriceItem(theme: presentationData.theme, strings: presentationData.strings, systemStyle: .glass, isEnabled: true, minValue: 1, maxValue: maxValue, value: value, price: price, sectionId: self.section, updated: { value, apply in
|
||||
arguments.updateStarsAmount(StarsAmount(value: value, nanos: 0), apply)
|
||||
}, openSetCustom: nil)
|
||||
case let .messagePriceInfo(_, value):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(value), sectionId: self.section)
|
||||
case let .unrestrictBoostersSwitch(_, title, value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: title, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: title, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateUnrestrictBoosters(value ? 1 : 0)
|
||||
})
|
||||
case let .unrestrictBoosters(theme, strings, value):
|
||||
return ChatUnrestrictBoostersItem(theme: theme, strings: strings, value: value, enabled: true, sectionId: self.section, updated: { value in
|
||||
return ChatUnrestrictBoostersItem(theme: theme, strings: strings, systemStyle: .glass, value: value, enabled: true, sectionId: self.section, updated: { value in
|
||||
arguments.updateUnrestrictBoosters(value)
|
||||
})
|
||||
case let .unrestrictBoostersInfo(_, value):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(value), sectionId: self.section)
|
||||
case let .kicked(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: text, label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openKicked()
|
||||
})
|
||||
case let .exceptionsHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .add(theme, text):
|
||||
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.addPersonIcon(theme), title: text, sectionId: self.section, editing: false, action: {
|
||||
return ItemListPeerActionItem(presentationData: presentationData, systemStyle: .glass, icon: PresentationResourcesItemList.addPersonIcon(theme), title: text, sectionId: self.section, editing: false, action: {
|
||||
arguments.addPeer()
|
||||
})
|
||||
case let .peerItem(_, strings, dateTimeFormat, nameDisplayOrder, _, participant, editing, enabled, canOpen, defaultBannedRights):
|
||||
|
|
@ -477,7 +477,7 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
|||
default:
|
||||
break
|
||||
}
|
||||
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: EnginePeer(participant.peer), presence: nil, text: text, label: .none, editing: editing, switchValue: nil, enabled: enabled, selectable: true, sectionId: self.section, action: canOpen ? {
|
||||
return ItemListPeerItem(presentationData: presentationData, systemStyle: .glass, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: EnginePeer(participant.peer), presence: nil, text: text, label: .none, editing: editing, switchValue: nil, enabled: enabled, selectable: true, sectionId: self.section, action: canOpen ? {
|
||||
arguments.openPeer(participant.participant)
|
||||
} : {
|
||||
arguments.openPeerInfo(EnginePeer(participant.peer))
|
||||
|
|
|
|||
|
|
@ -623,11 +623,11 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
|
|||
case let .typeHeader(_, title):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
|
||||
case let .typePublic(_, text, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
return ItemListCheckboxItem(presentationData: presentationData, systemStyle: .glass, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.updateCurrentType(.publicChannel)
|
||||
})
|
||||
case let .typePrivate(_, text, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
return ItemListCheckboxItem(presentationData: presentationData, systemStyle: .glass, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.updateCurrentType(.privateChannel)
|
||||
})
|
||||
case let .typeInfo(_, text):
|
||||
|
|
@ -641,7 +641,7 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
|
|||
case let .privateLinkHeader(_, title):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
|
||||
case let .privateLink(_, invite, peers, importersCount, displayImporters):
|
||||
return ItemListPermanentInviteLinkItem(context: arguments.context, presentationData: presentationData, invite: invite, count: importersCount, peers: peers, displayButton: true, displayImporters: displayImporters, buttonColor: nil, sectionId: self.section, style: .blocks, copyAction: {
|
||||
return ItemListPermanentInviteLinkItem(context: arguments.context, presentationData: presentationData, systemStyle: .glass, invite: invite, count: importersCount, peers: peers, displayButton: true, displayImporters: displayImporters, buttonColor: nil, sectionId: self.section, style: .blocks, copyAction: {
|
||||
if let invite = invite {
|
||||
arguments.copyLink(invite)
|
||||
}
|
||||
|
|
@ -658,7 +658,7 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
|
|||
}, openCallAction: {
|
||||
})
|
||||
case let .editablePublicLink(theme, _, placeholder, currentText):
|
||||
return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: "t.me/", textColor: theme.list.itemPrimaryTextColor), text: currentText, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: false), clearType: .always, tag: ChannelVisibilityEntryTag.publicLink, sectionId: self.section, textUpdated: { updatedText in
|
||||
return ItemListSingleLineInputItem(presentationData: presentationData, systemStyle: .glass, title: NSAttributedString(string: "t.me/", textColor: theme.list.itemPrimaryTextColor), text: currentText, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: false), clearType: .always, tag: ChannelVisibilityEntryTag.publicLink, sectionId: self.section, textUpdated: { updatedText in
|
||||
arguments.updatePublicLinkText(currentText, updatedText)
|
||||
}, updatedFocus: { focus in
|
||||
if focus {
|
||||
|
|
@ -669,7 +669,7 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
|
|||
case let .privateLinkInfo(_, text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case let .privateLinkManage(theme, text):
|
||||
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.linkIcon(theme), title: text, sectionId: self.section, editing: false, action: {
|
||||
return ItemListPeerActionItem(presentationData: presentationData, systemStyle: .glass, icon: PresentationResourcesItemList.linkIcon(theme), title: text, sectionId: self.section, editing: false, action: {
|
||||
arguments.manageInviteLinks()
|
||||
})
|
||||
case let .privateLinkManageInfo(_, text):
|
||||
|
|
@ -707,7 +707,7 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
|
|||
if let addressName = peer.addressName {
|
||||
label = "t.me/" + addressName
|
||||
}
|
||||
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer, presence: nil, text: .text(label, .secondary), label: .none, editing: editing, switchValue: nil, enabled: enabled, selectable: true, sectionId: self.section, action: nil, setPeerIdWithRevealedOptions: { previousId, id in
|
||||
return ItemListPeerItem(presentationData: presentationData, systemStyle: .glass, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer, presence: nil, text: .text(label, .secondary), label: .none, editing: editing, switchValue: nil, enabled: enabled, selectable: true, sectionId: self.section, action: nil, setPeerIdWithRevealedOptions: { previousId, id in
|
||||
arguments.setPeerIdWithRevealedOptions(previousId, id)
|
||||
}, removePeer: { peerId in
|
||||
arguments.revokePeerId(peerId)
|
||||
|
|
@ -715,7 +715,7 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
|
|||
case let .additionalLinkHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .additionalLink(_, link, _):
|
||||
return AdditionalLinkItem(presentationData: presentationData, username: link, sectionId: self.section, style: .blocks, tapAction: {
|
||||
return AdditionalLinkItem(presentationData: presentationData, systemStyle: .glass, username: link, sectionId: self.section, style: .blocks, tapAction: {
|
||||
if !link.flags.contains(.isEditable) {
|
||||
if link.flags.contains(.isActive) {
|
||||
arguments.deactivateLink(link.username)
|
||||
|
|
@ -729,16 +729,16 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
|
|||
case let .joinToSendHeader(_, title):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
|
||||
case let .joinToSendEveryone(_, text, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
return ItemListCheckboxItem(presentationData: presentationData, systemStyle: .glass, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.updateJoinToSend(.everyone)
|
||||
arguments.toggleApproveMembers(false)
|
||||
})
|
||||
case let .joinToSendMembers(_, text, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
return ItemListCheckboxItem(presentationData: presentationData, systemStyle: .glass, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.updateJoinToSend(.members)
|
||||
})
|
||||
case let .approveMembers(_, text, selected):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: text, value: selected, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: text, value: selected, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.toggleApproveMembers(value)
|
||||
})
|
||||
case let .approveMembersInfo(_, text):
|
||||
|
|
@ -746,7 +746,7 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
|
|||
case let .forwardingHeader(_, title):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
|
||||
case let .forwardingDisabled(_, text, selected):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: text, value: selected, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: text, value: selected, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.toggleForwarding(!value)
|
||||
})
|
||||
case let .forwardingInfo(_, text):
|
||||
|
|
|
|||
|
|
@ -13,13 +13,15 @@ import PresentationDataUtils
|
|||
class ChatSlowmodeItem: ListViewItem, ItemListItem {
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let value: Int32
|
||||
let sectionId: ItemListSectionId
|
||||
let updated: (Int32) -> Void
|
||||
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, value: Int32, enabled: Bool, sectionId: ItemListSectionId, updated: @escaping (Int32) -> Void) {
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, systemStyle: ItemListSystemStyle, value: Int32, enabled: Bool, sectionId: ItemListSectionId, updated: @escaping (Int32) -> Void) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.systemStyle = systemStyle
|
||||
self.value = value
|
||||
self.sectionId = sectionId
|
||||
self.updated = updated
|
||||
|
|
@ -181,6 +183,7 @@ class ChatSlowmodeItemNode: ListViewItemNode {
|
|||
let contentSize: CGSize
|
||||
let insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
let separatorRightInset: CGFloat = item.systemStyle == .glass ? 16.0 : 0.0
|
||||
|
||||
var textLayoutAndApply: [(TextNodeLayout, () -> TextNode)] = []
|
||||
|
||||
|
|
@ -248,12 +251,12 @@ class ChatSlowmodeItemNode: ListViewItemNode {
|
|||
bottomStripeOffset = 0.0
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: item.systemStyle == .glass) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset - params.rightInset - separatorRightInset, height: separatorHeight))
|
||||
|
||||
for (_, apply) in textLayoutAndApply {
|
||||
let _ = apply()
|
||||
|
|
|
|||
|
|
@ -13,13 +13,15 @@ import PresentationDataUtils
|
|||
class ChatUnrestrictBoostersItem: ListViewItem, ItemListItem {
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let value: Int32
|
||||
let sectionId: ItemListSectionId
|
||||
let updated: (Int32) -> Void
|
||||
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, value: Int32, enabled: Bool, sectionId: ItemListSectionId, updated: @escaping (Int32) -> Void) {
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, systemStyle: ItemListSystemStyle = .legacy, value: Int32, enabled: Bool, sectionId: ItemListSectionId, updated: @escaping (Int32) -> Void) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.systemStyle = systemStyle
|
||||
self.value = value
|
||||
self.sectionId = sectionId
|
||||
self.updated = updated
|
||||
|
|
@ -190,6 +192,7 @@ class ChatUnrestrictBoostersItemNode: ListViewItemNode {
|
|||
let contentSize: CGSize
|
||||
let insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
let separatorRightInset: CGFloat = item.systemStyle == .glass ? 16.0 : 0.0
|
||||
|
||||
var textLayoutAndApply: [(TextNodeLayout, () -> TextNode)] = []
|
||||
|
||||
|
|
@ -257,12 +260,12 @@ class ChatUnrestrictBoostersItemNode: ListViewItemNode {
|
|||
bottomStripeOffset = 0.0
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: item.systemStyle == .glass) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset - params.rightInset - separatorRightInset, height: separatorHeight))
|
||||
|
||||
for (_, apply) in textLayoutAndApply {
|
||||
let _ = apply()
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import AccountContext
|
|||
public class ItemListReactionItem: ListViewItem, ItemListItem {
|
||||
let context: AccountContext
|
||||
let presentationData: ItemListPresentationData
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let availableReactions: AvailableReactions?
|
||||
let reaction: MessageReaction.Reaction
|
||||
let title: String
|
||||
|
|
@ -26,6 +27,7 @@ public class ItemListReactionItem: ListViewItem, ItemListItem {
|
|||
public init(
|
||||
context: AccountContext,
|
||||
presentationData: ItemListPresentationData,
|
||||
systemStyle: ItemListSystemStyle = .glass,
|
||||
availableReactions: AvailableReactions?,
|
||||
reaction: MessageReaction.Reaction,
|
||||
title: String,
|
||||
|
|
@ -38,6 +40,7 @@ public class ItemListReactionItem: ListViewItem, ItemListItem {
|
|||
) {
|
||||
self.context = context
|
||||
self.presentationData = presentationData
|
||||
self.systemStyle = systemStyle
|
||||
self.availableReactions = availableReactions
|
||||
self.reaction = reaction
|
||||
self.title = title
|
||||
|
|
@ -200,6 +203,8 @@ public class ItemListReactionItemNode: ListViewItemNode, ItemListItemNode {
|
|||
var contentSize: CGSize
|
||||
var insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
let separatorRightInset: CGFloat = item.systemStyle == .glass ? 16.0 : 0.0
|
||||
|
||||
let itemBackgroundColor: UIColor
|
||||
let itemSeparatorColor: UIColor
|
||||
|
||||
|
|
@ -228,7 +233,15 @@ public class ItemListReactionItemNode: ListViewItemNode, ItemListItemNode {
|
|||
|
||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.title, font: titleFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.leftInset - params.rightInset - 80.0 - sideImageInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
contentSize.height = max(contentSize.height, titleLayout.size.height + 22.0)
|
||||
|
||||
let verticalInset: CGFloat
|
||||
switch item.systemStyle {
|
||||
case .glass:
|
||||
verticalInset = 15.0
|
||||
case .legacy:
|
||||
verticalInset = 11.0
|
||||
}
|
||||
contentSize.height = max(contentSize.height, titleLayout.size.height + verticalInset * 2.0)
|
||||
|
||||
if !item.enabled {
|
||||
if currentDisabledOverlayNode == nil {
|
||||
|
|
@ -350,12 +363,12 @@ public class ItemListReactionItemNode: ListViewItemNode, ItemListItemNode {
|
|||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: item.systemStyle == .glass) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: layoutSize.width - bottomStripeInset - params.rightInset - separatorRightInset, height: separatorHeight))
|
||||
}
|
||||
|
||||
if strongSelf.imageNode == nil, let availableReactions = item.availableReactions {
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ private enum PeerAllowedReactionListControllerEntry: ItemListNodeEntry {
|
|||
let arguments = arguments as! PeerAllowedReactionListControllerArguments
|
||||
switch self {
|
||||
case let .allowSwitch(text, value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
if value {
|
||||
arguments.setMode(.some, false)
|
||||
} else {
|
||||
|
|
@ -185,6 +185,7 @@ private enum PeerAllowedReactionListControllerEntry: ItemListNodeEntry {
|
|||
case let .allowAll(text, isEnabled):
|
||||
return ItemListCheckboxItem(
|
||||
presentationData: presentationData,
|
||||
systemStyle: .glass,
|
||||
icon: nil,
|
||||
iconSize: nil,
|
||||
iconPlacement: .default,
|
||||
|
|
@ -204,6 +205,7 @@ private enum PeerAllowedReactionListControllerEntry: ItemListNodeEntry {
|
|||
case let .allowSome(text, isEnabled):
|
||||
return ItemListCheckboxItem(
|
||||
presentationData: presentationData,
|
||||
systemStyle: .glass,
|
||||
icon: nil,
|
||||
iconSize: nil,
|
||||
iconPlacement: .default,
|
||||
|
|
@ -223,6 +225,7 @@ private enum PeerAllowedReactionListControllerEntry: ItemListNodeEntry {
|
|||
case let .allowNone(text, isEnabled):
|
||||
return ItemListCheckboxItem(
|
||||
presentationData: presentationData,
|
||||
systemStyle: .glass,
|
||||
icon: nil,
|
||||
iconSize: nil,
|
||||
iconPlacement: .default,
|
||||
|
|
@ -247,6 +250,7 @@ private enum PeerAllowedReactionListControllerEntry: ItemListNodeEntry {
|
|||
return ItemListReactionItem(
|
||||
context: arguments.context,
|
||||
presentationData: presentationData,
|
||||
systemStyle: .glass,
|
||||
availableReactions: availableReactions,
|
||||
reaction: reaction,
|
||||
title: text,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import PresentationDataUtils
|
|||
import ViewControllerComponent
|
||||
import AccountContext
|
||||
import SolidRoundedButtonComponent
|
||||
import ButtonComponent
|
||||
import MultilineTextComponent
|
||||
import MultilineTextWithEntitiesComponent
|
||||
import BundleIconComponent
|
||||
|
|
@ -2098,7 +2099,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||
context.add(optionsSection
|
||||
.position(CGPoint(x: availableWidth / 2.0, y: size.height + optionsSection.size.height / 2.0))
|
||||
.clipsToBounds(true)
|
||||
.cornerRadius(10.0)
|
||||
.cornerRadius(26.0)
|
||||
)
|
||||
size.height += optionsSection.size.height
|
||||
|
||||
|
|
@ -3836,8 +3837,9 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
|||
}
|
||||
}
|
||||
|
||||
let buttonSideInset: CGFloat = 36.0
|
||||
|
||||
let controller = environment.controller
|
||||
let sideInset: CGFloat = 16.0
|
||||
let button = button.update(
|
||||
component: SolidRoundedButtonComponent(
|
||||
title: buttonTitle,
|
||||
|
|
@ -3852,8 +3854,8 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
|||
],
|
||||
foregroundColor: .white
|
||||
),
|
||||
height: 50.0,
|
||||
cornerRadius: 11.0,
|
||||
height: 52.0,
|
||||
cornerRadius: 26.0,
|
||||
gloss: true,
|
||||
isLoading: state.inProgress,
|
||||
action: {
|
||||
|
|
@ -3865,7 +3867,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
|||
}
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - environment.safeInsets.left - environment.safeInsets.right, height: 50.0),
|
||||
availableSize: CGSize(width: context.availableSize.width - buttonSideInset * 2.0 - environment.safeInsets.left - environment.safeInsets.right, height: 52.0),
|
||||
transition: context.transition)
|
||||
|
||||
let bottomPanel = bottomPanel.update(
|
||||
|
|
|
|||
|
|
@ -1535,7 +1535,7 @@ private class FooterNode: ASDisplayNode {
|
|||
self.backgroundNode = NavigationBackgroundNode(color: theme.rootController.tabBar.backgroundColor)
|
||||
self.separatorNode = ASDisplayNode()
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0, gloss: gloss)
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0, isShimmering: gloss)
|
||||
self.buttonNode.title = title
|
||||
|
||||
self.coverNode = ASDisplayNode()
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ final class PremiumOptionComponent: CombinedComponent {
|
|||
return { context in
|
||||
let component = context.component
|
||||
|
||||
var insets = UIEdgeInsets(top: 11.0, left: 46.0, bottom: 13.0, right: 16.0)
|
||||
var insets = UIEdgeInsets(top: 15.0, left: 46.0, bottom: 17.0, right: 16.0)
|
||||
|
||||
let label = label.update(
|
||||
component: MultilineTextComponent(
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ public final class QrCodeScreen: ViewController {
|
|||
self.cancelButton = HighlightableButtonNode()
|
||||
self.cancelButton.setTitle(self.presentationData.strings.Common_Done, with: Font.bold(17.0), with: accentColor, for: .normal)
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, gloss: false)
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, isShimmering: false)
|
||||
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.maximumNumberOfLines = 3
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ final class DeleteAccountFooterItemNode: ItemListControllerFooterItemNode {
|
|||
self.clipNode = ASDisplayNode()
|
||||
self.clipNode.clipsToBounds = true
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0, gloss: true)
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0, isShimmering: true)
|
||||
|
||||
self.secondaryButtonNode = HighlightableButtonNode()
|
||||
|
||||
|
|
|
|||
|
|
@ -118,11 +118,11 @@ private enum GlobalAutoremoveEntry: ItemListNodeEntry {
|
|||
case .header:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.Privacy_Messages_SectionTitle, sectionId: self.section)
|
||||
case let .optionEverybody(value):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: presentationData.strings.Privacy_Messages_ValueEveryone, style: .left, checked: value == .everybody, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
return ItemListCheckboxItem(presentationData: presentationData, systemStyle: .glass, title: presentationData.strings.Privacy_Messages_ValueEveryone, style: .left, checked: value == .everybody, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.updateValue(.everybody)
|
||||
})
|
||||
case let .optionPremium(value, isEnabled):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, icon: isEnabled ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: presentationData.strings.Privacy_Messages_ValueContactsAndPremium, style: .left, checked: isEnabled && value == .requirePremium, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
return ItemListCheckboxItem(presentationData: presentationData, systemStyle: .glass, icon: isEnabled ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: presentationData.strings.Privacy_Messages_ValueContactsAndPremium, style: .left, checked: isEnabled && value == .requirePremium, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
if isEnabled {
|
||||
arguments.updateValue(.requirePremium)
|
||||
} else {
|
||||
|
|
@ -134,7 +134,7 @@ private enum GlobalAutoremoveEntry: ItemListNodeEntry {
|
|||
if case .paidMessages = value {
|
||||
isChecked = true
|
||||
}
|
||||
return ItemListCheckboxItem(presentationData: presentationData, icon: isEnabled || isChecked ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: presentationData.strings.Privacy_Messages_ChargeForMessages, style: .left, checked: isChecked, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
return ItemListCheckboxItem(presentationData: presentationData, systemStyle: .glass, icon: isEnabled || isChecked ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: presentationData.strings.Privacy_Messages_ChargeForMessages, style: .left, checked: isChecked, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.updateValue(.paidMessages(StarsAmount(value: 400, nanos: 0)))
|
||||
})
|
||||
case let .footer(value):
|
||||
|
|
@ -152,7 +152,7 @@ private enum GlobalAutoremoveEntry: ItemListNodeEntry {
|
|||
case .priceHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.Privacy_Messages_MessagePrice, sectionId: self.section)
|
||||
case let .price(value, maxValue, price, isEnabled):
|
||||
return MessagePriceItem(theme: presentationData.theme, strings: presentationData.strings, isEnabled: isEnabled, minValue: 1, maxValue: maxValue, value: value, price: price, sectionId: self.section, updated: { value, _ in
|
||||
return MessagePriceItem(theme: presentationData.theme, strings: presentationData.strings, systemStyle: .glass, isEnabled: isEnabled, minValue: 1, maxValue: maxValue, value: value, price: price, sectionId: self.section, updated: { value, _ in
|
||||
arguments.updateValue(.paidMessages(StarsAmount(value: value, nanos: 0)))
|
||||
}, openSetCustom: {
|
||||
arguments.openSetCustomStarsAmount()
|
||||
|
|
@ -164,7 +164,7 @@ private enum GlobalAutoremoveEntry: ItemListNodeEntry {
|
|||
case .exceptionsHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.Privacy_Messages_RemoveFeeHeader, sectionId: self.section)
|
||||
case let .exceptions(count):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: presentationData.strings.Privacy_Messages_RemoveFee, label: count > 0 ? "\(count)" : "", sectionId: self.section, style: .blocks, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: presentationData.strings.Privacy_Messages_RemoveFee, label: count > 0 ? "\(count)" : "", sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openExceptions()
|
||||
})
|
||||
case .exceptionsInfo:
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, ASScrollViewDe
|
|||
self.cancelButton.accessibilityLabel = presentationData.strings.Common_Close
|
||||
self.cancelButton.accessibilityTraits = [.button]
|
||||
|
||||
self.terminateButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemBlocksBackgroundColor, foregroundColor: self.presentationData.theme.list.itemDestructiveColor), font: .regular, height: 44.0, cornerRadius: 11.0, gloss: false)
|
||||
self.terminateButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemBlocksBackgroundColor, foregroundColor: self.presentationData.theme.list.itemDestructiveColor), font: .regular, height: 44.0, cornerRadius: 11.0)
|
||||
|
||||
var hasSecretChats = false
|
||||
var hasIncomingCalls = false
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ private enum UsernameSetupEntry: ItemListNodeEntry {
|
|||
case let .publicLinkHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .editablePublicLink(theme, _, prefix, currentText, text, enabled):
|
||||
return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: enabled ? prefix : "", textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .username, spacing: 10.0, clearType: enabled ? .always : .none, enabled: enabled, tag: UsernameEntryTag.username, sectionId: self.section, textUpdated: { updatedText in
|
||||
return ItemListSingleLineInputItem(presentationData: presentationData, systemStyle: .glass, title: NSAttributedString(string: enabled ? prefix : "", textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .username, spacing: 10.0, clearType: enabled ? .always : .none, enabled: enabled, tag: UsernameEntryTag.username, sectionId: self.section, textUpdated: { updatedText in
|
||||
arguments.updatePublicLinkText(currentText, updatedText)
|
||||
}, action: {
|
||||
})
|
||||
|
|
@ -233,7 +233,7 @@ private enum UsernameSetupEntry: ItemListNodeEntry {
|
|||
case let .additionalLinkHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .additionalLink(_, link, _, canToggleIsActive):
|
||||
return AdditionalLinkItem(presentationData: presentationData, username: link, sectionId: self.section, style: .blocks, tapAction: {
|
||||
return AdditionalLinkItem(presentationData: presentationData, systemStyle: .glass, username: link, sectionId: self.section, style: .blocks, tapAction: {
|
||||
if canToggleIsActive {
|
||||
if link.isActive {
|
||||
arguments.deactivateLink(link.username)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ swift_library(
|
|||
"//submodules/ShimmerEffect:ShimmerEffect",
|
||||
"//submodules/Components/HierarchyTrackingLayer:HierarchyTrackingLayer",
|
||||
"//submodules/ManagedAnimationNode:ManagedAnimationNode",
|
||||
"//submodules/TelegramUI/Components/GlassBackgroundComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import SwiftSignalKit
|
|||
import HierarchyTrackingLayer
|
||||
import ShimmerEffect
|
||||
import ManagedAnimationNode
|
||||
import GlassBackgroundComponent
|
||||
|
||||
private func generateIndefiniteActivityIndicatorImage(color: UIColor, diameter: CGFloat = 22.0, lineWidth: CGFloat = 2.0) -> UIImage? {
|
||||
return generateImage(CGSize(width: diameter, height: diameter), rotatedContext: { size, context in
|
||||
|
|
@ -164,8 +165,9 @@ private final class BadgeNode: ASDisplayNode {
|
|||
|
||||
public final class SolidRoundedButtonNode: ASDisplayNode {
|
||||
private var theme: SolidRoundedButtonTheme
|
||||
private var glass: Bool
|
||||
private var fontSize: CGFloat
|
||||
private let gloss: Bool
|
||||
private let isShimmering: Bool
|
||||
|
||||
public let buttonBackgroundNode: ASImageNode
|
||||
private var buttonBackgroundAnimationView: UIImageView?
|
||||
|
|
@ -174,7 +176,9 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
|
|||
private var borderView: UIView?
|
||||
private var borderMaskView: UIView?
|
||||
private var borderShimmerView: ShimmerEffectForegroundView?
|
||||
|
||||
|
||||
private var chromeView: UIImageView?
|
||||
|
||||
private let buttonNode: HighlightTrackingButtonNode
|
||||
public let titleNode: ImmediateTextNode
|
||||
private let subtitleNode: ImmediateTextNode
|
||||
|
|
@ -267,7 +271,7 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
|
|||
_ = self.updateLayout(width: width, transition: .immediate)
|
||||
}
|
||||
|
||||
if self.gloss {
|
||||
if self.isShimmering {
|
||||
self.animationTimer?.invalidate()
|
||||
|
||||
Queue.mainQueue().after(1.25) {
|
||||
|
|
@ -338,14 +342,15 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
|
|||
}
|
||||
}
|
||||
|
||||
public init(title: String? = nil, icon: UIImage? = nil, theme: SolidRoundedButtonTheme, font: SolidRoundedButtonFont = .bold, fontSize: CGFloat = 17.0, height: CGFloat = 48.0, cornerRadius: CGFloat = 24.0, gloss: Bool = false) {
|
||||
public init(title: String? = nil, icon: UIImage? = nil, theme: SolidRoundedButtonTheme, glass: Bool = false, font: SolidRoundedButtonFont = .bold, fontSize: CGFloat = 17.0, height: CGFloat = 48.0, cornerRadius: CGFloat = 24.0, isShimmering: Bool = false) {
|
||||
self.theme = theme
|
||||
self.glass = glass
|
||||
self.font = font
|
||||
self.fontSize = fontSize
|
||||
self.buttonHeight = height
|
||||
self.buttonCornerRadius = cornerRadius
|
||||
self.title = title
|
||||
self.gloss = gloss
|
||||
self.isShimmering = isShimmering
|
||||
|
||||
self.buttonBackgroundNode = ASImageNode()
|
||||
self.buttonBackgroundNode.displaysAsynchronously = false
|
||||
|
|
@ -443,7 +448,7 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
|
|||
}
|
||||
|
||||
private func setupGloss() {
|
||||
if self.gloss {
|
||||
if self.isShimmering {
|
||||
if self.shimmerView == nil {
|
||||
let shimmerView = ShimmerEffectForegroundView()
|
||||
self.shimmerView = shimmerView
|
||||
|
|
@ -792,6 +797,26 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
|
|||
self.subtitleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
|
||||
}
|
||||
|
||||
let chromeView: UIImageView
|
||||
var chromeTransition = transition
|
||||
if let current = self.chromeView {
|
||||
chromeView = current
|
||||
} else {
|
||||
chromeTransition = .immediate
|
||||
chromeView = UIImageView()
|
||||
self.chromeView = chromeView
|
||||
if let shimmeringView = self.shimmerView {
|
||||
self.view.insertSubview(chromeView, aboveSubview: shimmeringView)
|
||||
} else {
|
||||
self.view.insertSubview(chromeView, aboveSubview: self.buttonBackgroundNode.view)
|
||||
}
|
||||
|
||||
chromeView.layer.compositingFilter = "overlayBlendMode"
|
||||
chromeView.alpha = 0.8
|
||||
chromeView.image = GlassBackgroundView.generateForegroundImage(size: CGSize(width: 26.0 * 2.0, height: 26.0 * 2.0), isDark: self.theme.backgroundColor.lightness < 0.4, fillColor: .clear)
|
||||
}
|
||||
chromeTransition.updateFrame(view: chromeView, frame: CGRect(origin: .zero, size: buttonSize))
|
||||
|
||||
return buttonSize.height
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ final class PremiumStickerPackAccessoryNode: SparseNode, PeekControllerAccessory
|
|||
UIColor(rgb: 0x6b93ff),
|
||||
UIColor(rgb: 0x8878ff),
|
||||
UIColor(rgb: 0xe46ace)
|
||||
], foregroundColor: .white), height: 50.0, cornerRadius: 11.0, gloss: true)
|
||||
], foregroundColor: .white), height: 50.0, cornerRadius: 11.0, isShimmering: true)
|
||||
self.proceedButton.iconPosition = .right
|
||||
self.proceedButton.iconSpacing = 4.0
|
||||
self.proceedButton.animation = "premium_unlock"
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ private class VoiceChatCameraPreviewControllerNode: ViewControllerTracingNode, A
|
|||
self.titleNode = ASTextNode()
|
||||
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.bold(17.0), textColor: UIColor(rgb: 0xffffff))
|
||||
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: UIColor(rgb: 0xffffff), foregroundColor: UIColor(rgb: 0x4f5352)), font: .bold, height: 48.0, cornerRadius: 24.0, gloss: false)
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: UIColor(rgb: 0xffffff), foregroundColor: UIColor(rgb: 0x4f5352)), font: .bold, height: 48.0, cornerRadius: 24.0)
|
||||
self.doneButton.title = self.presentationData.strings.VoiceChat_VideoPreviewContinue
|
||||
|
||||
if #available(iOS 12.0, *) {
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ private class VoiceChatRecordingSetupControllerNode: ViewControllerTracingNode,
|
|||
|
||||
self.doneButton = VoiceChatActionButton()
|
||||
|
||||
self.cancelButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: buttonColor, foregroundColor: buttonTextColor), font: .regular, height: 52.0, cornerRadius: 11.0, gloss: false)
|
||||
self.cancelButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: buttonColor, foregroundColor: buttonTextColor), font: .regular, height: 52.0, cornerRadius: 11.0)
|
||||
self.cancelButton.title = self.presentationData.strings.Common_Cancel
|
||||
|
||||
self.modeContainerNode = ASDisplayNode()
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ public final class PermissionContentNode: ASDisplayNode {
|
|||
self.textNode.displaysAsynchronously = false
|
||||
self.textNode.isAccessibilityElement = true
|
||||
|
||||
self.actionButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: theme), height: 52.0, cornerRadius: 9.0, gloss: true)
|
||||
self.actionButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: theme), height: 52.0, cornerRadius: 9.0, isShimmering: true)
|
||||
|
||||
self.footerNode = ImmediateTextNode()
|
||||
self.footerNode.textAlignment = .center
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ final class AttachmentFileEmptyStateItemNode: ItemListControllerEmptyStateItemNo
|
|||
self.textNode.lineSpacing = 0.1
|
||||
self.textNode.textAlignment = .center
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0, gloss: true)
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 52.0, cornerRadius: 26.0, isShimmering: true)
|
||||
|
||||
super.init()
|
||||
|
||||
|
|
|
|||
|
|
@ -890,7 +890,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
|||
self.animationNode = AnimationNode(animation: self.isDarkAppearance ? "anim_sun_reverse" : "anim_sun", colors: iconColors(theme: self.presentationData.theme), scale: 1.0)
|
||||
self.animationNode.isUserInteractionEnabled = false
|
||||
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, gloss: false)
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0)
|
||||
switch controller.subject {
|
||||
case .peer:
|
||||
self.doneButton.title = self.presentationData.strings.InviteLink_QRCode_Share
|
||||
|
|
@ -898,7 +898,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
|||
self.doneButton.title = self.presentationData.strings.Share_ShareMessage
|
||||
}
|
||||
|
||||
self.scanButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .clear, foregroundColor: self.presentationData.theme.actionSheet.controlAccentColor), font: .regular, height: 42.0, cornerRadius: 0.0, gloss: false)
|
||||
self.scanButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .clear, foregroundColor: self.presentationData.theme.actionSheet.controlAccentColor), font: .regular, height: 42.0, cornerRadius: 0.0)
|
||||
self.scanButton.title = presentationData.strings.PeerInfo_QRCode_Scan
|
||||
self.scanButton.icon = UIImage(bundleImageName: "Settings/ScanQr")
|
||||
|
||||
|
|
|
|||
|
|
@ -557,7 +557,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
self.menuButtonIconNode.customColor = presentationInterfaceState.theme.chat.inputPanel.actionControlForegroundColor
|
||||
self.menuButtonTextNode = ImmediateTextNode()
|
||||
|
||||
self.startButton = SolidRoundedButtonNode(title: presentationInterfaceState.strings.Bot_Start, theme: SolidRoundedButtonTheme(theme: presentationInterfaceState.theme), height: 50.0, cornerRadius: 11.0, gloss: true)
|
||||
self.startButton = SolidRoundedButtonNode(title: presentationInterfaceState.strings.Bot_Start, theme: SolidRoundedButtonTheme(theme: presentationInterfaceState.theme), height: 50.0, cornerRadius: 11.0, isShimmering: true)
|
||||
self.startButton.progressType = .embedded
|
||||
self.startButton.isHidden = true
|
||||
|
||||
|
|
|
|||
|
|
@ -175,9 +175,9 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, ASScrollViewDel
|
|||
self.cancelButton.accessibilityLabel = self.presentationData.strings.Common_Cancel
|
||||
self.cancelButton.accessibilityTraits = [.button]
|
||||
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, gloss: false)
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, isShimmering: false)
|
||||
|
||||
self.onlineButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: buttonColor, foregroundColor: buttonTextColor), font: .regular, height: 52.0, cornerRadius: 11.0, gloss: false)
|
||||
self.onlineButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: buttonColor, foregroundColor: buttonTextColor), font: .regular, height: 52.0, cornerRadius: 11.0, isShimmering: false)
|
||||
switch mode {
|
||||
case let .suggestPost(needsTime, _, _):
|
||||
if needsTime {
|
||||
|
|
|
|||
|
|
@ -925,7 +925,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, ASScrollViewDelega
|
|||
self.animationNode = AnimationNode(animation: self.isDarkAppearance ? "anim_sun_reverse" : "anim_sun", colors: iconColors(theme: self.presentationData.theme), scale: 1.0)
|
||||
self.animationNode.isUserInteractionEnabled = false
|
||||
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 50.0, cornerRadius: 11.0)
|
||||
|
||||
self.otherButton = HighlightableButtonNode()
|
||||
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ class ChatTimerScreenNode: ViewControllerTracingNode, ASScrollViewDelegate, UIPi
|
|||
self.cancelButton = HighlightableButtonNode()
|
||||
self.cancelButton.setTitle(self.presentationData.strings.Common_Cancel, with: Font.regular(17.0), with: accentColor, for: .normal)
|
||||
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, gloss: false)
|
||||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, isShimmering: false)
|
||||
self.doneButton.title = self.presentationData.strings.Conversation_Timer_Send
|
||||
|
||||
self.disableButton = HighlightableButtonNode()
|
||||
|
|
|
|||
|
|
@ -391,16 +391,19 @@ final class NewContactScreenComponent: Component {
|
|||
|
||||
let cleanNumber = number.replacingOccurrences(of: "+", with: "")
|
||||
var scheduleResolve = false
|
||||
var resolveDelay: Double = 2.5
|
||||
if !mask.isEmpty && abs(cleanNumber.count - mask.count) < 3 {
|
||||
scheduleResolve = true
|
||||
if abs(cleanNumber.count - mask.count) == 0 {
|
||||
resolveDelay = 0.1
|
||||
}
|
||||
} else if mask.isEmpty && cleanNumber.count > 4 {
|
||||
scheduleResolve = true
|
||||
}
|
||||
let _ = component
|
||||
|
||||
if scheduleResolve {
|
||||
self.resolvedPeerDisposable.set(
|
||||
((Signal.complete() |> delay(2.5, queue: Queue.mainQueue()))
|
||||
((Signal.complete() |> delay(resolveDelay, queue: Queue.mainQueue()))
|
||||
|> then(
|
||||
component.context.engine.peers.resolvePeerByPhone(phone: number)
|
||||
|> beforeStarted({ [weak self] in
|
||||
|
|
@ -414,16 +417,24 @@ final class NewContactScreenComponent: Component {
|
|||
})
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let self else {
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
if let peer {
|
||||
self.resolvedPeer = .peer(peer: peer, isContact: false)
|
||||
self.resolvedPeerDisposable.set((component.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.IsContact(id: peer.id)) |> deliverOnMainQueue).start(next: { [weak self] isContact in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.resolvedPeer = .peer(peer: peer, isContact: isContact)
|
||||
if !self.isUpdating {
|
||||
self.state?.updated(transition: .easeInOut(duration: 0.2))
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
self.resolvedPeer = .notFound
|
||||
}
|
||||
if !self.isUpdating {
|
||||
self.state?.updated(transition: .easeInOut(duration: 0.2))
|
||||
if !self.isUpdating {
|
||||
self.state?.updated(transition: .easeInOut(duration: 0.2))
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
|
|
|||
|
|
@ -661,15 +661,11 @@ final class GiftOptionsScreenComponent: Component {
|
|||
topPanelHeight += 39.0
|
||||
}
|
||||
|
||||
// if let tabSelectorView = self.tabSelector.view {
|
||||
// let tabSelectorSize = tabSelectorView.bounds.size
|
||||
// transition.setFrame(view: tabSelectorView, frame: CGRect(origin: CGPoint(x: floor((availableWidth - tabSelectorSize.width) / 2.0), y: max(56.0, self.tabSelectorOrigin - contentOffset)), size: tabSelectorSize))
|
||||
// }
|
||||
|
||||
let edgeEffectHeight: CGFloat = 88.0
|
||||
let topEdgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: availableWidth, height: edgeEffectHeight))
|
||||
transition.setFrame(view: self.topEdgeEffectView, frame: topEdgeEffectFrame)
|
||||
self.topEdgeEffectView.update(content: theme.list.blocksBackgroundColor, alpha: 1.0, rect: topEdgeEffectFrame, edge: .top, edgeSize: topEdgeEffectFrame.height, transition: transition)
|
||||
self.topEdgeEffectView.update(content: .clear, blur: true, alpha: 1.0, rect: topEdgeEffectFrame, edge: .top, edgeSize: topEdgeEffectFrame.height, transition: transition)
|
||||
if self.topEdgeEffectView.superview == nil {
|
||||
if let headerView = self.header.view {
|
||||
self.insertSubview(self.topEdgeEffectView, aboveSubview: headerView)
|
||||
|
|
@ -682,41 +678,7 @@ final class GiftOptionsScreenComponent: Component {
|
|||
let bottomEdgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: self.bounds.height - edgeEffectHeight - environment.additionalInsets.bottom), size: CGSize(width: availableWidth, height: edgeEffectHeight))
|
||||
transition.setFrame(view: self.bottomEdgeEffectView, frame: bottomEdgeEffectFrame)
|
||||
self.bottomEdgeEffectView.update(content: theme.list.blocksBackgroundColor, blur: true, alpha: 1.0, rect: bottomEdgeEffectFrame, edge: .bottom, edgeSize: bottomEdgeEffectFrame.height, transition: transition)
|
||||
|
||||
// var panelTransition = transition
|
||||
// if self.topPanel.view?.superview != nil && !self.switchingFilter {
|
||||
// panelTransition = .spring(duration: 0.3)
|
||||
// }
|
||||
// let topPanelSize = self.topPanel.update(
|
||||
// transition: panelTransition,
|
||||
// component: AnyComponent(BlurredBackgroundComponent(
|
||||
// color: environment.theme.rootController.navigationBar.blurredBackgroundColor
|
||||
// )),
|
||||
// environment: {},
|
||||
// containerSize: CGSize(width: availableWidth, height: topPanelHeight)
|
||||
// )
|
||||
//
|
||||
// let topSeparatorSize = self.topSeparator.update(
|
||||
// transition: panelTransition,
|
||||
// component: AnyComponent(Rectangle(
|
||||
// color: environment.theme.rootController.navigationBar.separatorColor
|
||||
// )),
|
||||
// environment: {},
|
||||
// containerSize: CGSize(width: availableWidth, height: UIScreenPixel)
|
||||
// )
|
||||
// let topPanelFrame = CGRect(origin: .zero, size: CGSize(width: availableWidth, height: topPanelSize.height))
|
||||
// let topSeparatorFrame = CGRect(origin: CGPoint(x: 0.0, y: topPanelSize.height), size: CGSize(width: topSeparatorSize.width, height: topSeparatorSize.height))
|
||||
// if let topPanelView = self.topPanel.view, let topSeparatorView = self.topSeparator.view {
|
||||
// if topPanelView.superview == nil {
|
||||
// if let headerView = self.header.view {
|
||||
// self.insertSubview(topSeparatorView, aboveSubview: headerView)
|
||||
// self.insertSubview(topPanelView, aboveSubview: headerView)
|
||||
// }
|
||||
// }
|
||||
// panelTransition.setFrame(view: topPanelView, frame: topPanelFrame)
|
||||
// panelTransition.setFrame(view: topSeparatorView, frame: topSeparatorFrame)
|
||||
// }
|
||||
|
||||
|
||||
let bottomContentOffset = max(0.0, self.scrollView.contentSize.height - self.scrollView.contentOffset.y - self.scrollView.frame.height)
|
||||
if interactive, bottomContentOffset < 320.0, case .transfer = self.starsFilter {
|
||||
self.state?.starGiftsContext.loadMore()
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ private let smallTextFont = Font.with(size: 13.0, traits: .monospacedNumbers)
|
|||
public final class MessagePriceItem: Equatable, ListViewItem, ItemListItem, ListItemComponentAdaptor.ItemGenerator {
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let isEnabled: Bool
|
||||
let minValue: Int64
|
||||
let maxValue: Int64
|
||||
|
|
@ -30,9 +31,10 @@ public final class MessagePriceItem: Equatable, ListViewItem, ItemListItem, List
|
|||
let openSetCustom: (() -> Void)?
|
||||
let openPremiumInfo: (() -> Void)?
|
||||
|
||||
public init(theme: PresentationTheme, strings: PresentationStrings, isEnabled: Bool, minValue: Int64, maxValue: Int64, value: Int64, price: String, sectionId: ItemListSectionId, updated: @escaping (Int64, Bool) -> Void, openSetCustom: (() -> Void)? = nil, openPremiumInfo: (() -> Void)? = nil) {
|
||||
public init(theme: PresentationTheme, strings: PresentationStrings, systemStyle: ItemListSystemStyle = .legacy, isEnabled: Bool, minValue: Int64, maxValue: Int64, value: Int64, price: String, sectionId: ItemListSectionId, updated: @escaping (Int64, Bool) -> Void, openSetCustom: (() -> Void)? = nil, openPremiumInfo: (() -> Void)? = nil) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.systemStyle = systemStyle
|
||||
self.isEnabled = isEnabled
|
||||
self.minValue = minValue
|
||||
self.maxValue = maxValue
|
||||
|
|
@ -301,6 +303,7 @@ private class MessagePriceItemNode: ListViewItemNode {
|
|||
var contentSize: CGSize
|
||||
let insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
let separatorRightInset: CGFloat = item.systemStyle == .glass ? 16.0 : 0.0
|
||||
|
||||
contentSize = CGSize(width: params.width, height: 88.0)
|
||||
if !item.isEnabled {
|
||||
|
|
@ -358,12 +361,12 @@ private class MessagePriceItemNode: ListViewItemNode {
|
|||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: item.systemStyle == .glass) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset - params.rightInset - separatorRightInset, height: separatorHeight))
|
||||
|
||||
strongSelf.leftTextNode.attributedText = NSAttributedString(string: "\(item.minValue)", font: Font.regular(13.0), textColor: item.theme.list.itemSecondaryTextColor)
|
||||
strongSelf.rightTextNode.attributedText = NSAttributedString(string: "\(item.maxValue)", font: Font.regular(13.0), textColor: item.theme.list.itemSecondaryTextColor)
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ private enum OldChannelsEntry: ItemListNodeEntry {
|
|||
case let .peersHeader(title):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
|
||||
case let .peer(_, peer, selected):
|
||||
return ContactsPeerItem(presentationData: presentationData, style: .blocks, sectionId: self.section, sortOrder: .firstLast, displayOrder: .firstLast, context: arguments.context, peerMode: .peer, peer: .peer(peer: EnginePeer(peer.peer), chatPeer: EnginePeer(peer.peer)), status: .custom(string: NSAttributedString(string: localizedOldChannelDate(peer: peer, strings: presentationData.strings)), multiline: false, isActive: false, icon: nil), badge: nil, enabled: true, selection: ContactsPeerItemSelection.selectable(selected: selected), editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), options: [], actionIcon: .none, index: nil, header: nil, action: { _ in
|
||||
return ContactsPeerItem(presentationData: presentationData, style: .blocks, systemStyle: .glass, sectionId: self.section, sortOrder: .firstLast, displayOrder: .firstLast, context: arguments.context, peerMode: .peer, peer: .peer(peer: EnginePeer(peer.peer), chatPeer: EnginePeer(peer.peer)), status: .custom(string: NSAttributedString(string: localizedOldChannelDate(peer: peer, strings: presentationData.strings)), multiline: false, isActive: false, icon: nil), badge: nil, enabled: true, selection: ContactsPeerItemSelection.selectable(selected: selected), editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), options: [], actionIcon: .none, index: nil, header: nil, action: { _ in
|
||||
arguments.togglePeer(peer.peer.id, true)
|
||||
}, setPeerIdWithRevealedOptions: nil, deletePeer: nil, itemHighlighting: nil, contextAction: nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
self.emptyAnimationNode.isHidden = true
|
||||
self.emptyAnimationSize = CGSize(width: 120.0, height: 120.0)
|
||||
|
||||
self.emptyButtonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), cornerRadius: 11.0, gloss: true)
|
||||
self.emptyButtonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), cornerRadius: 11.0, isShimmering: true)
|
||||
self.emptyButtonNode.isHidden = true
|
||||
self.emptyButtonNode.pressed = {
|
||||
createNewGroup?()
|
||||
|
|
|
|||
|
|
@ -359,10 +359,12 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
|
|||
id: product.id,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
header: nil,
|
||||
footer: nil,
|
||||
items: [AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
background: backgroundComponent,
|
||||
title: titleComponent,
|
||||
contentInsets: UIEdgeInsets(top: 12.0, left: -6.0, bottom: 12.0, right: 0.0),
|
||||
|
|
@ -414,10 +416,12 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
|
|||
id: items.count,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
header: nil,
|
||||
footer: nil,
|
||||
items: [AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
title: titleCombinedComponent,
|
||||
titleAlignment: .center,
|
||||
contentInsets: UIEdgeInsets(top: 7.0, left: 0.0, bottom: 7.0, right: 0.0),
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ final class DataButtonComponent: Component {
|
|||
super.init(frame: frame)
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.layer.cornerRadius = 10.0
|
||||
self.layer.cornerRadius = 26.0
|
||||
|
||||
self.highligthedChanged = { [weak self] isHighlighted in
|
||||
guard let self, let component = self.component, let highlightBackgroundFrame = self.highlightBackgroundFrame else {
|
||||
|
|
@ -111,7 +111,7 @@ final class DataButtonComponent: Component {
|
|||
containerSize: CGSize(width: availableSize.width, height: 100.0)
|
||||
)
|
||||
|
||||
let height: CGFloat = 44.0
|
||||
let height: CGFloat = 52.0
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) / 2.0), y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ final class DataCategoriesComponent: Component {
|
|||
super.init(frame: frame)
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.layer.cornerRadius = 10.0
|
||||
self.layer.cornerRadius = 26.0
|
||||
|
||||
self.addSubview(self.containerView)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ private final class SubItemComponent: Component {
|
|||
containerSize: CGSize(width: availableWidth, height: 100.0)
|
||||
)
|
||||
|
||||
let height: CGFloat = 44.0
|
||||
let height: CGFloat = 52.0
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: leftInset, y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||
let titleValueFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: floor((height - titleValueSize.height) / 2.0)), size: titleValueSize)
|
||||
|
|
@ -469,7 +469,7 @@ final class DataCategoryItemComponent: Component {
|
|||
containerSize: CGSize(width: availableWidth, height: 100.0)
|
||||
)
|
||||
|
||||
var height: CGFloat = 44.0
|
||||
var height: CGFloat = 52.0
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: leftInset, y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||
let titleValueFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: floor((height - titleValueSize.height) / 2.0)), size: titleValueSize)
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ final class DataUsageScreenComponent: Component {
|
|||
|
||||
self.autoDownloadSettingsContainerView = UIView()
|
||||
self.autoDownloadSettingsContainerView.clipsToBounds = true
|
||||
self.autoDownloadSettingsContainerView.layer.cornerRadius = 10.0
|
||||
self.autoDownloadSettingsContainerView.layer.cornerRadius = 26.0
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ final class StorageCategoriesComponent: Component {
|
|||
super.init(frame: frame)
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.layer.cornerRadius = 10.0
|
||||
self.layer.cornerRadius = 26.0
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
|
|
@ -227,8 +227,8 @@ final class StorageCategoriesComponent: Component {
|
|||
),
|
||||
font: .bold,
|
||||
fontSize: 17.0,
|
||||
height: 50.0,
|
||||
cornerRadius: 10.0,
|
||||
height: 52.0,
|
||||
cornerRadius: 26.0,
|
||||
gloss: false,
|
||||
isEnabled: totalSelectedSize != 0,
|
||||
animationName: nil,
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ final class StorageCategoryItemComponent: Component {
|
|||
containerSize: CGSize(width: availableWidth, height: 100.0)
|
||||
)
|
||||
|
||||
var height: CGFloat = 44.0
|
||||
var height: CGFloat = 52.0
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: leftInset, y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||
let titleValueFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: floor((height - titleValueSize.height) / 2.0)), size: titleValueSize)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ final class StorageKeepSizeComponent: Component {
|
|||
super.init(frame: frame)
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.layer.cornerRadius = 10.0
|
||||
self.layer.cornerRadius = 26.0
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
|
|
@ -106,7 +106,7 @@ final class StorageKeepSizeComponent: Component {
|
|||
self.backgroundColor = component.theme.list.itemBlocksBackgroundColor
|
||||
}
|
||||
|
||||
let height: CGFloat = 88.0
|
||||
let height: CGFloat = 96.0
|
||||
|
||||
var titleSizes: [CGSize] = []
|
||||
for i in 0 ..< self.titles.count {
|
||||
|
|
@ -133,7 +133,7 @@ final class StorageKeepSizeComponent: Component {
|
|||
} else if i > 0 {
|
||||
position -= titleSize.width / 2.0
|
||||
}
|
||||
transition.setFrame(view: titleView, frame: CGRect(origin: CGPoint(x: position, y: 15.0), size: titleSize))
|
||||
transition.setFrame(view: titleView, frame: CGRect(origin: CGPoint(x: position, y: 19.0), size: titleSize))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ final class StorageKeepSizeComponent: Component {
|
|||
sliderView.knobImage = PresentationResourcesItemList.knobImage(component.theme)
|
||||
}
|
||||
|
||||
transition.setFrame(view: sliderView, frame: CGRect(origin: CGPoint(x: 15.0, y: 37.0), size: CGSize(width: availableSize.width - 15.0 * 2.0, height: 44.0)))
|
||||
transition.setFrame(view: sliderView, frame: CGRect(origin: CGPoint(x: 15.0, y: 41.0), size: CGSize(width: availableSize.width - 15.0 * 2.0, height: 44.0)))
|
||||
sliderView.hitTestEdgeInsets = UIEdgeInsets(top: -sliderView.frame.minX, left: 0.0, bottom: 0.0, right: -sliderView.frame.minX)
|
||||
|
||||
self.updateSliderView()
|
||||
|
|
|
|||
|
|
@ -202,9 +202,9 @@ final class StoragePeerTypeItemComponent: Component {
|
|||
}
|
||||
}
|
||||
|
||||
var height: CGFloat = 44.0
|
||||
var height: CGFloat = 52.0
|
||||
if subtitleSize != nil {
|
||||
height = 60.0
|
||||
height = 64.0
|
||||
}
|
||||
|
||||
let titleFrame: CGRect
|
||||
|
|
|
|||
|
|
@ -816,7 +816,7 @@ final class StorageUsageScreenComponent: Component {
|
|||
|
||||
self.keepDurationSectionContainerView = UIView()
|
||||
self.keepDurationSectionContainerView.clipsToBounds = true
|
||||
self.keepDurationSectionContainerView.layer.cornerRadius = 10.0
|
||||
self.keepDurationSectionContainerView.layer.cornerRadius = 26.0
|
||||
|
||||
self.headerProgressBackgroundLayer = SimpleLayer()
|
||||
self.headerProgressForegroundLayer = SimpleLayer()
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/TelegramUI/Components/ToastComponent",
|
||||
"//submodules/TelegramUI/Components/LottieComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
"//submodules/Markdown",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ import ButtonComponent
|
|||
import ToastComponent
|
||||
import LottieComponent
|
||||
import MultilineTextComponent
|
||||
import BundleIconComponent
|
||||
import Markdown
|
||||
import TelegramStringFormatting
|
||||
import GlassBarButtonComponent
|
||||
|
||||
private final class StoryStealthModeSheetContentComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
|
@ -176,40 +178,7 @@ private final class StoryStealthModeSheetContentComponent: Component {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if case .upgrade = component.mode {
|
||||
let cancelButton: ComponentView<Empty>
|
||||
if let current = self.cancelButton {
|
||||
cancelButton = current
|
||||
} else {
|
||||
cancelButton = ComponentView()
|
||||
self.cancelButton = cancelButton
|
||||
}
|
||||
let cancelButtonSize = cancelButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(Button(
|
||||
content: AnyComponent(Text(text: environment.strings.Common_Cancel, font: Font.regular(17.0), color: environment.theme.list.itemAccentColor)),
|
||||
action: { [weak self] in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.dismiss()
|
||||
}
|
||||
).minSize(CGSize(width: 8.0, height: 44.0))),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 200.0, height: 100.0)
|
||||
)
|
||||
if let cancelButtonView = cancelButton.view {
|
||||
if cancelButtonView.superview == nil {
|
||||
self.addSubview(cancelButtonView)
|
||||
}
|
||||
transition.setFrame(view: cancelButtonView, frame: CGRect(origin: CGPoint(x: 16.0, y: 6.0), size: cancelButtonSize))
|
||||
}
|
||||
} else if let cancelButton = self.cancelButton {
|
||||
self.cancelButton = nil
|
||||
cancelButton.view?.removeFromSuperview()
|
||||
}
|
||||
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
contentHeight += 32.0
|
||||
|
||||
|
|
@ -240,6 +209,45 @@ private final class StoryStealthModeSheetContentComponent: Component {
|
|||
contentHeight += contentSize.height
|
||||
contentHeight += 41.0
|
||||
|
||||
if case .upgrade = component.mode {
|
||||
let cancelButton: ComponentView<Empty>
|
||||
if let current = self.cancelButton {
|
||||
cancelButton = current
|
||||
} else {
|
||||
cancelButton = ComponentView()
|
||||
self.cancelButton = cancelButton
|
||||
}
|
||||
let cancelButtonSize = cancelButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: environment.theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: environment.theme.overallDarkAppearance,
|
||||
state: .tintedGlass,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: environment.theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
component.dismiss()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 40.0, height: 40.0)
|
||||
)
|
||||
if let cancelButtonView = cancelButton.view {
|
||||
if cancelButtonView.superview == nil {
|
||||
self.addSubview(cancelButtonView)
|
||||
}
|
||||
transition.setFrame(view: cancelButtonView, frame: CGRect(origin: CGPoint(x: 16.0, y: 16.0), size: cancelButtonSize))
|
||||
}
|
||||
} else if let cancelButton = self.cancelButton {
|
||||
self.cancelButton = nil
|
||||
cancelButton.view?.removeFromSuperview()
|
||||
}
|
||||
|
||||
let buttonText: String
|
||||
let content: AnyComponentWithIdentity<Empty>
|
||||
switch component.mode {
|
||||
|
|
@ -266,10 +274,12 @@ private final class StoryStealthModeSheetContentComponent: Component {
|
|||
))
|
||||
}
|
||||
|
||||
let buttonSideInset: CGFloat = 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)
|
||||
|
|
@ -302,9 +312,9 @@ private final class StoryStealthModeSheetContentComponent: Component {
|
|||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 50.0)
|
||||
containerSize: CGSize(width: availableSize.width - buttonSideInset * 2.0, height: 52.0)
|
||||
)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: buttonSize)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: buttonSideInset, y: contentHeight), size: buttonSize)
|
||||
if let buttonView = self.button.view {
|
||||
if buttonView.superview == nil {
|
||||
self.addSubview(buttonView)
|
||||
|
|
@ -316,7 +326,7 @@ private final class StoryStealthModeSheetContentComponent: Component {
|
|||
if environment.safeInsets.bottom.isZero {
|
||||
contentHeight += 16.0
|
||||
} else {
|
||||
contentHeight += environment.safeInsets.bottom + 14.0
|
||||
contentHeight += environment.safeInsets.bottom + 10.0
|
||||
}
|
||||
|
||||
return CGSize(width: availableSize.width, height: contentHeight)
|
||||
|
|
@ -438,6 +448,7 @@ private final class StoryStealthModeSheetScreenComponent: Component {
|
|||
})
|
||||
}
|
||||
)),
|
||||
style: .glass,
|
||||
backgroundColor: .color(environment.theme.overallDarkAppearance ? environment.theme.list.itemBlocksBackgroundColor : environment.theme.list.blocksBackgroundColor),
|
||||
animateOut: self.sheetAnimateOut
|
||||
)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue