mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Various improvements
This commit is contained in:
parent
2f3cf25666
commit
8897deff91
29 changed files with 484 additions and 321 deletions
|
|
@ -909,8 +909,52 @@ public class MediaEditorTransitionOutExternalState {
|
|||
}
|
||||
}
|
||||
|
||||
public protocol CameraScreen: ViewController {
|
||||
public enum CameraScreenMode {
|
||||
case story
|
||||
case sticker
|
||||
case avatar
|
||||
}
|
||||
|
||||
public final class CameraScreenTransitionIn {
|
||||
public weak var sourceView: UIView?
|
||||
public let sourceRect: CGRect
|
||||
public let sourceCornerRadius: CGFloat
|
||||
public let useFillAnimation: Bool
|
||||
|
||||
public init(
|
||||
sourceView: UIView,
|
||||
sourceRect: CGRect,
|
||||
sourceCornerRadius: CGFloat,
|
||||
useFillAnimation: Bool
|
||||
) {
|
||||
self.sourceView = sourceView
|
||||
self.sourceRect = sourceRect
|
||||
self.sourceCornerRadius = sourceCornerRadius
|
||||
self.useFillAnimation = useFillAnimation
|
||||
}
|
||||
}
|
||||
|
||||
public final class CameraScreenTransitionOut {
|
||||
public weak var destinationView: UIView?
|
||||
public let destinationRect: CGRect
|
||||
public let destinationCornerRadius: CGFloat
|
||||
public let completion: (() -> Void)?
|
||||
|
||||
public init(
|
||||
destinationView: UIView,
|
||||
destinationRect: CGRect,
|
||||
destinationCornerRadius: CGFloat,
|
||||
completion: (() -> Void)? = nil
|
||||
) {
|
||||
self.destinationView = destinationView
|
||||
self.destinationRect = destinationRect
|
||||
self.destinationCornerRadius = destinationCornerRadius
|
||||
self.completion = completion
|
||||
}
|
||||
}
|
||||
|
||||
public protocol CameraScreen: ViewController {
|
||||
func returnFromEditor()
|
||||
}
|
||||
|
||||
public protocol MediaEditorScreen: ViewController {
|
||||
|
|
@ -1330,6 +1374,8 @@ public protocol SharedAccountContext: AnyObject {
|
|||
|
||||
func makeStickerPackScreen(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, mainStickerPack: StickerPackReference, stickerPacks: [StickerPackReference], loadedStickerPacks: [LoadedStickerPack], actionTitle: String?, isEditing: Bool, expandIfNeeded: Bool, parentNavigationController: NavigationController?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, actionPerformed: ((Bool) -> Void)?) -> ViewController
|
||||
|
||||
func makeCameraScreen(context: AccountContext, mode: CameraScreenMode, cameraHolder: Any?, transitionIn: CameraScreenTransitionIn?, transitionOut: @escaping (Bool) -> CameraScreenTransitionOut?, completion: @escaping (Any, @escaping () -> Void) -> Void, transitionedOut: (() -> Void)?) -> ViewController
|
||||
|
||||
func makeMediaPickerScreen(context: AccountContext, hasSearch: Bool, completion: @escaping (Any) -> Void) -> ViewController
|
||||
|
||||
func makeStoryMediaEditorScreen(context: AccountContext, source: Any?, text: String?, link: (url: String, name: String?)?, remainingCount: Int32, completion: @escaping ([MediaEditorScreenResult], MediaEditorTransitionOutExternalState, @escaping (@escaping () -> Void) -> Void) -> Void) -> ViewController
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public final class SolidRoundedButtonComponent: Component {
|
|||
public let height: CGFloat
|
||||
public let cornerRadius: CGFloat
|
||||
public let gloss: Bool
|
||||
public let glass: Bool
|
||||
public let isEnabled: Bool
|
||||
public let iconName: String?
|
||||
public let animationName: String?
|
||||
|
|
@ -39,6 +40,7 @@ public final class SolidRoundedButtonComponent: Component {
|
|||
height: CGFloat = 48.0,
|
||||
cornerRadius: CGFloat = 24.0,
|
||||
gloss: Bool = false,
|
||||
glass: Bool = false,
|
||||
isEnabled: Bool = true,
|
||||
iconName: String? = nil,
|
||||
animationName: String? = nil,
|
||||
|
|
@ -58,6 +60,7 @@ public final class SolidRoundedButtonComponent: Component {
|
|||
self.height = height
|
||||
self.cornerRadius = cornerRadius
|
||||
self.gloss = gloss
|
||||
self.glass = glass
|
||||
self.isEnabled = isEnabled
|
||||
self.iconName = iconName
|
||||
self.animationName = animationName
|
||||
|
|
@ -101,6 +104,9 @@ public final class SolidRoundedButtonComponent: Component {
|
|||
if lhs.gloss != rhs.gloss {
|
||||
return false
|
||||
}
|
||||
if lhs.glass != rhs.glass {
|
||||
return false
|
||||
}
|
||||
if lhs.isEnabled != rhs.isEnabled {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -610,7 +610,12 @@ public final class DatePickerNode: ASDisplayNode {
|
|||
}
|
||||
self.theme = theme
|
||||
|
||||
self.backgroundColor = self.theme.backgroundColor
|
||||
self.backgroundColor = theme.backgroundColor
|
||||
|
||||
self.datePickerBackgroundNode.backgroundColor = theme.backgroundColor
|
||||
self.monthPickerBackgroundNode.backgroundColor = theme.backgroundColor
|
||||
self.timePickerBackgroundNode.backgroundColor = theme.backgroundColor
|
||||
|
||||
self.monthArrowNode.image = generateSmallArrowImage(color: theme.accentColor)
|
||||
self.previousButtonNode.setImage(generateNavigationArrowImage(color: theme.accentColor, mirror: true), for: .normal)
|
||||
self.nextButtonNode.setImage(generateNavigationArrowImage(color: theme.accentColor, mirror: false), for: .normal)
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
|
|||
case let .mainLinkHeader(text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .mainLink(link, isGenerating):
|
||||
return ItemListFolderInviteLinkItem(context: arguments.context, presentationData: presentationData, invite: link, count: 0, peers: [], displayButton: true, enableButton: !isGenerating, buttonTitle: presentationData.strings.FolderLinkScreen_LinkActionCopy, secondaryButtonTitle: link != nil ? presentationData.strings.FolderLinkScreen_LinkActionShare : nil, displayImporters: false, buttonColor: nil, sectionId: self.section, style: .blocks, copyAction: {
|
||||
return ItemListFolderInviteLinkItem(context: arguments.context, presentationData: presentationData, systemStyle: .glass, invite: link, count: 0, peers: [], displayButton: true, enableButton: !isGenerating, buttonTitle: presentationData.strings.FolderLinkScreen_LinkActionCopy, secondaryButtonTitle: link != nil ? presentationData.strings.FolderLinkScreen_LinkActionShare : nil, displayImporters: false, buttonColor: nil, sectionId: self.section, style: .blocks, copyAction: {
|
||||
if let link {
|
||||
arguments.copyLink(link.link)
|
||||
}
|
||||
|
|
@ -197,6 +197,7 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
|
|||
case let .peer(_, peer, isSelected, disabledReasonText):
|
||||
return ItemListPeerItem(
|
||||
presentationData: presentationData,
|
||||
systemStyle: .glass,
|
||||
dateTimeFormat: PresentationDateTimeFormat(),
|
||||
nameDisplayOrder: presentationData.nameDisplayOrder,
|
||||
context: arguments.context,
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
|
|||
case let .titleHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .title(_, placeholder, value):
|
||||
return ItemListSingleLineInputItem(context: arguments.context, presentationData: presentationData, title: NSAttributedString(), text: value, placeholder: placeholder, maxLength: 32, sectionId: self.section, textUpdated: { value in
|
||||
return ItemListSingleLineInputItem(context: arguments.context, presentationData: presentationData, systemStyle: .glass, title: NSAttributedString(), text: value, placeholder: placeholder, maxLength: 32, sectionId: self.section, textUpdated: { value in
|
||||
arguments.updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.title = value
|
||||
|
|
@ -302,7 +302,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
|
|||
case let .titleInfo(_, text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case let .subscriptionFeeToggle(_, text, value, enabled):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enabled: enabled, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: text, value: value, enabled: enabled, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.subscriptionEnabled = value
|
||||
|
|
@ -325,7 +325,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
|
|||
title.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: false)), range: NSRange(range, in: title.string))
|
||||
title.addAttribute(.baselineOffset, value: -1.0, range: NSRange(range, in: title.string))
|
||||
}
|
||||
return ItemListSingleLineInputItem(context: arguments.context, presentationData: presentationData, title: title, text: value.flatMap { "\($0)" } ?? "", placeholder: placeholder, label: label, type: .number, spacing: 3.0, enabled: enabled, tag: InviteLinksEditEntryTag.subscriptionFee, sectionId: self.section, textUpdated: { text in
|
||||
return ItemListSingleLineInputItem(context: arguments.context, presentationData: presentationData, systemStyle: .glass, title: title, text: value.flatMap { "\($0)" } ?? "", placeholder: placeholder, label: label, type: .number, spacing: 3.0, enabled: enabled, tag: InviteLinksEditEntryTag.subscriptionFee, sectionId: self.section, textUpdated: { text in
|
||||
arguments.updateState { state in
|
||||
var updatedState = state
|
||||
if var value = Int64(text).flatMap({ StarsAmount(value: $0, nanos: 0) }) {
|
||||
|
|
@ -343,7 +343,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
|
|||
case let .subscriptionFeeInfo(_, text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section)
|
||||
case let .requestApproval(_, text, value, enabled):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enabled: enabled, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: text, value: value, enabled: enabled, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.requestApproval = value
|
||||
|
|
@ -373,7 +373,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
|
|||
} else {
|
||||
text = presentationData.strings.InviteLink_Create_TimeLimitExpiryDateNever
|
||||
}
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: presentationData.strings.InviteLink_Create_TimeLimitExpiryDate, enabled: enabled, label: text, labelStyle: active ? .coloredText(theme.list.itemAccentColor) : .text, sectionId: self.section, style: .blocks, disclosureStyle: .none, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: presentationData.strings.InviteLink_Create_TimeLimitExpiryDate, enabled: enabled, label: text, labelStyle: active ? .coloredText(theme.list.itemAccentColor) : .text, sectionId: self.section, style: .blocks, disclosureStyle: .none, action: {
|
||||
arguments.dismissInput()
|
||||
arguments.updateState { state in
|
||||
var updatedState = state
|
||||
|
|
@ -437,7 +437,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
|
|||
} else {
|
||||
text = focused ? "" : presentationData.strings.InviteLink_Create_UsersLimitNumberOfUsersUnlimited
|
||||
}
|
||||
return ItemListSingleLineInputItem(context: arguments.context, presentationData: presentationData, title: NSAttributedString(string: presentationData.strings.InviteLink_Create_UsersLimitNumberOfUsers, textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .number, alignment: .right, enabled: enabled, selectAllOnFocus: true, secondaryStyle: !customValue, tag: InviteLinksEditEntryTag.usage, sectionId: self.section, textUpdated: { updatedText in
|
||||
return ItemListSingleLineInputItem(context: arguments.context, presentationData: presentationData, systemStyle: .glass, title: NSAttributedString(string: presentationData.strings.InviteLink_Create_UsersLimitNumberOfUsers, textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .number, alignment: .right, enabled: enabled, selectAllOnFocus: true, secondaryStyle: !customValue, tag: InviteLinksEditEntryTag.usage, sectionId: self.section, textUpdated: { updatedText in
|
||||
arguments.updateState { state in
|
||||
var updatedState = state
|
||||
if updatedText.isEmpty {
|
||||
|
|
@ -472,7 +472,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
|
|||
case let .usageInfo(_, text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case let .revoke(_, text):
|
||||
return ItemListActionItem(presentationData: presentationData, title: text, kind: .destructive, alignment: .center, sectionId: self.section, style: .blocks, action: {
|
||||
return ItemListActionItem(presentationData: presentationData, systemStyle: .glass, title: text, kind: .destructive, alignment: .center, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.revoke()
|
||||
}, tag: nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ private func actionButtonImage(color: UIColor) -> UIImage? {
|
|||
public class ItemListFolderInviteLinkItem: ListViewItem, ItemListItem {
|
||||
let context: AccountContext
|
||||
let presentationData: ItemListPresentationData
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let invite: ExportedChatFolderLink?
|
||||
let count: Int32
|
||||
let peers: [EnginePeer]
|
||||
|
|
@ -49,6 +50,7 @@ public class ItemListFolderInviteLinkItem: ListViewItem, ItemListItem {
|
|||
public init(
|
||||
context: AccountContext,
|
||||
presentationData: ItemListPresentationData,
|
||||
systemStyle: ItemListSystemStyle = .legacy,
|
||||
invite: ExportedChatFolderLink?,
|
||||
count: Int32,
|
||||
peers: [EnginePeer],
|
||||
|
|
@ -69,6 +71,7 @@ public class ItemListFolderInviteLinkItem: ListViewItem, ItemListItem {
|
|||
) {
|
||||
self.context = context
|
||||
self.presentationData = presentationData
|
||||
self.systemStyle = systemStyle
|
||||
self.invite = invite
|
||||
self.count = count
|
||||
self.peers = peers
|
||||
|
|
@ -339,7 +342,7 @@ public class ItemListFolderInviteLinkItemNode: ListViewItemNode, ItemListItemNod
|
|||
let verticalInset: CGFloat = 16.0
|
||||
let fieldHeight: CGFloat = 52.0
|
||||
let fieldSpacing: CGFloat = 16.0
|
||||
let buttonHeight: CGFloat = 50.0
|
||||
let buttonHeight: CGFloat = 52.0
|
||||
|
||||
var height = verticalInset * 2.0 + fieldHeight + fieldSpacing + buttonHeight + 54.0
|
||||
|
||||
|
|
@ -379,7 +382,7 @@ public class ItemListFolderInviteLinkItemNode: ListViewItemNode, ItemListItemNod
|
|||
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: 26.0, color: item.presentationData.theme.list.itemInputField.backgroundColor)
|
||||
strongSelf.addressButtonIconNode.image = actionButtonImage(color: item.presentationData.theme.list.itemInputField.controlColor)
|
||||
}
|
||||
|
||||
|
|
@ -436,7 +439,7 @@ public class ItemListFolderInviteLinkItemNode: ListViewItemNode, ItemListItemNod
|
|||
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)
|
||||
|
|
@ -454,7 +457,7 @@ public class ItemListFolderInviteLinkItemNode: ListViewItemNode, ItemListItemNod
|
|||
strongSelf.addressButtonNode.frame = strongSelf.containerNode.bounds
|
||||
strongSelf.referenceContainerNode.frame = strongSelf.containerNode.bounds
|
||||
strongSelf.addressButtonIconNode.frame = strongSelf.containerNode.bounds
|
||||
|
||||
|
||||
let shareButtonNode: SolidRoundedButtonNode
|
||||
if let currentShareButtonNode = strongSelf.shareButtonNode {
|
||||
shareButtonNode = currentShareButtonNode
|
||||
|
|
@ -465,7 +468,7 @@ public class ItemListFolderInviteLinkItemNode: ListViewItemNode, ItemListItemNod
|
|||
} 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: buttonHeight, cornerRadius: buttonHeight * 0.5)
|
||||
shareButtonNode.pressed = { [weak self] in
|
||||
self?.item?.shareAction?()
|
||||
}
|
||||
|
|
@ -485,7 +488,7 @@ public class ItemListFolderInviteLinkItemNode: ListViewItemNode, ItemListItemNod
|
|||
} else {
|
||||
buttonTheme = SolidRoundedButtonTheme(theme: item.presentationData.theme)
|
||||
}
|
||||
secondaryButtonNode = SolidRoundedButtonNode(theme: buttonTheme, height: 50.0, cornerRadius: 11.0)
|
||||
secondaryButtonNode = SolidRoundedButtonNode(theme: buttonTheme, glass: item.systemStyle == .glass, height: buttonHeight, cornerRadius: buttonHeight * 0.5)
|
||||
secondaryButtonNode.pressed = { [weak self] in
|
||||
self?.item?.secondaryAction?()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2649,18 +2649,20 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||
transition.updateTransformScale(node: self.moreButtonNode.iconNode, scale: moreIsVisible ? 1.0 : 0.1)
|
||||
}
|
||||
|
||||
if case .assets(_, .story) = self.subject, self.selectionCount > 0 {
|
||||
let text = self.presentationData.strings.MediaPicker_CreateStory(self.selectionCount)
|
||||
self.mainButtonStatePromise.set(.single(AttachmentMainButtonState(text: text, badge: nil, font: .bold, background: .color(self.presentationData.theme.actionSheet.controlAccentColor), textColor: self.presentationData.theme.list.itemCheckColors.foregroundColor, isVisible: true, progress: .none, isEnabled: true, hasShimmer: false, position: .top)))
|
||||
|
||||
if self.selectionCount > 1 && self.selectionCount <= 6 {
|
||||
self.secondaryButtonStatePromise.set(.single(AttachmentMainButtonState(text: self.presentationData.strings.MediaPicker_CombineIntoCollage, badge: nil, font: .regular, background: .color(.clear), textColor: self.presentationData.theme.actionSheet.controlAccentColor, isVisible: true, progress: .none, isEnabled: true, hasShimmer: false, iconName: "Media Editor/Collage", smallSpacing: true, position: .bottom)))
|
||||
if case .assets(_, .story) = self.subject {
|
||||
if self.selectionCount > 0 {
|
||||
let text = self.presentationData.strings.MediaPicker_CreateStory(self.selectionCount)
|
||||
self.mainButtonStatePromise.set(.single(AttachmentMainButtonState(text: text, badge: nil, font: .bold, background: .color(self.presentationData.theme.actionSheet.controlAccentColor), textColor: self.presentationData.theme.list.itemCheckColors.foregroundColor, isVisible: true, progress: .none, isEnabled: true, hasShimmer: false, position: .top)))
|
||||
|
||||
if self.selectionCount > 1 && self.selectionCount <= 6 {
|
||||
self.secondaryButtonStatePromise.set(.single(AttachmentMainButtonState(text: self.presentationData.strings.MediaPicker_CombineIntoCollage, badge: nil, font: .regular, background: .color(.clear), textColor: self.presentationData.theme.actionSheet.controlAccentColor, isVisible: true, progress: .none, isEnabled: true, hasShimmer: false, iconName: "Media Editor/Collage", smallSpacing: true, position: .bottom)))
|
||||
} else {
|
||||
self.secondaryButtonStatePromise.set(.single(nil))
|
||||
}
|
||||
} else {
|
||||
self.mainButtonStatePromise.set(.single(nil))
|
||||
self.secondaryButtonStatePromise.set(.single(nil))
|
||||
}
|
||||
} else {
|
||||
self.mainButtonStatePromise.set(.single(nil))
|
||||
self.secondaryButtonStatePromise.set(.single(nil))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3716,46 +3718,47 @@ public func stickerMediaPickerController(
|
|||
}
|
||||
mediaPickerController.openCamera = { [weak controller] cameraHolder in
|
||||
let _ = controller
|
||||
// guard let cameraHolder = cameraHolder as? CameraHolder else {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// var returnToCameraImpl: (() -> Void)?
|
||||
// let cameraScreen = CameraScreenImpl(
|
||||
// context: context,
|
||||
// mode: .sticker,
|
||||
// holder: cameraHolder,
|
||||
// transitionIn: CameraScreenImpl.TransitionIn(
|
||||
// sourceView: cameraHolder.parentView,
|
||||
// sourceRect: cameraHolder.parentView.bounds,
|
||||
// sourceCornerRadius: 0.0,
|
||||
// useFillAnimation: false
|
||||
// ),
|
||||
// transitionOut: { _ in
|
||||
// return CameraScreenImpl.TransitionOut(
|
||||
// destinationView: cameraHolder.parentView,
|
||||
// destinationRect: cameraHolder.parentView.bounds,
|
||||
// destinationCornerRadius: 0.0
|
||||
// )
|
||||
// },
|
||||
// completion: { result, _, _, commit in
|
||||
// completion(result, nil, .zero, nil, true, { _ in return nil }, {
|
||||
// returnToCameraImpl?()
|
||||
// })
|
||||
// }
|
||||
// )
|
||||
// cameraScreen.transitionedOut = { [weak cameraHolder] in
|
||||
// if let cameraHolder {
|
||||
// cameraHolder.restore()
|
||||
// }
|
||||
// }
|
||||
// controller?.push(cameraScreen)
|
||||
//
|
||||
// returnToCameraImpl = { [weak cameraScreen] in
|
||||
// if let cameraScreen {
|
||||
// cameraScreen.returnFromEditor()
|
||||
// }
|
||||
// }
|
||||
guard let cameraHolder = cameraHolder as? CameraHolder else {
|
||||
return
|
||||
}
|
||||
|
||||
var returnToCameraImpl: (() -> Void)?
|
||||
|
||||
let cameraScreen = context.sharedContext.makeCameraScreen(
|
||||
context: context,
|
||||
mode: .sticker,
|
||||
cameraHolder: cameraHolder,
|
||||
transitionIn: CameraScreenTransitionIn(
|
||||
sourceView: cameraHolder.parentView,
|
||||
sourceRect: cameraHolder.parentView.bounds,
|
||||
sourceCornerRadius: 0.0,
|
||||
useFillAnimation: false
|
||||
),
|
||||
transitionOut: { _ in
|
||||
return CameraScreenTransitionOut(
|
||||
destinationView: cameraHolder.parentView,
|
||||
destinationRect: cameraHolder.parentView.bounds,
|
||||
destinationCornerRadius: 0.0
|
||||
)
|
||||
},
|
||||
completion: { result, commit in
|
||||
completion(result, nil, .zero, nil, true, { _ in return nil }, {
|
||||
returnToCameraImpl?()
|
||||
})
|
||||
},
|
||||
transitionedOut: { [weak cameraHolder] in
|
||||
if let cameraHolder {
|
||||
cameraHolder.restore()
|
||||
}
|
||||
}
|
||||
)
|
||||
controller?.push(cameraScreen)
|
||||
|
||||
returnToCameraImpl = { [weak cameraScreen] in
|
||||
if let cameraScreen = cameraScreen as? CameraScreen {
|
||||
cameraScreen.returnFromEditor()
|
||||
}
|
||||
}
|
||||
}
|
||||
present(mediaPickerController, mediaPickerController.mediaPickerContext)
|
||||
}
|
||||
|
|
@ -3844,46 +3847,47 @@ public func avatarMediaPickerController(
|
|||
}
|
||||
mediaPickerController.openCamera = { [weak controller] cameraHolder in
|
||||
let _ = controller
|
||||
// guard let cameraHolder = cameraHolder as? CameraHolder else {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// var returnToCameraImpl: (() -> Void)?
|
||||
// let cameraScreen = CameraScreenImpl(
|
||||
// context: context,
|
||||
// mode: .avatar,
|
||||
// holder: cameraHolder,
|
||||
// transitionIn: CameraScreenImpl.TransitionIn(
|
||||
// sourceView: cameraHolder.parentView,
|
||||
// sourceRect: cameraHolder.parentView.bounds,
|
||||
// sourceCornerRadius: 0.0,
|
||||
// useFillAnimation: false
|
||||
// ),
|
||||
// transitionOut: { _ in
|
||||
// return CameraScreenImpl.TransitionOut(
|
||||
// destinationView: cameraHolder.parentView,
|
||||
// destinationRect: cameraHolder.parentView.bounds,
|
||||
// destinationCornerRadius: 0.0
|
||||
// )
|
||||
// },
|
||||
// completion: { result, _, _, commit in
|
||||
// completion(result, nil, .zero, nil, true, { _ in return nil }, {
|
||||
// returnToCameraImpl?()
|
||||
// })
|
||||
// }
|
||||
// )
|
||||
// cameraScreen.transitionedOut = { [weak cameraHolder] in
|
||||
// if let cameraHolder {
|
||||
// cameraHolder.restore()
|
||||
// }
|
||||
// }
|
||||
// controller?.push(cameraScreen)
|
||||
//
|
||||
// returnToCameraImpl = { [weak cameraScreen] in
|
||||
// if let cameraScreen {
|
||||
// cameraScreen.returnFromEditor()
|
||||
// }
|
||||
// }
|
||||
guard let cameraHolder = cameraHolder as? CameraHolder else {
|
||||
return
|
||||
}
|
||||
|
||||
var returnToCameraImpl: (() -> Void)?
|
||||
|
||||
let cameraScreen = context.sharedContext.makeCameraScreen(
|
||||
context: context,
|
||||
mode: .avatar,
|
||||
cameraHolder: cameraHolder,
|
||||
transitionIn: CameraScreenTransitionIn(
|
||||
sourceView: cameraHolder.parentView,
|
||||
sourceRect: cameraHolder.parentView.bounds,
|
||||
sourceCornerRadius: 0.0,
|
||||
useFillAnimation: false
|
||||
),
|
||||
transitionOut: { _ in
|
||||
return CameraScreenTransitionOut(
|
||||
destinationView: cameraHolder.parentView,
|
||||
destinationRect: cameraHolder.parentView.bounds,
|
||||
destinationCornerRadius: 0.0
|
||||
)
|
||||
},
|
||||
completion: { result, commit in
|
||||
completion(result, nil, .zero, nil, true, { _ in return nil }, {
|
||||
returnToCameraImpl?()
|
||||
})
|
||||
},
|
||||
transitionedOut: { [weak cameraHolder] in
|
||||
if let cameraHolder {
|
||||
cameraHolder.restore()
|
||||
}
|
||||
}
|
||||
)
|
||||
controller?.push(cameraScreen)
|
||||
|
||||
returnToCameraImpl = { [weak cameraScreen] in
|
||||
if let cameraScreen = cameraScreen as? CameraScreen {
|
||||
cameraScreen.returnFromEditor()
|
||||
}
|
||||
}
|
||||
}
|
||||
present(mediaPickerController, mediaPickerController.mediaPickerContext)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/ScrollComponent",
|
||||
"//submodules/TelegramUI/Components/Premium/PremiumStarComponent",
|
||||
"//submodules/TelegramUI/Components/Premium/PremiumCoinComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import SolidRoundedButtonComponent
|
|||
import BlurredBackgroundComponent
|
||||
import Markdown
|
||||
import TelegramUIPreferences
|
||||
import GlassBarButtonComponent
|
||||
|
||||
public final class PremiumGradientBackgroundComponent: Component {
|
||||
public let colors: [UIColor]
|
||||
|
|
@ -519,7 +520,6 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
|
||||
final class State: ComponentState {
|
||||
private let context: AccountContext
|
||||
var cachedCloseImage: UIImage?
|
||||
|
||||
var isPremium: Bool?
|
||||
var reactions: [AvailableReactions.Reaction]?
|
||||
|
|
@ -682,7 +682,7 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
}
|
||||
|
||||
static var body: Body {
|
||||
let closeButton = Child(Button.self)
|
||||
let closeButton = Child(GlassBarButtonComponent.self)
|
||||
let background = Child(PremiumGradientBackgroundComponent.self)
|
||||
let pager = Child(DemoPagerComponent.self)
|
||||
let button = Child(SolidRoundedButtonComponent.self)
|
||||
|
|
@ -695,9 +695,7 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
let strings = environment.strings
|
||||
|
||||
let state = context.state
|
||||
|
||||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||
|
||||
|
||||
let background = background.update(
|
||||
component: PremiumGradientBackgroundComponent(colors: [
|
||||
UIColor(rgb: 0x0077ff),
|
||||
|
|
@ -711,15 +709,7 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
context.add(background
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: background.size.height / 2.0))
|
||||
)
|
||||
|
||||
let closeImage: UIImage
|
||||
if let image = state.cachedCloseImage {
|
||||
closeImage = image
|
||||
} else {
|
||||
closeImage = generateCloseButtonImage(backgroundColor: .clear, foregroundColor: UIColor(rgb: 0xffffff))!
|
||||
state.cachedCloseImage = closeImage
|
||||
}
|
||||
|
||||
|
||||
var isStandalone = false
|
||||
if case .other = component.source {
|
||||
isStandalone = true
|
||||
|
|
@ -1140,38 +1130,30 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
.position(CGPoint(x: context.availableSize.width / 2.0, y: pager.size.height / 2.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
let closeButton = closeButton.update(
|
||||
component: Button(
|
||||
content: AnyComponent(ZStack([
|
||||
AnyComponentWithIdentity(
|
||||
id: "background",
|
||||
component: AnyComponent(
|
||||
BlurredBackgroundComponent(
|
||||
color: UIColor(rgb: 0x888888, alpha: 0.1)
|
||||
)
|
||||
)
|
||||
),
|
||||
AnyComponentWithIdentity(
|
||||
id: "icon",
|
||||
component: AnyComponent(
|
||||
Image(image: closeImage)
|
||||
)
|
||||
),
|
||||
])),
|
||||
action: { [weak component] in
|
||||
component?.dismiss()
|
||||
component: GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: theme.overallDarkAppearance,
|
||||
state: .glass,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
component.dismiss()
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: 30.0, height: 30.0),
|
||||
availableSize: CGSize(width: 40.0, height: 40.0),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(closeButton
|
||||
.position(CGPoint(x: context.availableSize.width - environment.safeInsets.left - closeButton.size.width, y: 28.0))
|
||||
.clipsToBounds(true)
|
||||
.cornerRadius(15.0)
|
||||
.position(CGPoint(x: 16.0 + closeButton.size.width / 2.0, y: 16.0 + closeButton.size.height / 2.0))
|
||||
)
|
||||
|
||||
|
||||
var measuredTextHeight: CGFloat?
|
||||
var text: String
|
||||
switch component.subject {
|
||||
|
|
@ -1309,6 +1291,7 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
}
|
||||
}
|
||||
|
||||
let bottomInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
|
||||
let button = button.update(
|
||||
component: SolidRoundedButtonComponent(
|
||||
title: buttonText,
|
||||
|
|
@ -1324,9 +1307,10 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
),
|
||||
font: .bold,
|
||||
fontSize: 17.0,
|
||||
height: 50.0,
|
||||
cornerRadius: 11.0,
|
||||
height: 52.0,
|
||||
cornerRadius: 26.0,
|
||||
gloss: state.isPremium != true,
|
||||
glass: true,
|
||||
animationName: isStandalone ? buttonAnimationName : nil,
|
||||
iconPosition: .right,
|
||||
iconSpacing: 4.0,
|
||||
|
|
@ -1340,7 +1324,7 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
}
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0),
|
||||
availableSize: CGSize(width: context.availableSize.width - bottomInsets.left - bottomInsets.right, height: 52.0),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
|
|
@ -1358,19 +1342,12 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
}
|
||||
}
|
||||
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight + 20.0), size: button.size)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: bottomInsets.left, y: contentHeight + 20.0), size: button.size)
|
||||
context.add(button
|
||||
.position(CGPoint(x: buttonFrame.midX, y: buttonFrame.midY))
|
||||
)
|
||||
|
||||
let bottomPanelPadding: CGFloat = 12.0
|
||||
let bottomInset: CGFloat
|
||||
if case .regular = environment.metrics.widthClass {
|
||||
bottomInset = bottomPanelPadding
|
||||
} else {
|
||||
bottomInset = environment.safeInsets.bottom > 0.0 ? environment.safeInsets.bottom + 5.0 : bottomPanelPadding
|
||||
}
|
||||
return CGSize(width: context.availableSize.width, height: buttonFrame.maxY + bottomInset)
|
||||
|
||||
return CGSize(width: context.availableSize.width, height: buttonFrame.maxY + bottomInsets.bottom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1428,6 +1405,7 @@ private final class DemoSheetComponent: CombinedComponent {
|
|||
})
|
||||
}
|
||||
)),
|
||||
style: .glass,
|
||||
backgroundColor: .color(environment.theme.actionSheet.opaqueItemBackgroundColor),
|
||||
followContentSizeChanges: context.component.source == .other,
|
||||
animateOut: animateOut
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import AvatarNode
|
|||
import TextFormat
|
||||
import RoundedRectWithTailPath
|
||||
import PremiumPeerShortcutComponent
|
||||
import GlassBarButtonComponent
|
||||
|
||||
func generateCloseButtonImage(backgroundColor: UIColor, foregroundColor: UIColor) -> UIImage? {
|
||||
return generateImage(CGSize(width: 30.0, height: 30.0), contextGenerator: { size, context in
|
||||
|
|
@ -177,7 +178,7 @@ public class PremiumLimitDisplayComponent: Component {
|
|||
override init(frame: CGRect) {
|
||||
self.container = UIView()
|
||||
self.container.clipsToBounds = true
|
||||
self.container.layer.cornerRadius = 6.0
|
||||
self.container.layer.cornerRadius = 15.0
|
||||
|
||||
self.inactiveBackground = SimpleLayer()
|
||||
|
||||
|
|
@ -783,7 +784,6 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
|
||||
var myBoostCount: Int32 = 0
|
||||
|
||||
var cachedCloseImage: (UIImage, PresentationTheme)?
|
||||
var cachedChevronImage: (UIImage, PresentationTheme)?
|
||||
|
||||
init(context: AccountContext, subject: PremiumLimitScreen.Subject) {
|
||||
|
|
@ -819,7 +819,7 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
}
|
||||
|
||||
static var body: Body {
|
||||
let closeButton = Child(Button.self)
|
||||
let closeButton = Child(GlassBarButtonComponent.self)
|
||||
let title = Child(MultilineTextComponent.self)
|
||||
let text = Child(BalancedTextComponent.self)
|
||||
let alternateText = Child(List<Empty>.self)
|
||||
|
|
@ -854,27 +854,29 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||
let textSideInset: CGFloat = 32.0 + environment.safeInsets.left
|
||||
|
||||
let closeImage: UIImage
|
||||
if let (image, theme) = state.cachedCloseImage, theme === environment.theme {
|
||||
closeImage = image
|
||||
} else {
|
||||
closeImage = generateCloseButtonImage(backgroundColor: UIColor(rgb: 0x808084, alpha: 0.1), foregroundColor: theme.actionSheet.inputClearButtonColor)!
|
||||
state.cachedCloseImage = (closeImage, theme)
|
||||
}
|
||||
|
||||
|
||||
let closeButton = closeButton.update(
|
||||
component: Button(
|
||||
content: AnyComponent(Image(image: closeImage)),
|
||||
action: { [weak component] in
|
||||
component?.dismiss()
|
||||
component?.cancel()
|
||||
component: GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: theme.overallDarkAppearance,
|
||||
state: .generic,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
component.dismiss()
|
||||
component.cancel()
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: 30.0, height: 30.0),
|
||||
availableSize: CGSize(width: 40.0, height: 40.0),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(closeButton
|
||||
.position(CGPoint(x: context.availableSize.width - environment.safeInsets.left - closeButton.size.width, y: 28.0))
|
||||
.position(CGPoint(x: 16.0 + closeButton.size.width / 2.0, y: 16.0 + closeButton.size.height / 2.0))
|
||||
)
|
||||
|
||||
var boostUpdated = false
|
||||
|
|
@ -1394,17 +1396,6 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height),
|
||||
transition: .immediate
|
||||
)
|
||||
|
||||
// alternateTextChild = alternateText.update(
|
||||
// component: BalancedTextComponent(
|
||||
// text: .markdown(text: string, attributes: markdownAttributes),
|
||||
// horizontalAlignment: .center,
|
||||
// maximumNumberOfLines: 0,
|
||||
// lineSpacing: 0.1
|
||||
// ),
|
||||
// availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height),
|
||||
// transition: .immediate
|
||||
// )
|
||||
} else {
|
||||
textChild = text.update(
|
||||
component: BalancedTextComponent(
|
||||
|
|
@ -1456,6 +1447,8 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
}
|
||||
|
||||
let isIncreaseButton = !reachedMaximumLimit && !isPremiumDisabled
|
||||
|
||||
let bottomInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
|
||||
let button = button.update(
|
||||
component: SolidRoundedButtonComponent(
|
||||
title: actionButtonText ?? (isIncreaseButton ? strings.Premium_IncreaseLimit : strings.Common_OK),
|
||||
|
|
@ -1466,9 +1459,10 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
),
|
||||
font: .bold,
|
||||
fontSize: 17.0,
|
||||
height: 50.0,
|
||||
cornerRadius: 10.0,
|
||||
height: 52.0,
|
||||
cornerRadius: 26.0,
|
||||
gloss: isIncreaseButton && actionButtonHasGloss,
|
||||
glass: true,
|
||||
iconName: buttonIconName,
|
||||
animationName: isIncreaseButton ? buttonAnimationName : nil,
|
||||
iconPosition: buttonIconName != nil ? .left : .right,
|
||||
|
|
@ -1482,7 +1476,7 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
}
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0),
|
||||
availableSize: CGSize(width: context.availableSize.width - bottomInsets.left - bottomInsets.right, height: 52.0),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
|
|
@ -1501,20 +1495,20 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
),
|
||||
font: .regular,
|
||||
fontSize: 17.0,
|
||||
height: 50.0,
|
||||
cornerRadius: 10.0,
|
||||
height: 52.0,
|
||||
cornerRadius: 26.0,
|
||||
action: {
|
||||
if component.action() {
|
||||
component.dismiss()
|
||||
}
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0),
|
||||
availableSize: CGSize(width: context.availableSize.width - bottomInsets.left - bottomInsets.right, height: 52.0),
|
||||
transition: context.transition
|
||||
)
|
||||
buttonOffset += 66.0
|
||||
|
||||
let linkFrame = CGRect(origin: CGPoint(x: sideInset, y: textOffset + (textChild?.size ?? .zero).height + 24.0), size: linkButton.size)
|
||||
let linkFrame = CGRect(origin: CGPoint(x: bottomInsets.left, y: textOffset + (textChild?.size ?? .zero).height + 24.0), size: linkButton.size)
|
||||
context.add(linkButton
|
||||
.position(CGPoint(x: linkFrame.midX, y: linkFrame.midY))
|
||||
)
|
||||
|
|
@ -1525,7 +1519,7 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
}
|
||||
|
||||
context.add(title
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: 28.0))
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: 36.0))
|
||||
)
|
||||
|
||||
var textSize: CGSize
|
||||
|
|
@ -1594,7 +1588,7 @@ private final class LimitSheetContent: CombinedComponent {
|
|||
.position(CGPoint(x: context.availableSize.width / 2.0, y: limit.size.height / 2.0 + 44.0 + topOffset))
|
||||
)
|
||||
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: textOffset + ceil(textSize.height / 2.0) + buttonOffset + 24.0), size: button.size)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: bottomInsets.left, y: textOffset + ceil(textSize.height / 2.0) + buttonOffset + 24.0), size: button.size)
|
||||
context.add(button
|
||||
.position(CGPoint(x: buttonFrame.midX, y: buttonFrame.midY))
|
||||
)
|
||||
|
|
@ -1760,6 +1754,7 @@ private final class LimitSheetComponent: CombinedComponent {
|
|||
openStats: context.component.openStats,
|
||||
openGift: context.component.openGift
|
||||
)),
|
||||
style: .glass,
|
||||
backgroundColor: .color(environment.theme.actionSheet.opaqueItemBackgroundColor),
|
||||
followContentSizeChanges: true,
|
||||
externalState: sheetExternalState,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ public enum ServerProvidedSuggestion: Equatable {
|
|||
case gracePremium
|
||||
case starsSubscriptionLowBalance
|
||||
case setupPhoto
|
||||
case setupLoginEmail
|
||||
case setupLoginEmailBlocking
|
||||
case link(id: String, url: String, title: ServerSuggestionInfo.Item.Text, subtitle: ServerSuggestionInfo.Item.Text)
|
||||
|
||||
init?(string: String) {
|
||||
|
|
@ -50,6 +52,10 @@ public enum ServerProvidedSuggestion: Equatable {
|
|||
self = .starsSubscriptionLowBalance
|
||||
case "USERPIC_SETUP":
|
||||
self = .setupPhoto
|
||||
case "SETUP_LOGIN_EMAIL":
|
||||
self = .setupLoginEmail
|
||||
case "SETUP_LOGIN_EMAIL_NOSKIP":
|
||||
self = .setupLoginEmailBlocking
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
|
@ -85,6 +91,10 @@ public enum ServerProvidedSuggestion: Equatable {
|
|||
return "STARS_SUBSCRIPTION_LOW_BALANCE"
|
||||
case .setupPhoto:
|
||||
return "USERPIC_SETUP"
|
||||
case .setupLoginEmail:
|
||||
return "SETUP_LOGIN_EMAIL"
|
||||
case .setupLoginEmailBlocking:
|
||||
return "SETUP_LOGIN_EMAIL_NOSKIP"
|
||||
case let .link(id, _, _, _):
|
||||
return id
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ swift_library(
|
|||
"//submodules/Components/ViewControllerComponent",
|
||||
"//submodules/Components/ComponentDisplayAdapters",
|
||||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/AppBundle",
|
||||
|
|
@ -30,6 +31,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/ListSectionComponent",
|
||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ final class AdminUserActionsPeerComponent: Component {
|
|||
|
||||
let contextInset: CGFloat = 0.0
|
||||
|
||||
let height: CGFloat = 44.0
|
||||
let height: CGFloat = 52.0
|
||||
let verticalInset: CGFloat = 1.0
|
||||
let leftInset: CGFloat = 30.0 + component.sideInset
|
||||
var rightInset: CGFloat = contextInset * 2.0 + 8.0 + component.sideInset
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import TelegramStringFormatting
|
|||
import ListSectionComponent
|
||||
import ListActionItemComponent
|
||||
import PlainButtonComponent
|
||||
import GlassBarButtonComponent
|
||||
import BundleIconComponent
|
||||
|
||||
private enum ActionTypeSection: Hashable, CaseIterable {
|
||||
case members
|
||||
|
|
@ -486,19 +488,28 @@ private final class RecentActionsSettingsSheetComponent: Component {
|
|||
|
||||
let leftButtonSize = self.leftButton.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
|
||||
component: AnyComponent(GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: environment.theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: environment.theme.overallDarkAppearance,
|
||||
state: .generic,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: environment.theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
)
|
||||
)),
|
||||
action: { [weak self] _ in
|
||||
guard let self, let controller = self.environment?.controller() else {
|
||||
return
|
||||
}
|
||||
controller.dismiss()
|
||||
}
|
||||
).minSize(CGSize(width: 44.0, height: 56.0))),
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 120.0, height: 100.0)
|
||||
containerSize: CGSize(width: 40.0, height: 40.0)
|
||||
)
|
||||
let leftButtonFrame = CGRect(origin: CGPoint(x: 16.0 + environment.safeInsets.left, y: 0.0), size: leftButtonSize)
|
||||
let leftButtonFrame = CGRect(origin: CGPoint(x: 16.0 + environment.safeInsets.left, y: 16.0), size: leftButtonSize)
|
||||
if let leftButtonView = self.leftButton.view {
|
||||
if leftButtonView.superview == nil {
|
||||
self.navigationBarContainer.addSubview(leftButtonView)
|
||||
|
|
@ -582,6 +593,7 @@ private final class RecentActionsSettingsSheetComponent: Component {
|
|||
|
||||
return AnyComponentWithIdentity(id: sectionId, component: AnyComponent(ListActionItemComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
title: itemTitle,
|
||||
leftIcon: .check(ListActionItemComponent.LeftIcon.Check(
|
||||
isSelected: selectedCount == totalCount,
|
||||
|
|
@ -661,6 +673,7 @@ private final class RecentActionsSettingsSheetComponent: Component {
|
|||
|
||||
subItems.append(AnyComponentWithIdentity(id: actionType, component: AnyComponent(ListActionItemComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
|
|
@ -702,7 +715,7 @@ private final class RecentActionsSettingsSheetComponent: Component {
|
|||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - leftButtonFrame.maxX * 2.0, height: 100.0)
|
||||
)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) * 0.5), y: floor((54.0 - titleSize.height) * 0.5)), size: titleSize)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) * 0.5), y: floor((72.0 - titleSize.height) * 0.5)), size: titleSize)
|
||||
if let titleView = title.view {
|
||||
if titleView.superview == nil {
|
||||
self.navigationBarContainer.addSubview(titleView)
|
||||
|
|
@ -728,6 +741,7 @@ private final class RecentActionsSettingsSheetComponent: Component {
|
|||
transition: optionsSectionTransition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: environment.strings.Channel_AdminLogFilter_FilterActionsTypeTitle,
|
||||
|
|
@ -796,6 +810,7 @@ private final class RecentActionsSettingsSheetComponent: Component {
|
|||
}
|
||||
adminsSectionItems.append(AnyComponentWithIdentity(id: adminsSectionItems.count, component: AnyComponent(ListActionItemComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
|
|
@ -828,6 +843,7 @@ private final class RecentActionsSettingsSheetComponent: Component {
|
|||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: environment.strings.Channel_AdminLogFilter_FilterActionsAdminsTitle,
|
||||
|
|
@ -854,10 +870,12 @@ private final class RecentActionsSettingsSheetComponent: Component {
|
|||
|
||||
contentHeight += 30.0
|
||||
|
||||
let bottomInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
|
||||
let actionButtonSize = self.actionButton.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.9)
|
||||
|
|
@ -883,10 +901,10 @@ private final class RecentActionsSettingsSheetComponent: Component {
|
|||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 50.0)
|
||||
containerSize: CGSize(width: availableSize.width - bottomInsets.left - bottomInsets.right, height: 52.0)
|
||||
)
|
||||
let bottomPanelHeight = 8.0 + environment.safeInsets.bottom + actionButtonSize.height
|
||||
let actionButtonFrame = CGRect(origin: CGPoint(x: sideInset, y: availableSize.height - bottomPanelHeight), size: actionButtonSize)
|
||||
let bottomPanelHeight = actionButtonSize.height + bottomInsets.bottom
|
||||
let actionButtonFrame = CGRect(origin: CGPoint(x: bottomInsets.left, y: availableSize.height - bottomPanelHeight), size: actionButtonSize)
|
||||
if let actionButtonView = actionButton.view {
|
||||
if actionButtonView.superview == nil {
|
||||
self.addSubview(actionButtonView)
|
||||
|
|
|
|||
|
|
@ -226,11 +226,11 @@ final class AvatarEditorScreenComponent: Component {
|
|||
|
||||
self.backgroundContainerView = UIView()
|
||||
self.backgroundContainerView.clipsToBounds = true
|
||||
self.backgroundContainerView.layer.cornerRadius = 10.0
|
||||
self.backgroundContainerView.layer.cornerRadius = 26.0
|
||||
|
||||
self.keyboardContainerView = UIView()
|
||||
self.keyboardContainerView.clipsToBounds = true
|
||||
self.keyboardContainerView.layer.cornerRadius = 10.0
|
||||
self.keyboardContainerView.layer.cornerRadius = 26.0
|
||||
|
||||
self.panelBackgroundView = BlurredBackgroundView(color: .white)
|
||||
self.panelHostView = PagerExternalTopPanelContainer()
|
||||
|
|
@ -1317,11 +1317,13 @@ final class AvatarEditorScreenComponent: Component {
|
|||
))))
|
||||
}
|
||||
|
||||
let bottomInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
|
||||
let buttonSize = self.buttonView.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(
|
||||
ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
style: .glass,
|
||||
color: theme.list.itemCheckColors.fillColor,
|
||||
foreground: theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.8)
|
||||
|
|
@ -1337,13 +1339,13 @@ final class AvatarEditorScreenComponent: Component {
|
|||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 50.0)
|
||||
containerSize: CGSize(width: availableSize.width - bottomInsets.left - bottomInsets.right, height: 52.0)
|
||||
)
|
||||
if let buttonView = self.buttonView.view {
|
||||
if buttonView.superview == nil {
|
||||
self.addSubview(buttonView)
|
||||
}
|
||||
transition.setFrame(view: buttonView, frame: CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: buttonSize))
|
||||
transition.setFrame(view: buttonView, frame: CGRect(origin: CGPoint(x: bottomInsets.left, y: contentHeight), size: buttonSize))
|
||||
}
|
||||
|
||||
let bottomPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight - 4.0), size: CGSize(width: availableSize.width, height: availableSize.height - contentHeight + 4.0))
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ final class BackgroundColorComponent: Component {
|
|||
var validIds: [AnyHashable] = []
|
||||
for i in 0 ..< values.count {
|
||||
let position: CGFloat = sideInset + (spacing + itemSize.width) * CGFloat(i)
|
||||
let itemFrame = CGRect(origin: CGPoint(x: position, y: 10.0), size: itemSize)
|
||||
let itemFrame = CGRect(origin: CGPoint(x: position, y: 11.0), size: itemSize)
|
||||
var isVisible = false
|
||||
if visibleBounds.intersects(itemFrame) {
|
||||
isVisible = true
|
||||
|
|
@ -171,7 +171,7 @@ final class BackgroundColorComponent: Component {
|
|||
self.component = component
|
||||
self.state = state
|
||||
|
||||
let height: CGFloat = 50.0
|
||||
let height: CGFloat = 52.0
|
||||
let size = CGSize(width: availableSize.width, height: height)
|
||||
let scrollFrame = CGRect(origin: .zero, size: size)
|
||||
|
||||
|
|
|
|||
|
|
@ -617,7 +617,7 @@ public final class ButtonComponent: Component {
|
|||
})
|
||||
}
|
||||
|
||||
if component.background.style == .glass {
|
||||
if component.background.style == .glass, component.background.color.alpha > 0.9 {
|
||||
let chromeView: UIImageView
|
||||
var chromeTransition = transition
|
||||
if let current = self.chromeView {
|
||||
|
|
|
|||
|
|
@ -21,11 +21,20 @@ private let calendar = Calendar(identifier: .gregorian)
|
|||
private final class ChatScheduleTimeSheetContentComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
public class ExternalState {
|
||||
public fileprivate(set) var repeatValueFrame: CGRect
|
||||
|
||||
public init() {
|
||||
self.repeatValueFrame = .zero
|
||||
}
|
||||
}
|
||||
|
||||
let context: AccountContext
|
||||
let mode: ChatScheduleTimeScreen.Mode
|
||||
let currentTime: Int32?
|
||||
let currentRepeatPeriod: Int32?
|
||||
let minimalTime: Int32?
|
||||
let externalState: ExternalState
|
||||
let dismiss: () -> Void
|
||||
|
||||
init(
|
||||
|
|
@ -34,6 +43,7 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
currentTime: Int32?,
|
||||
currentRepeatPeriod: Int32?,
|
||||
minimalTime: Int32?,
|
||||
externalState: ExternalState,
|
||||
dismiss: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
|
|
@ -41,6 +51,7 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
self.currentTime = currentTime
|
||||
self.currentRepeatPeriod = currentRepeatPeriod
|
||||
self.minimalTime = minimalTime
|
||||
self.externalState = externalState
|
||||
self.dismiss = dismiss
|
||||
}
|
||||
|
||||
|
|
@ -133,14 +144,18 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
defer {
|
||||
self.isUpdating = false
|
||||
}
|
||||
|
||||
let environment = environment[EnvironmentType.self].value
|
||||
|
||||
let themeUpdated = self.environment?.theme != environment.theme
|
||||
|
||||
self.environment = environment
|
||||
|
||||
if self.component == nil {
|
||||
self.updateMinimumDate(currentTime: component.currentTime, minimalTime: component.minimalTime)
|
||||
self.repeatPeriod = component.currentRepeatPeriod
|
||||
}
|
||||
|
||||
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
|
|
@ -210,6 +225,10 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
let datePicker: DatePickerNode
|
||||
if let current = self.datePicker {
|
||||
datePicker = current
|
||||
|
||||
if themeUpdated {
|
||||
datePicker.updateTheme(DatePickerTheme(theme: environment.theme))
|
||||
}
|
||||
} else {
|
||||
datePicker = DatePickerNode(
|
||||
theme: DatePickerTheme(theme: environment.theme),
|
||||
|
|
@ -588,6 +607,7 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
theme: environment.theme,
|
||||
sourceFrame: repeatValueFrame,
|
||||
component: AnyComponent(RepeatMenuComponent(
|
||||
theme: environment.theme,
|
||||
value: self.repeatPeriod,
|
||||
valueUpdated: { [weak self] value in
|
||||
guard let self, let component = self.component, let environment = self.environment else {
|
||||
|
|
@ -602,13 +622,13 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
content: .premiumPaywall(
|
||||
title: "Premium Required",
|
||||
text: "Subscribe to **Telegram Premium** to schedule repeating messages.",
|
||||
customUndoText: nil,
|
||||
customUndoText: "Add",
|
||||
timeout: nil,
|
||||
linkAction: nil
|
||||
),
|
||||
elevatedLayout: true,
|
||||
elevatedLayout: false,
|
||||
action: { [weak environment] action in
|
||||
if case .info = action {
|
||||
if case .undo = action {
|
||||
var replaceImpl: ((ViewController) -> Void)?
|
||||
let controller = component.context.sharedContext.makePremiumDemoController(context: component.context, subject: .colors, forceDark: false, action: {
|
||||
let controller = component.context.sharedContext.makePremiumIntroController(context: component.context, source: .nameColor, forceDark: false, dismissed: nil)
|
||||
|
|
@ -656,30 +676,7 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
// if let controller = environment.controller(), !controller.automaticallyControlPresentationContextLayout {
|
||||
// let sideInset: CGFloat = 0.0
|
||||
// let bottomInset: CGFloat = max(environment.safeInsets.bottom, contentHeight)
|
||||
//// if case .regular = environment.metrics.widthClass {
|
||||
//// sideInset = floor((context.availableSize.width - 430.0) / 2.0) - 12.0
|
||||
//// bottomInset = (context.availableSize.height - sheetExternalState.contentHeight) / 2.0 + sheetExternalState.contentHeight
|
||||
//// }
|
||||
//
|
||||
// let layout = ContainerViewLayout(
|
||||
// size: availableSize,
|
||||
// metrics: environment.metrics,
|
||||
// deviceMetrics: environment.deviceMetrics,
|
||||
// intrinsicInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: bottomInset, right: 0.0),
|
||||
// safeInsets: UIEdgeInsets(top: 0.0, left: max(sideInset, environment.safeInsets.left), bottom: 0.0, right: max(sideInset, environment.safeInsets.right)),
|
||||
// additionalInsets: .zero,
|
||||
// statusBarHeight: environment.statusBarHeight,
|
||||
// inputHeight: nil,
|
||||
// inputHeightIsInteractivellyChanging: false,
|
||||
// inVoiceOver: false
|
||||
// )
|
||||
// controller.presentationContext.containerLayoutUpdated(layout, transition: transition.containedViewLayoutTransition)
|
||||
// }
|
||||
|
||||
component.externalState.repeatValueFrame = repeatValueFrame
|
||||
|
||||
return contentSize
|
||||
}
|
||||
|
|
@ -739,6 +736,8 @@ private final class ChatScheduleTimeScreenComponent: Component {
|
|||
final class View: UIView {
|
||||
private let sheet = ComponentView<(ViewControllerComponentContainer.Environment, SheetComponentEnvironment)>()
|
||||
private let sheetAnimateOut = ActionSlot<Action<Void>>()
|
||||
private let sheetExternalState = SheetComponent<EnvironmentType>.ExternalState()
|
||||
private let contentExternalState = ChatScheduleTimeSheetContentComponent.ExternalState()
|
||||
|
||||
private var component: ChatScheduleTimeScreenComponent?
|
||||
private var environment: EnvironmentType?
|
||||
|
|
@ -782,6 +781,7 @@ private final class ChatScheduleTimeScreenComponent: Component {
|
|||
currentTime: component.currentTime,
|
||||
currentRepeatPeriod: component.currentRepeatPeriod,
|
||||
minimalTime: component.minimalTime,
|
||||
externalState: self.contentExternalState,
|
||||
dismiss: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
|
|
@ -796,6 +796,7 @@ private final class ChatScheduleTimeScreenComponent: Component {
|
|||
style: .glass,
|
||||
backgroundColor: .color(environment.theme.actionSheet.opaqueItemBackgroundColor),
|
||||
followContentSizeChanges: true,
|
||||
externalState: self.sheetExternalState,
|
||||
animateOut: self.sheetAnimateOut
|
||||
)),
|
||||
environment: {
|
||||
|
|
@ -811,6 +812,25 @@ private final class ChatScheduleTimeScreenComponent: Component {
|
|||
transition.setFrame(view: sheetView, frame: CGRect(origin: CGPoint(), size: availableSize))
|
||||
}
|
||||
|
||||
if let controller = environment.controller(), !controller.automaticallyControlPresentationContextLayout {
|
||||
let sideInset: CGFloat = 20.0
|
||||
let bottomInset: CGFloat = self.sheetExternalState.contentHeight - self.contentExternalState.repeatValueFrame.minY + 14.0
|
||||
|
||||
let layout = ContainerViewLayout(
|
||||
size: availableSize,
|
||||
metrics: environment.metrics,
|
||||
deviceMetrics: environment.deviceMetrics,
|
||||
intrinsicInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: bottomInset, right: 0.0),
|
||||
safeInsets: UIEdgeInsets(top: 0.0, left: max(sideInset, environment.safeInsets.left), bottom: 0.0, right: max(sideInset, environment.safeInsets.right)),
|
||||
additionalInsets: .zero,
|
||||
statusBarHeight: environment.statusBarHeight,
|
||||
inputHeight: nil,
|
||||
inputHeightIsInteractivellyChanging: false,
|
||||
inVoiceOver: false
|
||||
)
|
||||
controller.presentationContext.containerLayoutUpdated(layout, transition: transition.containedViewLayoutTransition)
|
||||
}
|
||||
|
||||
return availableSize
|
||||
}
|
||||
}
|
||||
|
|
@ -860,7 +880,7 @@ public class ChatScheduleTimeScreen: ViewControllerComponentContainer {
|
|||
self.navigationPresentation = .flatModal
|
||||
self.blocksBackgroundWhenInOverlay = true
|
||||
|
||||
//self.automaticallyControlPresentationContextLayout = false
|
||||
self.automaticallyControlPresentationContextLayout = false
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
|
|
@ -1148,18 +1168,24 @@ private final class MenuComponent: Component {
|
|||
}
|
||||
|
||||
private final class RepeatMenuComponent: Component {
|
||||
let theme: PresentationTheme
|
||||
let value: Int32?
|
||||
let valueUpdated: (Int32?) -> Void
|
||||
|
||||
init(
|
||||
theme: PresentationTheme,
|
||||
value: Int32?,
|
||||
valueUpdated: @escaping (Int32?) -> Void
|
||||
) {
|
||||
self.theme = theme
|
||||
self.value = value
|
||||
self.valueUpdated = valueUpdated
|
||||
}
|
||||
|
||||
public static func ==(lhs: RepeatMenuComponent, rhs: RepeatMenuComponent) -> Bool {
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
if lhs.value != rhs.value {
|
||||
return false
|
||||
}
|
||||
|
|
@ -1205,14 +1231,16 @@ private final class RepeatMenuComponent: Component {
|
|||
let sideInset: CGFloat = 18.0
|
||||
let itemInset: CGFloat = 60.0
|
||||
|
||||
self.checkIcon.tintColor = .black
|
||||
let textColor = component.theme.contextMenu.primaryColor
|
||||
|
||||
self.checkIcon.tintColor = textColor
|
||||
|
||||
let neverSize = self.never.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(
|
||||
PlainButtonComponent(
|
||||
content: AnyComponent(
|
||||
Text(text: "Never", font: Font.regular(17.0), color: .black)
|
||||
Text(text: "Never", font: Font.regular(17.0), color: textColor)
|
||||
),
|
||||
action: { [weak self] in
|
||||
guard let self else {
|
||||
|
|
@ -1277,7 +1305,7 @@ private final class RepeatMenuComponent: Component {
|
|||
component: AnyComponent(
|
||||
PlainButtonComponent(
|
||||
content: AnyComponent(
|
||||
Text(text: repeatString, font: Font.regular(17.0), color: .black)
|
||||
Text(text: repeatString, font: Font.regular(17.0), color: textColor)
|
||||
),
|
||||
action: { [weak self] in
|
||||
guard let self else {
|
||||
|
|
@ -1311,7 +1339,7 @@ private final class RepeatMenuComponent: Component {
|
|||
|
||||
let size = CGSize(width: itemInset + maxWidth + 40.0, height: originY)
|
||||
|
||||
self.separator.backgroundColor = UIColor(rgb: 0xdddddd).cgColor
|
||||
self.separator.backgroundColor = textColor.withMultipliedAlpha(0.6).cgColor
|
||||
self.separator.frame = CGRect(origin: CGPoint(x: sideInset, y: 62.0), size: CGSize(width: size.width - sideInset * 2.0, height: UIScreenPixel))
|
||||
|
||||
return size
|
||||
|
|
|
|||
|
|
@ -374,8 +374,8 @@ private class MessagePriceItemNode: ListViewItemNode {
|
|||
|
||||
let centralLeftText = item.value == 0 ? item.strings.Stars_SendMessage_PriceFree : item.strings.Privacy_Messages_Stars(Int32(clamping: item.value))
|
||||
|
||||
strongSelf.centerLeftTextNode.attributedText = NSAttributedString(string: centralLeftText, font: textFont, textColor: item.openSetCustom != nil ? item.theme.list.itemAccentColor : item.theme.list.itemPrimaryTextColor)
|
||||
strongSelf.centerRightTextNode.attributedText = NSAttributedString(string: item.price, font: smallTextFont, textColor: item.openSetCustom != nil ? item.theme.list.itemAccentColor.withMultipliedAlpha(0.5) : item.theme.list.itemSecondaryTextColor)
|
||||
strongSelf.centerLeftTextNode.attributedText = NSAttributedString(string: centralLeftText, font: textFont, textColor: item.openSetCustom != nil && item.isEnabled ? item.theme.list.itemAccentColor : item.theme.list.itemPrimaryTextColor)
|
||||
strongSelf.centerRightTextNode.attributedText = NSAttributedString(string: item.price, font: smallTextFont, textColor: item.openSetCustom != nil && item.isEnabled ? item.theme.list.itemAccentColor.withMultipliedAlpha(0.5) : item.theme.list.itemSecondaryTextColor)
|
||||
|
||||
let leftTextSize = strongSelf.leftTextNode.updateLayout(CGSize(width: 100.0, height: 100.0))
|
||||
let rightTextSize = strongSelf.rightTextNode.updateLayout(CGSize(width: 100.0, height: 100.0))
|
||||
|
|
@ -402,7 +402,7 @@ private class MessagePriceItemNode: ListViewItemNode {
|
|||
}
|
||||
strongSelf.centerTextButtonBackground.tintColor = item.theme.list.itemAccentColor.withMultipliedAlpha(0.1)
|
||||
|
||||
if item.openSetCustom != nil {
|
||||
if item.openSetCustom != nil && item.isEnabled {
|
||||
strongSelf.centerTextButtonNode.isEnabled = true
|
||||
strongSelf.centerTextButtonBackground.isHidden = false
|
||||
} else {
|
||||
|
|
@ -446,12 +446,13 @@ private class MessagePriceItemNode: ListViewItemNode {
|
|||
}
|
||||
|
||||
let sideInset: CGFloat = 16.0
|
||||
let buttonSize = CGSize(width: params.width - params.leftInset - params.rightInset - sideInset * 2.0, height: 50.0)
|
||||
let buttonSize = CGSize(width: params.width - params.leftInset - params.rightInset - sideInset * 2.0, height: 52.0)
|
||||
let _ = strongSelf.button.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
style: .glass,
|
||||
color: item.theme.list.itemCheckColors.fillColor,
|
||||
foreground: item.theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: item.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9)
|
||||
|
|
|
|||
|
|
@ -302,6 +302,7 @@ final class PostSuggestionsSettingsScreenComponent: Component {
|
|||
var switchSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
switchSectionItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
|
|
@ -326,6 +327,7 @@ final class PostSuggestionsSettingsScreenComponent: Component {
|
|||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
header: nil,
|
||||
footer: nil,
|
||||
items: switchSectionItems
|
||||
|
|
@ -394,6 +396,7 @@ final class PostSuggestionsSettingsScreenComponent: Component {
|
|||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: environment.strings.ChannelMessages_PriceSectionTitle,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ swift_library(
|
|||
"//submodules/Components/ViewControllerComponent",
|
||||
"//submodules/Components/ComponentDisplayAdapters",
|
||||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/AppBundle",
|
||||
|
|
@ -26,6 +27,7 @@ swift_library(
|
|||
"//submodules/PresentationDataUtils",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ public final class BirthdayPickerContentComponent: Component {
|
|||
|
||||
let sideInset: CGFloat = 16.0
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
var contentHeight: CGFloat = 8.0
|
||||
|
||||
let titleString = NSMutableAttributedString()
|
||||
let titleRawString: String
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ import Display
|
|||
import ComponentFlow
|
||||
import SwiftSignalKit
|
||||
import ViewControllerComponent
|
||||
import TelegramCore
|
||||
import AccountContext
|
||||
import SheetComponent
|
||||
import ButtonComponent
|
||||
import TelegramCore
|
||||
import GlassBarButtonComponent
|
||||
import BundleIconComponent
|
||||
|
||||
private final class BirthdayPickerSheetContentComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
|
@ -116,18 +118,29 @@ private final class BirthdayPickerSheetContentComponent: Component {
|
|||
|
||||
let cancelSize = self.cancel.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
|
||||
if let self, let component = self.component {
|
||||
component.dismiss()
|
||||
component: AnyComponent(
|
||||
GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: environment.theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: environment.theme.overallDarkAppearance,
|
||||
state: .generic,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: environment.theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
)
|
||||
)),
|
||||
action: { [weak self] _ in
|
||||
if let self, let component = self.component {
|
||||
component.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
).minSize(CGSize(width: 32.0, height: 32.0))),
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width, height: 32.0)
|
||||
containerSize: CGSize(width: 40.0, height: 40.0)
|
||||
)
|
||||
let cancelFrame = CGRect(origin: CGPoint(x: sideInset, y: 13.0), size: cancelSize)
|
||||
let cancelFrame = CGRect(origin: CGPoint(x: 16.0, y: 16.0), size: cancelSize)
|
||||
if let cancelView = self.cancel.view {
|
||||
if cancelView.superview == nil {
|
||||
self.addSubview(cancelView)
|
||||
|
|
@ -145,10 +158,12 @@ private final class BirthdayPickerSheetContentComponent: Component {
|
|||
buttonTitle = environment.strings.SuggestBirthdate_Accept_Action
|
||||
}
|
||||
|
||||
let bottomInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
|
||||
let buttonSize = self.button.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
style: .glass,
|
||||
color: environment.theme.list.itemCheckColors.fillColor,
|
||||
foreground: environment.theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.8)
|
||||
|
|
@ -166,9 +181,9 @@ private final class BirthdayPickerSheetContentComponent: Component {
|
|||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 50.0)
|
||||
containerSize: CGSize(width: availableSize.width - bottomInsets.left - bottomInsets.right, height: 52.0)
|
||||
)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: buttonSize)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: bottomInsets.left, y: contentHeight), size: buttonSize)
|
||||
if let buttonView = self.button.view {
|
||||
if buttonView.superview == nil {
|
||||
self.addSubview(buttonView)
|
||||
|
|
@ -176,13 +191,8 @@ private final class BirthdayPickerSheetContentComponent: Component {
|
|||
transition.setFrame(view: buttonView, frame: buttonFrame)
|
||||
}
|
||||
contentHeight += buttonSize.height
|
||||
|
||||
if environment.safeInsets.bottom.isZero {
|
||||
contentHeight += 16.0
|
||||
} else {
|
||||
contentHeight += environment.safeInsets.bottom + 14.0
|
||||
}
|
||||
|
||||
contentHeight += bottomInsets.bottom
|
||||
|
||||
return CGSize(width: availableSize.width, height: contentHeight)
|
||||
}
|
||||
}
|
||||
|
|
@ -321,6 +331,7 @@ private final class BirthdayPickerScreenComponent: Component {
|
|||
controller.requestLayout(forceUpdate: true, transition: transition)
|
||||
}
|
||||
)),
|
||||
style: .glass,
|
||||
backgroundColor: .color(environment.theme.list.plainBackgroundColor),
|
||||
followContentSizeChanges: true,
|
||||
isScrollEnabled: false,
|
||||
|
|
|
|||
|
|
@ -777,7 +777,7 @@ final class StarsStatisticsScreenComponent: Component {
|
|||
let panelTransition = transition
|
||||
if !panelItems.isEmpty {
|
||||
let panelContainerInset: CGFloat = self.listIsExpanded ? 0.0 : 16.0
|
||||
let panelContainerCornerRadius: CGFloat = self.listIsExpanded ? 0.0 : 11.0
|
||||
let panelContainerCornerRadius: CGFloat = self.listIsExpanded ? 0.0 : 26.0
|
||||
|
||||
let panelContainerSize = self.panelContainer.update(
|
||||
transition: panelTransition,
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||
transition.setFrame(view: self.topPanelBackgroundView, frame: CGRect(origin: .zero, size: topPanelFrame.size))
|
||||
transition.setFrame(view: self.topPanelMergedBackgroundView, frame: CGRect(origin: .zero, size: topPanelFrame.size))
|
||||
|
||||
transition.setCornerRadius(layer: self.topPanelClippingView.layer, cornerRadius: component.insets.left > 0.0 ? 11.0 : 0.0)
|
||||
transition.setCornerRadius(layer: self.topPanelClippingView.layer, cornerRadius: component.insets.left > 0.0 ? 26.0 : 0.0)
|
||||
|
||||
transition.setFrame(layer: self.panelsBackgroundLayer, frame: CGRect(origin: CGPoint(x: component.insets.left, y: topPanelFrame.maxY), size: CGSize(width: containerWidth, height: availableSize.height - topPanelFrame.maxY)))
|
||||
|
||||
|
|
|
|||
|
|
@ -1134,7 +1134,7 @@ final class StarsTransactionsScreenComponent: Component {
|
|||
|
||||
if !panelItems.isEmpty {
|
||||
let panelContainerInset: CGFloat = self.listIsExpanded ? 0.0 : 16.0
|
||||
let panelContainerCornerRadius: CGFloat = self.listIsExpanded ? 0.0 : 11.0
|
||||
let panelContainerCornerRadius: CGFloat = self.listIsExpanded ? 0.0 : 26.0
|
||||
|
||||
let panelContainerSize = self.panelContainer.update(
|
||||
transition: panelTransition,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ swift_library(
|
|||
"//submodules/Components/ComponentDisplayAdapters",
|
||||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/Components/BalancedTextComponent",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/AppBundle",
|
||||
|
|
@ -29,6 +30,7 @@ swift_library(
|
|||
"//submodules/Components/SheetComponent",
|
||||
"//submodules/UndoUI",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
"//submodules/TelegramUI/Components/ListSectionComponent",
|
||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||
"//submodules/TelegramUI/Components/Stars/StarsImageComponent",
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import StarsImageComponent
|
|||
import ConfettiEffect
|
||||
import PremiumPeerShortcutComponent
|
||||
import StarsBalanceOverlayComponent
|
||||
import GlassBarButtonComponent
|
||||
import TelegramStringFormatting
|
||||
|
||||
private final class SheetContent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
|
@ -68,7 +70,6 @@ private final class SheetContent: CombinedComponent {
|
|||
}
|
||||
|
||||
final class State: ComponentState {
|
||||
var cachedCloseImage: (UIImage, PresentationTheme)?
|
||||
var cachedStarImage: (UIImage, PresentationTheme)?
|
||||
|
||||
private let context: AccountContext
|
||||
|
|
@ -263,7 +264,7 @@ private final class SheetContent: CombinedComponent {
|
|||
static var body: Body {
|
||||
let background = Child(RoundedRectangle.self)
|
||||
let star = Child(StarsImageComponent.self)
|
||||
let closeButton = Child(Button.self)
|
||||
let closeButton = Child(GlassBarButtonComponent.self)
|
||||
let title = Child(Text.self)
|
||||
let peerShortcut = Child(PremiumPeerShortcutComponent.self)
|
||||
|
||||
|
|
@ -337,26 +338,30 @@ private final class SheetContent: CombinedComponent {
|
|||
.position(CGPoint(x: context.availableSize.width / 2.0, y: star.size.height / 2.0 - 27.0))
|
||||
)
|
||||
|
||||
let closeImage: UIImage
|
||||
if let (image, cacheTheme) = state.cachedCloseImage, theme === cacheTheme {
|
||||
closeImage = image
|
||||
} else {
|
||||
closeImage = generateCloseButtonImage(backgroundColor: UIColor(rgb: 0x808084, alpha: 0.1), foregroundColor: theme.actionSheet.inputClearButtonColor)!
|
||||
state.cachedCloseImage = (closeImage, theme)
|
||||
}
|
||||
|
||||
let closeButton = closeButton.update(
|
||||
component: Button(
|
||||
content: AnyComponent(Image(image: closeImage)),
|
||||
action: {
|
||||
component: GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: theme.overallDarkAppearance,
|
||||
state: .generic,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
component.dismiss()
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: 30.0, height: 30.0),
|
||||
availableSize: CGSize(width: 40.0, height: 40.0),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(closeButton
|
||||
.position(CGPoint(x: context.availableSize.width - closeButton.size.width, y: 28.0))
|
||||
.position(CGPoint(x: 16.0 + closeButton.size.width / 2.0, y: 16.0 + closeButton.size.height / 2.0))
|
||||
)
|
||||
|
||||
|
||||
let constrainedTitleWidth = context.availableSize.width - 16.0 * 2.0
|
||||
|
||||
|
|
@ -501,13 +506,15 @@ private final class SheetContent: CombinedComponent {
|
|||
availableSize: context.availableSize,
|
||||
transition: .immediate
|
||||
)
|
||||
|
||||
let smallLabelFont = Font.regular(11.0)
|
||||
let labelFont = Font.semibold(14.0)
|
||||
let formattedBalance = formatStarsAmountText(state.balance ?? StarsAmount.zero, dateTimeFormat: environment.dateTimeFormat)
|
||||
let balanceText = tonAmountAttributedString(formattedBalance, integralFont: labelFont, fractionalFont: smallLabelFont, color: textColor, decimalSeparator: environment.dateTimeFormat.decimalSeparator)
|
||||
|
||||
let balanceValue = balanceValue.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: presentationStringsFormattedNumber(state.balance ?? StarsAmount.zero, environment.dateTimeFormat.groupingSeparator),
|
||||
font: Font.semibold(16.0),
|
||||
textColor: textColor
|
||||
)),
|
||||
text: .plain(balanceText),
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: context.availableSize,
|
||||
|
|
@ -519,15 +526,15 @@ private final class SheetContent: CombinedComponent {
|
|||
transition: .immediate
|
||||
)
|
||||
|
||||
let topBalanceOriginY = 11.0
|
||||
let topBalanceOriginY = 19.0
|
||||
context.add(balanceTitle
|
||||
.position(CGPoint(x: 16.0 + environment.safeInsets.left + balanceTitle.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height / 2.0))
|
||||
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.left - balanceTitle.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height / 2.0))
|
||||
)
|
||||
context.add(balanceIcon
|
||||
.position(CGPoint(x: 16.0 + environment.safeInsets.left + balanceIcon.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0 + 1.0 + UIScreenPixel))
|
||||
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.left - balanceIcon.size.width / 2.0 - balanceValue.size.width - 3.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0 + 1.0 + UIScreenPixel))
|
||||
)
|
||||
context.add(balanceValue
|
||||
.position(CGPoint(x: 16.0 + environment.safeInsets.left + balanceIcon.size.width + 3.0 + balanceValue.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0 + 2.0 - UIScreenPixel))
|
||||
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.left - balanceValue.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0))
|
||||
)
|
||||
|
||||
if state.cachedStarImage == nil || state.cachedStarImage?.1 !== theme {
|
||||
|
|
@ -557,13 +564,15 @@ private final class SheetContent: CombinedComponent {
|
|||
let botTitle = state.botPeer?.compactDisplayTitle ?? ""
|
||||
let invoice = component.invoice
|
||||
let isMedia = !component.extendedMedia.isEmpty
|
||||
|
||||
let buttonSideInset: CGFloat = 30.0
|
||||
let button = button.update(
|
||||
component: ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
style: .glass,
|
||||
color: theme.list.itemCheckColors.fillColor,
|
||||
foreground: theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9),
|
||||
cornerRadius: 10.0
|
||||
pressedColor: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9)
|
||||
),
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable(0),
|
||||
|
|
@ -650,7 +659,7 @@ private final class SheetContent: CombinedComponent {
|
|||
})
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - 16.0 * 2.0, height: 50),
|
||||
availableSize: CGSize(width: context.availableSize.width - buttonSideInset * 2.0, height: 52),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(button
|
||||
|
|
@ -703,7 +712,11 @@ private final class SheetContent: CombinedComponent {
|
|||
)
|
||||
contentSize.height += info.size.height
|
||||
|
||||
contentSize.height += 48.0
|
||||
var bottomInset: CGFloat = environment.safeInsets.bottom
|
||||
if bottomInset < 5.0 {
|
||||
bottomInset = 8.0
|
||||
}
|
||||
contentSize.height += 4.0 + bottomInset
|
||||
|
||||
return contentSize
|
||||
}
|
||||
|
|
@ -779,6 +792,7 @@ private final class StarsTransferSheetComponent: CombinedComponent {
|
|||
})
|
||||
}
|
||||
)),
|
||||
style: .glass,
|
||||
backgroundColor: .color(environment.theme.list.modalBlocksBackgroundColor),
|
||||
followContentSizeChanges: true,
|
||||
clipsContent: true,
|
||||
|
|
@ -886,24 +900,3 @@ public final class StarsTransferScreen: ViewControllerComponentContainer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func generateCloseButtonImage(backgroundColor: UIColor, foregroundColor: UIColor) -> UIImage? {
|
||||
return generateImage(CGSize(width: 30.0, height: 30.0), contextGenerator: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
context.setFillColor(backgroundColor.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
context.setLineWidth(2.0)
|
||||
context.setLineCap(.round)
|
||||
context.setStrokeColor(foregroundColor.cgColor)
|
||||
|
||||
context.move(to: CGPoint(x: 10.0, y: 10.0))
|
||||
context.addLine(to: CGPoint(x: 20.0, y: 20.0))
|
||||
context.strokePath()
|
||||
|
||||
context.move(to: CGPoint(x: 20.0, y: 10.0))
|
||||
context.addLine(to: CGPoint(x: 10.0, y: 20.0))
|
||||
context.strokePath()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ import MediaEditorScreen
|
|||
import BusinessIntroSetupScreen
|
||||
import TelegramNotices
|
||||
import BotSettingsScreen
|
||||
import Camera
|
||||
import CameraScreen
|
||||
import BirthdayPickerScreen
|
||||
import StarsTransactionsScreen
|
||||
|
|
@ -3647,6 +3648,57 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
return editorController
|
||||
}
|
||||
|
||||
public func makeCameraScreen(context: AccountContext, mode: CameraScreenMode, cameraHolder: Any?, transitionIn: CameraScreenTransitionIn?, transitionOut: @escaping (Bool) -> CameraScreenTransitionOut?, completion: @escaping (Any, @escaping () -> Void) -> Void, transitionedOut: (() -> Void)?) -> ViewController {
|
||||
let mappedTransitionIn = transitionIn.flatMap {
|
||||
if let sourceView = $0.sourceView {
|
||||
return CameraScreenImpl.TransitionIn(
|
||||
sourceView: sourceView,
|
||||
sourceRect: $0.sourceRect,
|
||||
sourceCornerRadius: $0.sourceCornerRadius,
|
||||
useFillAnimation: $0.useFillAnimation
|
||||
)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
let mappedMode: CameraScreenImpl.Mode
|
||||
switch mode {
|
||||
case .sticker:
|
||||
mappedMode = .sticker
|
||||
case .avatar:
|
||||
mappedMode = .avatar
|
||||
case .story:
|
||||
mappedMode = .story
|
||||
}
|
||||
let controller = CameraScreenImpl(
|
||||
context: context,
|
||||
mode: mappedMode,
|
||||
holder: cameraHolder as? CameraHolder,
|
||||
transitionIn: mappedTransitionIn,
|
||||
transitionOut: { value in
|
||||
return transitionOut(value).flatMap {
|
||||
if let destinationView = $0.destinationView {
|
||||
return CameraScreenImpl.TransitionOut(
|
||||
destinationView: destinationView,
|
||||
destinationRect: $0.destinationRect,
|
||||
destinationCornerRadius: $0.destinationCornerRadius,
|
||||
completion: $0.completion
|
||||
)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
},
|
||||
completion: { result, _, _, commit in
|
||||
completion(result, commit)
|
||||
}
|
||||
)
|
||||
if let transitionedOut {
|
||||
controller.transitionedOut = transitionedOut
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
public func makeMediaPickerScreen(context: AccountContext, hasSearch: Bool, completion: @escaping (Any) -> Void) -> ViewController {
|
||||
return mediaPickerController(context: context, hasSearch: hasSearch, completion: completion)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue