Merge commit '3f9f29b7fb5b4f3dbe73800b32aafa9d4b88d3f9'

# Conflicts:
#	submodules/ChatSendMessageActionUI/BUILD
#	submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetControllerNode.swift
This commit is contained in:
Ali 2022-07-24 23:33:13 +02:00
commit 2a5523b266
21 changed files with 379 additions and 193 deletions

View File

@ -810,9 +810,9 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
} }
} }
let openNewCard: () -> Void = { [weak self] in let openNewCard: (String?) -> Void = { [weak self] customUrl in
if let strongSelf = self, let paymentForm = strongSelf.paymentFormValue { if let strongSelf = self, let paymentForm = strongSelf.paymentFormValue {
if let nativeProvider = paymentForm.nativeProvider, nativeProvider.name == "stripe" { if customUrl == nil, let nativeProvider = paymentForm.nativeProvider, nativeProvider.name == "stripe" {
guard let paramsData = nativeProvider.params.data(using: .utf8) else { guard let paramsData = nativeProvider.params.data(using: .utf8) else {
return return
} }
@ -891,7 +891,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
controller?.dismiss() controller?.dismiss()
} }
strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
} else if let nativeProvider = paymentForm.nativeProvider, nativeProvider.name == "smartglocal" { } else if customUrl == nil, let nativeProvider = paymentForm.nativeProvider, nativeProvider.name == "smartglocal" {
guard let paramsData = nativeProvider.params.data(using: .utf8) else { guard let paramsData = nativeProvider.params.data(using: .utf8) else {
return return
} }
@ -961,7 +961,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
} else { } else {
var dismissImpl: (() -> Void)? var dismissImpl: (() -> Void)?
let controller = BotCheckoutWebInteractionController(context: context, url: paymentForm.url, intent: .addPaymentMethod({ [weak self] token in let controller = BotCheckoutWebInteractionController(context: context, url: customUrl ?? paymentForm.url, intent: .addPaymentMethod({ [weak self] token in
dismissImpl?() dismissImpl?()
guard let strongSelf = self else { guard let strongSelf = self else {
@ -1060,12 +1060,14 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
strongSelf.controller?.view.endEditing(true) strongSelf.controller?.view.endEditing(true)
let methods = availablePaymentMethods(form: paymentForm, current: strongSelf.currentPaymentMethod) let methods = availablePaymentMethods(form: paymentForm, current: strongSelf.currentPaymentMethod)
if methods.isEmpty { if methods.isEmpty {
openNewCard() openNewCard(nil)
} else { } else {
strongSelf.present(BotCheckoutPaymentMethodSheetController(context: strongSelf.context, currentMethod: strongSelf.currentPaymentMethod, methods: methods, applyValue: { method in strongSelf.present(BotCheckoutPaymentMethodSheetController(context: strongSelf.context, currentMethod: strongSelf.currentPaymentMethod, methods: methods, applyValue: { method in
applyPaymentMethod(method) applyPaymentMethod(method)
}, newCard: { }, newCard: {
openNewCard() openNewCard(nil)
}, otherMethod: { url in
openNewCard(url)
}), ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) }), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
} }
} }

View File

@ -39,7 +39,7 @@ enum BotCheckoutPaymentMethod: Equatable {
final class BotCheckoutPaymentMethodSheetController: ActionSheetController { final class BotCheckoutPaymentMethodSheetController: ActionSheetController {
private var presentationDisposable: Disposable? private var presentationDisposable: Disposable?
init(context: AccountContext, currentMethod: BotCheckoutPaymentMethod?, methods: [BotCheckoutPaymentMethod], applyValue: @escaping (BotCheckoutPaymentMethod) -> Void, newCard: @escaping () -> Void) { init(context: AccountContext, currentMethod: BotCheckoutPaymentMethod?, methods: [BotCheckoutPaymentMethod], applyValue: @escaping (BotCheckoutPaymentMethod) -> Void, newCard: @escaping () -> Void, otherMethod: @escaping (String) -> Void) {
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let strings = presentationData.strings let strings = presentationData.strings
@ -82,7 +82,11 @@ final class BotCheckoutPaymentMethodSheetController: ActionSheetController {
value = nil value = nil
} }
items.append(BotCheckoutPaymentMethodItem(title: title, icon: icon, value: value, action: { [weak self] _ in items.append(BotCheckoutPaymentMethodItem(title: title, icon: icon, value: value, action: { [weak self] _ in
if case let .other(method) = method {
otherMethod(method.url)
} else {
applyValue(method) applyValue(method)
}
self?.dismissAnimated() self?.dismissAnimated()
})) }))
} }

View File

@ -20,7 +20,7 @@ swift_library(
"//submodules/ContextUI:ContextUI", "//submodules/ContextUI:ContextUI",
"//submodules/AppBundle:AppBundle", "//submodules/AppBundle:AppBundle",
"//submodules/TextFormat:TextFormat", "//submodules/TextFormat:TextFormat",
"//submodules/TelegramUI/Components/TextNodeWithEntities:TextNodeWithEntities", "//submodules/TelegramUI/Components/EmojiTextAttachmentView:EmojiTextAttachmentView",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -57,8 +57,10 @@ public final class ChatSendMessageActionSheetController: ViewController {
|> deliverOnMainQueue).start(next: { [weak self] presentationData in |> deliverOnMainQueue).start(next: { [weak self] presentationData in
if let strongSelf = self { if let strongSelf = self {
strongSelf.presentationData = presentationData strongSelf.presentationData = presentationData
if strongSelf.isNodeLoaded {
strongSelf.controllerNode.updatePresentationData(presentationData) strongSelf.controllerNode.updatePresentationData(presentationData)
} }
}
}) })
self.statusBar.statusBarStyle = .Hide self.statusBar.statusBarStyle = .Hide
@ -93,7 +95,7 @@ public final class ChatSendMessageActionSheetController: ViewController {
hasEntityKeyboard = true hasEntityKeyboard = true
} }
self.displayNode = ChatSendMessageActionSheetControllerNode(context: self.context, presentationData: self.presentationData, reminders: reminders, gesture: gesture, sourceSendButton: self.sourceSendButton, textInputNode: self.textInputNode, attachment: self.attachment, forwardedCount: forwardedCount, hasEntityKeyboard: hasEntityKeyboard, send: { [weak self] in self.displayNode = ChatSendMessageActionSheetControllerNode(context: self.context, presentationData: self.presentationData, reminders: reminders, gesture: gesture, sourceSendButton: self.sourceSendButton, textInputNode: self.textInputNode, attachment: self.attachment, forwardedCount: forwardedCount, hasEntityKeyboard: hasEntityKeyboard, emojiViewProvider: self.emojiViewProvider, send: { [weak self] in
self?.sendMessage(false) self?.sendMessage(false)
self?.dismiss(cancel: false) self?.dismiss(cancel: false)
}, sendSilently: { [weak self] in }, sendSilently: { [weak self] in

View File

@ -10,7 +10,7 @@ import AccountContext
import AppBundle import AppBundle
import ContextUI import ContextUI
import TextFormat import TextFormat
import TextNodeWithEntities import EmojiTextAttachmentView
private let leftInset: CGFloat = 16.0 private let leftInset: CGFloat = 16.0
private let rightInset: CGFloat = 16.0 private let rightInset: CGFloat = 16.0
@ -178,6 +178,9 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
private let toMessageTextNode: EditableTextNode private let toMessageTextNode: EditableTextNode
private let scrollNode: ASScrollNode private let scrollNode: ASScrollNode
private var fromCustomEmojiContainerView: CustomEmojiContainerView?
private var toCustomEmojiContainerView: CustomEmojiContainerView?
private var validLayout: ContainerViewLayout? private var validLayout: ContainerViewLayout?
private var sendButtonFrame: CGRect { private var sendButtonFrame: CGRect {
@ -186,7 +189,9 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
private var animateInputField = false private var animateInputField = false
init(context: AccountContext, presentationData: PresentationData, reminders: Bool, gesture: ContextGesture, sourceSendButton: ASDisplayNode, textInputNode: EditableTextNode, attachment: Bool, forwardedCount: Int?, hasEntityKeyboard: Bool, send: (() -> Void)?, sendSilently: (() -> Void)?, schedule: (() -> Void)?, cancel: (() -> Void)?) { private var emojiViewProvider: ((ChatTextInputTextCustomEmojiAttribute) -> UIView)?
init(context: AccountContext, presentationData: PresentationData, reminders: Bool, gesture: ContextGesture, sourceSendButton: ASDisplayNode, textInputNode: EditableTextNode, attachment: Bool, forwardedCount: Int?, hasEntityKeyboard: Bool, emojiViewProvider: ((ChatTextInputTextCustomEmojiAttribute) -> UIView)?, send: (() -> Void)?, sendSilently: (() -> Void)?, schedule: (() -> Void)?, cancel: (() -> Void)?) {
self.context = context self.context = context
self.presentationData = presentationData self.presentationData = presentationData
self.sourceSendButton = sourceSendButton self.sourceSendButton = sourceSendButton
@ -195,6 +200,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
self.attachment = attachment self.attachment = attachment
self.forwardedCount = forwardedCount self.forwardedCount = forwardedCount
self.hasEntityKeyboard = hasEntityKeyboard self.hasEntityKeyboard = hasEntityKeyboard
self.emojiViewProvider = emojiViewProvider
self.send = send self.send = send
self.cancel = cancel self.cancel = cancel
@ -352,6 +358,64 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
} }
} }
func updateTextContents() {
var customEmojiRects: [(CGRect, ChatTextInputTextCustomEmojiAttribute)] = []
let textInputNode = self.fromMessageTextNode
if let attributedText = textInputNode.attributedText {
let beginning = textInputNode.textView.beginningOfDocument
attributedText.enumerateAttributes(in: NSMakeRange(0, attributedText.length), options: [], using: { attributes, range, _ in
if let value = attributes[ChatTextInputAttributes.customEmoji] as? ChatTextInputTextCustomEmojiAttribute {
if let start = textInputNode.textView.position(from: beginning, offset: range.location), let end = textInputNode.textView.position(from: start, offset: range.length), let textRange = textInputNode.textView.textRange(from: start, to: end) {
let textRects = textInputNode.textView.selectionRects(for: textRange)
for textRect in textRects {
customEmojiRects.append((textRect.rect, value))
break
}
}
}
})
}
self.updateTextContents(rects: customEmojiRects, textInputNode: self.fromMessageTextNode, from: true)
self.updateTextContents(rects: customEmojiRects, textInputNode: self.toMessageTextNode, from: false)
}
func updateTextContents(rects: [(CGRect, ChatTextInputTextCustomEmojiAttribute)], textInputNode: EditableTextNode, from: Bool) {
if !rects.isEmpty {
let customEmojiContainerView: CustomEmojiContainerView
if from, let current = self.fromCustomEmojiContainerView {
customEmojiContainerView = current
} else if !from, let current = self.toCustomEmojiContainerView {
customEmojiContainerView = current
} else {
customEmojiContainerView = CustomEmojiContainerView(emojiViewProvider: { [weak self] emoji in
guard let strongSelf = self, let emojiViewProvider = strongSelf.emojiViewProvider else {
return nil
}
return emojiViewProvider(emoji)
})
customEmojiContainerView.isUserInteractionEnabled = false
textInputNode.textView.addSubview(customEmojiContainerView)
if from {
self.fromCustomEmojiContainerView = customEmojiContainerView
} else {
self.toCustomEmojiContainerView = customEmojiContainerView
}
}
customEmojiContainerView.update(emojiRects: rects)
} else {
if from, let customEmojiContainerView = self.fromCustomEmojiContainerView {
customEmojiContainerView.removeFromSuperview()
self.fromCustomEmojiContainerView = nil
} else if !from, let customEmojiContainerView = self.toCustomEmojiContainerView {
customEmojiContainerView.removeFromSuperview()
self.fromCustomEmojiContainerView = nil
}
}
}
func updatePresentationData(_ presentationData: PresentationData) { func updatePresentationData(_ presentationData: PresentationData) {
guard presentationData.theme !== self.presentationData.theme else { guard presentationData.theme !== self.presentationData.theme else {
return return
@ -460,6 +524,10 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
let springDamping: CGFloat = 104.0 let springDamping: CGFloat = 104.0
self.contentContainerNode.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, initialVelocity: 0.0, damping: springDamping) self.contentContainerNode.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, initialVelocity: 0.0, damping: springDamping)
self.contentContainerNode.layer.animateSpring(from: NSValue(cgPoint: contentOffset), to: NSValue(cgPoint: CGPoint()), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, additive: true) self.contentContainerNode.layer.animateSpring(from: NSValue(cgPoint: contentOffset), to: NSValue(cgPoint: CGPoint()), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, additive: true)
Queue.mainQueue().after(0.01, {
self.updateTextContents()
})
} }
func animateOut(cancel: Bool, completion: @escaping () -> Void) { func animateOut(cancel: Bool, completion: @escaping () -> Void) {
@ -693,3 +761,64 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
self.send?() self.send?()
} }
} }
final class CustomEmojiContainerView: UIView {
private let emojiViewProvider: (ChatTextInputTextCustomEmojiAttribute) -> UIView?
private var emojiLayers: [InlineStickerItemLayer.Key: UIView] = [:]
init(emojiViewProvider: @escaping (ChatTextInputTextCustomEmojiAttribute) -> UIView?) {
self.emojiViewProvider = emojiViewProvider
super.init(frame: CGRect())
}
required init(coder: NSCoder) {
preconditionFailure()
}
func update(emojiRects: [(CGRect, ChatTextInputTextCustomEmojiAttribute)]) {
var nextIndexById: [Int64: Int] = [:]
var validKeys = Set<InlineStickerItemLayer.Key>()
for (rect, emoji) in emojiRects {
let index: Int
if let nextIndex = nextIndexById[emoji.fileId] {
index = nextIndex
} else {
index = 0
}
nextIndexById[emoji.fileId] = index + 1
let key = InlineStickerItemLayer.Key(id: emoji.fileId, index: index)
let view: UIView
if let current = self.emojiLayers[key] {
view = current
} else if let newView = self.emojiViewProvider(emoji) {
view = newView
self.addSubview(newView)
self.emojiLayers[key] = view
} else {
continue
}
let size = CGSize(width: 24.0, height: 24.0)
view.frame = CGRect(origin: CGPoint(x: floor(rect.midX - size.width / 2.0), y: floor(rect.midY - size.height / 2.0)), size: size)
validKeys.insert(key)
}
var removeKeys: [InlineStickerItemLayer.Key] = []
for (key, view) in self.emojiLayers {
if !validKeys.contains(key) {
removeKeys.append(key)
view.removeFromSuperview()
}
}
for key in removeKeys {
self.emojiLayers.removeValue(forKey: key)
}
}
}

View File

@ -552,9 +552,9 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate {
} }
itemSize.height = height itemSize.height = height
} else if let fillsRowWithDynamicHeight = item.fillsRowWithDynamicHeight { } else if let fillsRowWithDynamicHeight = item.fillsRowWithDynamicHeight {
let height = fillsRowWithDynamicHeight(gridLayout.size.width) let height = fillsRowWithDynamicHeight(gridLayout.size.width - itemInsets.left - itemInsets.right)
nextItemOrigin.x = initialSpacing + itemInsets.left nextItemOrigin.x = initialSpacing + itemInsets.left
itemSize.width = gridLayout.size.width itemSize.width = gridLayout.size.width - itemInsets.left - itemInsets.right
itemSize.height = height itemSize.height = height
} else if index == 0 { } else if index == 0 {
let itemsInRow = max(1, Int(effectiveWidth) / Int(itemSize.width)) let itemsInRow = max(1, Int(effectiveWidth) / Int(itemSize.width))

View File

@ -122,11 +122,12 @@ private final class HapticFeedbackImpl {
} }
func warning() { func warning() {
if let notificationGenerator = self.notificationGenerator { AudioServicesPlaySystemSound(1102)
notificationGenerator.notificationOccurred(.warning) // if let notificationGenerator = self.notificationGenerator {
} else { // notificationGenerator.notificationOccurred(.warning)
// } else {
} //
// }
} }
@objc dynamic func f() { @objc dynamic func f() {

View File

@ -331,6 +331,7 @@ public class Window1 {
self.hostView = hostView self.hostView = hostView
self.badgeView = UIImageView() self.badgeView = UIImageView()
self.badgeView.image = UIImage(bundleImageName: "Components/AppBadge") self.badgeView.image = UIImage(bundleImageName: "Components/AppBadge")
self.badgeView.isHidden = true
self.systemUserInterfaceStyle = hostView.systemUserInterfaceStyle self.systemUserInterfaceStyle = hostView.systemUserInterfaceStyle
@ -655,7 +656,7 @@ public class Window1 {
} }
} }
private var forceBadgeHidden = false private var forceBadgeHidden = true
public func setForceBadgeHidden(_ hidden: Bool) { public func setForceBadgeHidden(_ hidden: Bool) {
guard hidden != self.forceBadgeHidden else { guard hidden != self.forceBadgeHidden else {
return return

View File

@ -20,7 +20,7 @@ public enum ItemListDisclosureLabelStyle {
case text case text
case detailText case detailText
case coloredText(UIColor) case coloredText(UIColor)
// case textWithIcon(UIColor) case textWithIcon(UIImage)
case multilineDetailText case multilineDetailText
case badge(UIColor) case badge(UIColor)
case color(UIColor) case color(UIColor)
@ -236,7 +236,9 @@ public class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode {
updatedLabelImage = generateFilledCircleImage(diameter: 17.0, color: color) updatedLabelImage = generateFilledCircleImage(diameter: 17.0, color: color)
} }
} }
if case let .image(image, _) = item.labelStyle { if case let .textWithIcon(image) = item.labelStyle {
updatedLabelImage = generateTintedImage(image: image, color: item.presentationData.theme.list.itemSecondaryTextColor)
} else if case let .image(image, _) = item.labelStyle {
updatedLabelImage = image updatedLabelImage = image
} }
@ -474,7 +476,18 @@ public class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode {
} }
strongSelf.labelNode.frame = labelFrame strongSelf.labelNode.frame = labelFrame
if case let .image(_, size) = item.labelStyle { if case .textWithIcon = item.labelStyle {
if let updatedLabelImage = updatedLabelImage {
strongSelf.labelImageNode.image = updatedLabelImage
}
if strongSelf.labelImageNode.supernode == nil {
strongSelf.addSubnode(strongSelf.labelImageNode)
}
if let size = strongSelf.labelImageNode.image?.size {
strongSelf.labelImageNode.frame = CGRect(origin: CGPoint(x: labelFrame.minX - size.width - 5.0, y: floor((layout.contentSize.height - size.height) / 2.0) - 1.0), size: size)
}
} else if case let .image(_, size) = item.labelStyle {
if let updatedLabelImage = updatedLabelImage { if let updatedLabelImage = updatedLabelImage {
strongSelf.labelImageNode.image = updatedLabelImage strongSelf.labelImageNode.image = updatedLabelImage
} }

View File

@ -478,7 +478,7 @@ func deleteAccountDataController(context: AccountContext, mode: DeleteAccountDat
addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_confirmation_cancel") addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_confirmation_cancel")
dismissImpl?() dismissImpl?()
})])) })], actionLayout: .vertical))
} }
} }

View File

@ -83,7 +83,7 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
case voiceCallPrivacy(PresentationTheme, String, String) case voiceCallPrivacy(PresentationTheme, String, String)
case forwardPrivacy(PresentationTheme, String, String) case forwardPrivacy(PresentationTheme, String, String)
case groupPrivacy(PresentationTheme, String, String) case groupPrivacy(PresentationTheme, String, String)
case voiceMessagePrivacy(PresentationTheme, String, String) case voiceMessagePrivacy(PresentationTheme, String, String, Bool)
case selectivePrivacyInfo(PresentationTheme, String) case selectivePrivacyInfo(PresentationTheme, String)
case passcode(PresentationTheme, String, Bool, String) case passcode(PresentationTheme, String, Bool, String)
case twoStepVerification(PresentationTheme, String, String, TwoStepVerificationAccessConfiguration?) case twoStepVerification(PresentationTheme, String, String, TwoStepVerificationAccessConfiguration?)
@ -209,8 +209,8 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
} else { } else {
return false return false
} }
case let .voiceMessagePrivacy(lhsTheme, lhsText, lhsValue): case let .voiceMessagePrivacy(lhsTheme, lhsText, lhsValue, lhsLocked):
if case let .voiceMessagePrivacy(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { if case let .voiceMessagePrivacy(rhsTheme, rhsText, rhsValue, rhsLocked) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsLocked == rhsLocked {
return true return true
} else { } else {
return false return false
@ -300,7 +300,7 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
case let .privacyHeader(_, text): case let .privacyHeader(_, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .blockedPeers(_, text, value): case let .blockedPeers(_, text, value):
return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: "Settings/Menu/Blocked")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: { return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: "Chat/Stickers/Blocked")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: {
arguments.openBlockedUsers() arguments.openBlockedUsers()
}) })
case let .phoneNumberPrivacy(_, text, value): case let .phoneNumberPrivacy(_, text, value):
@ -323,8 +323,8 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: {
arguments.openGroupsPrivacy() arguments.openGroupsPrivacy()
}) })
case let .voiceMessagePrivacy(_, text, value): case let .voiceMessagePrivacy(_, text, value, locked):
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, labelStyle: locked ? .textWithIcon(UIImage(bundleImageName: "Notification/SecretLock")!.precomposed()) : .text, sectionId: self.section, style: .blocks, action: {
arguments.openVoiceMessagePrivacy() arguments.openVoiceMessagePrivacy()
}) })
case let .selectivePrivacyInfo(_, text): case let .selectivePrivacyInfo(_, text):
@ -411,7 +411,7 @@ private func stringForSelectiveSettings(strings: PresentationStrings, settings:
} }
} }
private func privacyAndSecurityControllerEntries(presentationData: PresentationData, state: PrivacyAndSecurityControllerState, privacySettings: AccountPrivacySettings?, accessChallengeData: PostboxAccessChallengeData, blockedPeerCount: Int?, activeWebsitesCount: Int, hasTwoStepAuth: Bool?, twoStepAuthData: TwoStepVerificationAccessConfiguration?, canAutoarchive: Bool) -> [PrivacyAndSecurityEntry] { private func privacyAndSecurityControllerEntries(presentationData: PresentationData, state: PrivacyAndSecurityControllerState, privacySettings: AccountPrivacySettings?, accessChallengeData: PostboxAccessChallengeData, blockedPeerCount: Int?, activeWebsitesCount: Int, hasTwoStepAuth: Bool?, twoStepAuthData: TwoStepVerificationAccessConfiguration?, canAutoarchive: Bool, isPremium: Bool) -> [PrivacyAndSecurityEntry] {
var entries: [PrivacyAndSecurityEntry] = [] var entries: [PrivacyAndSecurityEntry] = []
entries.append(.blockedPeers(presentationData.theme, presentationData.strings.Settings_BlockedUsers, blockedPeerCount == nil ? "" : (blockedPeerCount == 0 ? presentationData.strings.PrivacySettings_BlockedPeersEmpty : "\(blockedPeerCount!)"))) entries.append(.blockedPeers(presentationData.theme, presentationData.strings.Settings_BlockedUsers, blockedPeerCount == nil ? "" : (blockedPeerCount == 0 ? presentationData.strings.PrivacySettings_BlockedPeersEmpty : "\(blockedPeerCount!)")))
@ -449,7 +449,7 @@ private func privacyAndSecurityControllerEntries(presentationData: PresentationD
entries.append(.lastSeenPrivacy(presentationData.theme, presentationData.strings.PrivacySettings_LastSeen, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.presence))) entries.append(.lastSeenPrivacy(presentationData.theme, presentationData.strings.PrivacySettings_LastSeen, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.presence)))
entries.append(.profilePhotoPrivacy(presentationData.theme, presentationData.strings.Privacy_ProfilePhoto, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.profilePhoto))) entries.append(.profilePhotoPrivacy(presentationData.theme, presentationData.strings.Privacy_ProfilePhoto, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.profilePhoto)))
entries.append(.voiceCallPrivacy(presentationData.theme, presentationData.strings.Privacy_Calls, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.voiceCalls))) entries.append(.voiceCallPrivacy(presentationData.theme, presentationData.strings.Privacy_Calls, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.voiceCalls)))
entries.append(.voiceMessagePrivacy(presentationData.theme, presentationData.strings.Privacy_VoiceMessages, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.voiceMessages))) entries.append(.voiceMessagePrivacy(presentationData.theme, presentationData.strings.Privacy_VoiceMessages, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.voiceMessages), !isPremium))
entries.append(.forwardPrivacy(presentationData.theme, presentationData.strings.Privacy_Forwards, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.forwards))) entries.append(.forwardPrivacy(presentationData.theme, presentationData.strings.Privacy_Forwards, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.forwards)))
entries.append(.groupPrivacy(presentationData.theme, presentationData.strings.Privacy_GroupsAndChannels, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.groupInvitations))) entries.append(.groupPrivacy(presentationData.theme, presentationData.strings.Privacy_GroupsAndChannels, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.groupInvitations)))
@ -458,7 +458,7 @@ private func privacyAndSecurityControllerEntries(presentationData: PresentationD
entries.append(.lastSeenPrivacy(presentationData.theme, presentationData.strings.PrivacySettings_LastSeen, presentationData.strings.Channel_NotificationLoading)) entries.append(.lastSeenPrivacy(presentationData.theme, presentationData.strings.PrivacySettings_LastSeen, presentationData.strings.Channel_NotificationLoading))
entries.append(.profilePhotoPrivacy(presentationData.theme, presentationData.strings.Privacy_ProfilePhoto, presentationData.strings.Channel_NotificationLoading)) entries.append(.profilePhotoPrivacy(presentationData.theme, presentationData.strings.Privacy_ProfilePhoto, presentationData.strings.Channel_NotificationLoading))
entries.append(.voiceCallPrivacy(presentationData.theme, presentationData.strings.Privacy_Calls, presentationData.strings.Channel_NotificationLoading)) entries.append(.voiceCallPrivacy(presentationData.theme, presentationData.strings.Privacy_Calls, presentationData.strings.Channel_NotificationLoading))
entries.append(.voiceMessagePrivacy(presentationData.theme, presentationData.strings.Privacy_VoiceMessages, presentationData.strings.Channel_NotificationLoading)) entries.append(.voiceMessagePrivacy(presentationData.theme, presentationData.strings.Privacy_VoiceMessages, presentationData.strings.Channel_NotificationLoading, !isPremium))
entries.append(.forwardPrivacy(presentationData.theme, presentationData.strings.Privacy_Forwards, presentationData.strings.Channel_NotificationLoading)) entries.append(.forwardPrivacy(presentationData.theme, presentationData.strings.Privacy_Forwards, presentationData.strings.Channel_NotificationLoading))
entries.append(.groupPrivacy(presentationData.theme, presentationData.strings.Privacy_GroupsAndChannels, presentationData.strings.Channel_NotificationLoading)) entries.append(.groupPrivacy(presentationData.theme, presentationData.strings.Privacy_GroupsAndChannels, presentationData.strings.Channel_NotificationLoading))
entries.append(.selectivePrivacyInfo(presentationData.theme, presentationData.strings.PrivacyLastSeenSettings_GroupsAndChannelsHelp)) entries.append(.selectivePrivacyInfo(presentationData.theme, presentationData.strings.PrivacyLastSeenSettings_GroupsAndChannelsHelp))
@ -944,9 +944,10 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
webSessionsContext.state, webSessionsContext.state,
context.sharedContext.accountManager.accessChallengeData(), context.sharedContext.accountManager.accessChallengeData(),
combineLatest(twoStepAuth.get(), twoStepAuthDataValue.get()), combineLatest(twoStepAuth.get(), twoStepAuthDataValue.get()),
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App()) context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App()),
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
) )
|> map { presentationData, state, privacySettings, noticeView, sharedData, recentPeers, blockedPeersState, activeWebsitesState, accessChallengeData, twoStepAuth, appConfiguration -> (ItemListControllerState, (ItemListNodeState, Any)) in |> map { presentationData, state, privacySettings, noticeView, sharedData, recentPeers, blockedPeersState, activeWebsitesState, accessChallengeData, twoStepAuth, appConfiguration, accountPeer -> (ItemListControllerState, (ItemListNodeState, Any)) in
var canAutoarchive = false var canAutoarchive = false
if let data = appConfiguration.data, let hasAutoarchive = data["autoarchive_setting_available"] as? Bool { if let data = appConfiguration.data, let hasAutoarchive = data["autoarchive_setting_available"] as? Bool {
canAutoarchive = hasAutoarchive canAutoarchive = hasAutoarchive
@ -959,7 +960,9 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.PrivacySettings_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false) let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.PrivacySettings_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: privacyAndSecurityControllerEntries(presentationData: presentationData, state: state, privacySettings: privacySettings, accessChallengeData: accessChallengeData.data, blockedPeerCount: blockedPeersState.totalCount, activeWebsitesCount: activeWebsitesState.sessions.count, hasTwoStepAuth: twoStepAuth.0, twoStepAuthData: twoStepAuth.1, canAutoarchive: canAutoarchive), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false) let isPremium = accountPeer?.isPremium ?? false
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: privacyAndSecurityControllerEntries(presentationData: presentationData, state: state, privacySettings: privacySettings, accessChallengeData: accessChallengeData.data, blockedPeerCount: blockedPeersState.totalCount, activeWebsitesCount: activeWebsitesState.sessions.count, hasTwoStepAuth: twoStepAuth.0, twoStepAuthData: twoStepAuth.1, canAutoarchive: canAutoarchive, isPremium: isPremium), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false)
return (controllerState, (listState, arguments)) return (controllerState, (listState, arguments))
} }

View File

@ -103,16 +103,14 @@ final class StickerPackEmojisItem: GridItem {
func node(layout: GridNodeLayout, synchronousLoad: Bool) -> GridItemNode { func node(layout: GridNodeLayout, synchronousLoad: Bool) -> GridItemNode {
let node = StickerPackEmojisItemNode() let node = StickerPackEmojisItemNode()
node.setup(item: self)
return node return node
} }
func update(node: GridItemNode) { func update(node: GridItemNode) {
guard let node = node as? StickerPackEmojisItemNode else { guard let _ = node as? StickerPackEmojisItemNode else {
assertionFailure() assertionFailure()
return return
} }
node.setup(item: self)
} }
} }
@ -173,7 +171,7 @@ final class StickerPackEmojisItemNode: GridItemNode {
let shimmerHostView = PortalSourceView() let shimmerHostView = PortalSourceView()
shimmerHostView.alpha = 0.0 shimmerHostView.alpha = 0.0
shimmerHostView.frame = CGRect(origin: CGPoint(), size: self.frame.size) shimmerHostView.frame = CGRect(origin: CGPoint(), size: self.size)
self.view.addSubview(shimmerHostView) self.view.addSubview(shimmerHostView)
self.shimmerHostView = shimmerHostView self.shimmerHostView = shimmerHostView
@ -195,9 +193,13 @@ final class StickerPackEmojisItemNode: GridItemNode {
self.boundsChangeTrackerLayer = boundsChangeTrackerLayer self.boundsChangeTrackerLayer = boundsChangeTrackerLayer
} }
private var setupTimestamp: Double? private var size = CGSize()
func setup(item: StickerPackEmojisItem) { override func updateLayout(item: GridItem, size: CGSize, isVisible: Bool, synchronousLoads: Bool) {
guard let item = item as? StickerPackEmojisItem else {
return
}
self.item = item self.item = item
self.size = size
if let title = item.title { if let title = item.title {
let isInstalled = item.isInstalled ?? false let isInstalled = item.isInstalled ?? false
@ -219,7 +221,7 @@ final class StickerPackEmojisItemNode: GridItemNode {
} }
func updateVisibleItems(attemptSynchronousLoads: Bool, transition: ContainedViewLayoutTransition) { func updateVisibleItems(attemptSynchronousLoads: Bool, transition: ContainedViewLayoutTransition) {
guard let item = self.item, !self.frame.width.isZero else { guard let item = self.item, !self.size.width.isZero else {
return return
} }
@ -231,10 +233,10 @@ final class StickerPackEmojisItemNode: GridItemNode {
var validIds = Set<EmojiPagerContentComponent.View.ItemLayer.Key>() var validIds = Set<EmojiPagerContentComponent.View.ItemLayer.Key>()
let itemLayout: ItemLayout let itemLayout: ItemLayout
if let current = self.itemLayout, current.width == self.frame.width && current.itemsCount == items.count && current.hasTitle == (item.title != nil) { if let current = self.itemLayout, current.width == self.size.width && current.itemsCount == items.count && current.hasTitle == (item.title != nil) {
itemLayout = current itemLayout = current
} else { } else {
itemLayout = ItemLayout(width: self.frame.width, itemsCount: items.count, hasTitle: item.title != nil) itemLayout = ItemLayout(width: self.size.width, itemsCount: items.count, hasTitle: item.title != nil)
self.itemLayout = itemLayout self.itemLayout = itemLayout
} }
@ -368,20 +370,20 @@ final class StickerPackEmojisItemNode: GridItemNode {
super.layout() super.layout()
if let _ = self.item { if let _ = self.item {
var buttonSize = self.buttonNode.calculateSizeThatFits(self.frame.size) var buttonSize = self.buttonNode.calculateSizeThatFits(self.size)
buttonSize.width += 24.0 buttonSize.width += 24.0
buttonSize.height = 28.0 buttonSize.height = 28.0
let titleSize = self.titleNode.updateLayout(CGSize(width: self.frame.width - 60.0, height: self.frame.height)) let titleSize = self.titleNode.updateLayout(CGSize(width: self.size.width - 60.0, height: self.size.height))
let subtitleSize = self.subtitleNode.updateLayout(CGSize(width: self.frame.width - 60.0, height: self.frame.height)) let subtitleSize = self.subtitleNode.updateLayout(CGSize(width: self.size.width - 60.0, height: self.size.height))
self.titleNode.frame = CGRect(origin: CGPoint(x: 16.0, y: 10.0), size: titleSize) self.titleNode.frame = CGRect(origin: CGPoint(x: 16.0, y: 10.0), size: titleSize)
self.subtitleNode.frame = CGRect(origin: CGPoint(x: 16.0, y: 33.0), size: subtitleSize) self.subtitleNode.frame = CGRect(origin: CGPoint(x: 16.0, y: 33.0), size: subtitleSize)
self.buttonNode.frame = CGRect(origin: CGPoint(x: self.frame.width - buttonSize.width - 16.0, y: 17.0), size: buttonSize) self.buttonNode.frame = CGRect(origin: CGPoint(x: self.size.width - buttonSize.width - 16.0, y: 17.0), size: buttonSize)
} }
self.shimmerHostView?.frame = CGRect(origin: CGPoint(), size: self.frame.size) self.shimmerHostView?.frame = CGRect(origin: CGPoint(), size: self.size)
self.updateVisibleItems(attemptSynchronousLoads: false, transition: .immediate) self.updateVisibleItems(attemptSynchronousLoads: false, transition: .immediate)
} }

View File

@ -911,14 +911,6 @@ private final class StickerPackContainer: ASDisplayNode {
} }
if updateLayout, let (layout, _, _, _) = self.validLayout { if updateLayout, let (layout, _, _, _) = self.validLayout {
let cancelSize = self.cancelButtonNode.measure(CGSize(width: layout.size.width, height: .greatestFiniteMagnitude))
self.cancelButtonNode.frame = CGRect(origin: CGPoint(x: layout.safeInsets.left + 16.0, y: 18.0), size: cancelSize)
let titleSize = self.titleNode.updateLayout(CGSize(width: layout.size.width - cancelSize.width * 2.0 - 40.0, height: .greatestFiniteMagnitude))
self.titleNode.frame = CGRect(origin: CGPoint(x: floor((-titleSize.width) / 2.0), y: floor((-titleSize.height) / 2.0)), size: titleSize)
self.moreButtonNode.frame = CGRect(origin: CGPoint(x: layout.size.width - layout.safeInsets.right - 46.0, y: 5.0), size: CGSize(width: 44.0, height: 44.0))
self.updateLayout(layout: layout, transition: .immediate) self.updateLayout(layout: layout, transition: .immediate)
} }
@ -1050,6 +1042,14 @@ private final class StickerPackContainer: ASDisplayNode {
titlePlaceholderNode.updateAbsoluteRect(titlePlaceholderNode.frame.offsetBy(dx: self.titleContainer.frame.minX, dy: self.titleContainer.frame.minY - gridInsets.top - gridFrame.minY), within: gridFrame.size) titlePlaceholderNode.updateAbsoluteRect(titlePlaceholderNode.frame.offsetBy(dx: self.titleContainer.frame.minX, dy: self.titleContainer.frame.minY - gridInsets.top - gridFrame.minY), within: gridFrame.size)
} }
let cancelSize = self.cancelButtonNode.measure(CGSize(width: layout.size.width, height: .greatestFiniteMagnitude))
self.cancelButtonNode.frame = CGRect(origin: CGPoint(x: layout.safeInsets.left + 16.0, y: 18.0), size: cancelSize)
let titleSize = self.titleNode.updateLayout(CGSize(width: layout.size.width - cancelSize.width * 2.0 - 40.0, height: .greatestFiniteMagnitude))
self.titleNode.frame = CGRect(origin: CGPoint(x: floor((-titleSize.width) / 2.0), y: floor((-titleSize.height) / 2.0)), size: titleSize)
self.moreButtonNode.frame = CGRect(origin: CGPoint(x: layout.size.width - layout.safeInsets.right - 46.0, y: 5.0), size: CGSize(width: 44.0, height: 44.0))
if firstTime { if firstTime {
while !self.enqueuedTransactions.isEmpty { while !self.enqueuedTransactions.isEmpty {
self.dequeueTransaction() self.dequeueTransaction()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3617,7 +3617,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}, didDismiss: { [weak self] in }, didDismiss: { [weak self] in
if let strongSelf = self { if let strongSelf = self {
let isFocused = strongSelf.chatDisplayNode.textInputPanelNode?.isFocused ?? false let isFocused = strongSelf.chatDisplayNode.textInputPanelNode?.isFocused ?? false
strongSelf.chatDisplayNode.insertSubnode(strongSelf.chatDisplayNode.inputPanelContainerNode, aboveSubnode: strongSelf.chatDisplayNode.historyNodeContainer) strongSelf.chatDisplayNode.insertSubnode(strongSelf.chatDisplayNode.inputPanelContainerNode, aboveSubnode: strongSelf.chatDisplayNode.inputContextPanelContainer)
if isFocused { if isFocused {
strongSelf.chatDisplayNode.textInputPanelNode?.ensureFocused() strongSelf.chatDisplayNode.textInputPanelNode?.ensureFocused()
} }

View File

@ -125,7 +125,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
private var secondaryInputPanelNode: ChatInputPanelNode? private var secondaryInputPanelNode: ChatInputPanelNode?
private(set) var accessoryPanelNode: AccessoryPanelNode? private(set) var accessoryPanelNode: AccessoryPanelNode?
private var inputContextPanelNode: ChatInputContextPanelNode? private var inputContextPanelNode: ChatInputContextPanelNode?
private let inputContextPanelContainer: ChatControllerTitlePanelNodeContainer let inputContextPanelContainer: ChatControllerTitlePanelNodeContainer
private let inputContextOverTextPanelContainer: ChatControllerTitlePanelNodeContainer private let inputContextOverTextPanelContainer: ChatControllerTitlePanelNodeContainer
private var overlayContextPanelNode: ChatInputContextPanelNode? private var overlayContextPanelNode: ChatInputContextPanelNode?

View File

@ -1067,7 +1067,14 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
} }
if isPremiumLocked { if isPremiumLocked {
let controller = PremiumIntroScreen(context: context, source: .stickers) var replaceImpl: ((ViewController) -> Void)?
let controller = PremiumDemoScreen(context: context, subject: .animatedEmoji, action: {
let controller = PremiumIntroScreen(context: context, source: .animatedEmoji)
replaceImpl?(controller)
})
replaceImpl = { [weak controller] c in
controller?.replace(with: c)
}
controllerInteraction.navigationController()?.pushViewController(controller) controllerInteraction.navigationController()?.pushViewController(controller)
return return

View File

@ -60,7 +60,7 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
self.addSubnode(self.iconImageNode) self.addSubnode(self.iconImageNode)
switch item { switch item {
case .input, .botInput: case .input, .botInput, .silentPost:
self.iconImageNode.isHidden = true self.iconImageNode.isHidden = true
self.animationView = ComponentView<Empty>() self.animationView = ComponentView<Empty>()
default: default:
@ -175,10 +175,29 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
self.iconImageNode.frame = imageFrame self.iconImageNode.frame = imageFrame
if let animationView = self.animationView { if let animationView = self.animationView {
let iconSize: CGSize = CGSize(width: 32.0, height: 32.0) let width = AccessoryItemIconButtonNode.calculateWidth(item: item, image: image, text: "", strings: self.strings)
let iconFrame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0) - bottomInset), size: iconSize) let iconSize = CGSize(width: width, height: width)
let animationFrame = iconFrame.insetBy(dx: -4.0, dy: -4.0)
let animationFrame = CGRect(origin: CGPoint(x: floor((size.width - width) / 2.0), y: floor((size.height - width) / 2.0) - bottomInset), size: CGSize(width: width, height: width))
var colorKeys: [String] = ["__allcolors__"]
let animationName: String
var animationMode: LottieAnimationComponent.AnimationItem.Mode = .still(position: .end)
if case let .silentPost(muted) = item {
if case let .silentPost(previousMuted) = previousItem {
if muted {
animationName = "input_anim_channelMute"
} else {
animationName = "input_anim_channelUnmute"
}
if muted != previousMuted {
animationMode = .animating(loop: false)
}
} else {
animationName = "input_anim_channelMute"
}
} else {
var previousInputMode: ChatTextInputAccessoryItem.InputMode? var previousInputMode: ChatTextInputAccessoryItem.InputMode?
var inputMode: ChatTextInputAccessoryItem.InputMode? var inputMode: ChatTextInputAccessoryItem.InputMode?
@ -203,9 +222,6 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
"Path 85.Path 85.Stroke 1" "Path 85.Path 85.Stroke 1"
] ]
var colorKeys: [String] = ["__allcolors__"]
let animationName: String
var animationMode: LottieAnimationComponent.AnimationItem.Mode = .still(position: .end)
if let inputMode = inputMode { if let inputMode = inputMode {
switch inputMode { switch inputMode {
case .keyboard: case .keyboard:
@ -270,10 +286,11 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
} else { } else {
animationName = "" animationName = ""
} }
}
var colors: [String: UIColor] = [:] var colors: [String: UIColor] = [:]
for colorKey in colorKeys { for colorKey in colorKeys {
colors[colorKey] = self.theme.chat.inputPanel.inputControlColor.blitOver(self.theme.chat.inputPanel.inputBackgroundColor, alpha: 1.0) colors[colorKey] = self.theme.chat.inputPanel.inputControlColor
} }
let animationSize = animationView.update( let animationSize = animationView.update(
@ -284,7 +301,7 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
mode: animationMode mode: animationMode
), ),
colors: colors, colors: colors,
size: CGSize(width: 32.0, height: 32.0) size: iconSize
)), )),
environment: {}, environment: {},
containerSize: animationFrame.size containerSize: animationFrame.size

View File

@ -74,12 +74,14 @@ public final class TelegramRootController: NavigationController {
} }
}) })
if context.sharedContext.applicationBindings.isMainApp {
self.applicationInFocusDisposable = (context.sharedContext.applicationBindings.applicationIsActive self.applicationInFocusDisposable = (context.sharedContext.applicationBindings.applicationIsActive
|> distinctUntilChanged |> distinctUntilChanged
|> deliverOn(Queue.mainQueue())).start(next: { value in |> deliverOn(Queue.mainQueue())).start(next: { value in
context.sharedContext.mainWindow?.setForceBadgeHidden(!value) context.sharedContext.mainWindow?.setForceBadgeHidden(!value)
}) })
} }
}
required public init(coder aDecoder: NSCoder) { required public init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")

View File

@ -800,39 +800,40 @@ public final class WebAppController: ViewController, AttachmentContainable {
self.needDismissConfirmation = needConfirmation self.needDismissConfirmation = needConfirmation
} }
case "web_app_request_phone": case "web_app_request_phone":
let _ = (self.context.account.postbox.loadedPeerWithId(self.context.account.peerId) break
|> deliverOnMainQueue).start(next: { [weak self] accountPeer in // let _ = (self.context.account.postbox.loadedPeerWithId(self.context.account.peerId)
guard let strongSelf = self else { // |> deliverOnMainQueue).start(next: { [weak self] accountPeer in
return // guard let strongSelf = self else {
} // return
guard let user = accountPeer as? TelegramUser, let phoneNumber = user.phone else { // }
return // guard let user = accountPeer as? TelegramUser, let phoneNumber = user.phone else {
} // return
// }
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData) //
var items: [ActionSheetItem] = [] // let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
items.append(ActionSheetTextItem(title: strongSelf.presentationData.strings.WebApp_ShareMyPhoneNumberConfirmation(formatPhoneNumber(phoneNumber), strongSelf.controller?.botName ?? "").string, parseMarkdown: true)) // var items: [ActionSheetItem] = []
items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.WebApp_ShareMyPhoneNumber, action: { [weak actionSheet] in // items.append(ActionSheetTextItem(title: strongSelf.presentationData.strings.WebApp_ShareMyPhoneNumberConfirmation(formatPhoneNumber(phoneNumber), strongSelf.controller?.botName ?? "").string, parseMarkdown: true))
actionSheet?.dismissAnimated() // items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.WebApp_ShareMyPhoneNumber, action: { [weak actionSheet] in
guard let strongSelf = self else { // actionSheet?.dismissAnimated()
return // guard let strongSelf = self else {
} // return
// }
strongSelf.sendPhoneRequestedEvent(phone: phoneNumber) //
})) // strongSelf.sendPhoneRequestedEvent(phone: phoneNumber)
// }))
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [ //
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in // actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
actionSheet?.dismissAnimated() // ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
guard let strongSelf = self else { // actionSheet?.dismissAnimated()
return // guard let strongSelf = self else {
} // return
// }
strongSelf.sendPhoneRequestedEvent(phone: nil) //
}) // strongSelf.sendPhoneRequestedEvent(phone: nil)
])]) // })
strongSelf.controller?.present(actionSheet, in: .window(.root)) // ])])
}) // strongSelf.controller?.present(actionSheet, in: .window(.root))
// })
default: default:
break break
} }