Merge commit 'aed91241e54eac239bcfe799960ef80995c772ab'

# Conflicts:
#	TelegramUI/ChatController.swift
This commit is contained in:
Peter 2018-09-05 00:35:04 +03:00
commit a5b6e48579
12 changed files with 164 additions and 94 deletions

View File

@ -11,13 +11,14 @@ private final class ChannelBlacklistControllerArguments {
let addPeer: () -> Void
let removePeer: (PeerId) -> Void
let openPeer: (ChannelParticipant) -> Void
init(account: Account, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addPeer: @escaping () -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (ChannelParticipant) -> Void) {
let openPeerInfo:(Peer) -> Void
init(account: Account, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addPeer: @escaping () -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (ChannelParticipant) -> Void, openPeerInfo: @escaping(Peer)->Void) {
self.account = account
self.addPeer = addPeer
self.setPeerIdWithRevealedOptions = setPeerIdWithRevealedOptions
self.removePeer = removePeer
self.openPeer = openPeer
self.openPeerInfo = openPeerInfo
}
}
@ -194,7 +195,9 @@ private enum ChannelBlacklistEntry: ItemListNodeEntry {
}
return ItemListPeerItem(theme: theme, strings: strings, account: arguments.account, peer: participant.peer, presence: nil, text: text, label: .none, editing: editing, switchValue: nil, enabled: enabled, sectionId: self.section, action: canOpen ? {
arguments.openPeer(participant.participant)
} : nil, setPeerIdWithRevealedOptions: { previousId, id in
} : {
arguments.openPeerInfo(participant.peer)
}, setPeerIdWithRevealedOptions: { previousId, id in
arguments.setPeerIdWithRevealedOptions(previousId, id)
}, removePeer: { peerId in
arguments.removePeer(peerId)
@ -295,7 +298,8 @@ public func channelBlacklistController(account: Account, peerId: PeerId) -> View
}
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
var pushControllerImpl: ((ViewController) -> Void)?
let actionsDisposable = DisposableSet()
let updateBannedDisposable = MetaDisposable()
@ -360,6 +364,10 @@ public func channelBlacklistController(account: Account, peerId: PeerId) -> View
}, openPeer: { participant in
presentControllerImpl?(channelBannedMemberController(account: account, peerId: peerId, memberId: participant.peerId, initialParticipant: participant, updated: { _ in
}), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
}, openPeerInfo: { peer in
if let controller = peerInfoController(account: account, peer: peer) {
pushControllerImpl?(controller)
}
})
let peerView = account.viewTracker.peerView(peerId)
@ -436,6 +444,12 @@ public func channelBlacklistController(account: Account, peerId: PeerId) -> View
controller.present(c, in: .window(.root), with: p)
}
}
pushControllerImpl = { [weak controller] c in
if let controller = controller {
(controller.navigationController as? NavigationController)?.pushViewController(c)
}
}
controller.visibleBottomContentOffsetChanged = { offset in
if case let .known(value) = offset, value < 40.0 {
account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.loadMore(peerId: peerId, control: loadMoreControl)

View File

@ -824,11 +824,11 @@ public func channelVisibilityController(account: Account, peerId: PeerId, mode:
if let updatedAddressNameValue = updatedAddressNameValue {
let confirm = standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: presentationData.strings.Channel_Edit_PrivatePublicLinkAlert, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
let invokeAction: ()->Void = {
updateState { state in
return state.withUpdatedUpdatingAddressName(true)
}
_ = ApplicationSpecificNotice.markAsSeenSetPublicChannelLink(postbox: account.postbox).start()
updateAddressNameDisposable.set((updateAddressName(account: account, domain: .peer(peerId), name: updatedAddressNameValue.isEmpty ? nil : updatedAddressNameValue) |> timeout(10, queue: Queue.mainQueue(), alternate: .fail(.generic))
|> deliverOnMainQueue).start(error: { _ in
@ -849,10 +849,19 @@ public func channelVisibilityController(account: Account, peerId: PeerId, mode:
dismissImpl?()
}
}))
})])
}
_ = (ApplicationSpecificNotice.getSetPublicChannelLink(postbox: account.postbox) |> deliverOnMainQueue).start(next: { showAlert in
if showAlert {
let confirm = standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: presentationData.strings.Channel_Edit_PrivatePublicLinkAlert, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: invokeAction)])
presentControllerImpl?(confirm, nil)
} else {
invokeAction()
}
})
presentControllerImpl?(confirm, nil)
} else {

View File

@ -235,6 +235,8 @@ public final class ChatController: TelegramController, UIViewControllerPreviewin
guard let strongSelf = self, strongSelf.isNodeLoaded, let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(message.id) else {
return false
}
var openMessageByAction: Bool = false
for media in message.media {
if let action = media as? TelegramMediaAction {
switch action.action {
@ -245,10 +247,14 @@ public final class ChatController: TelegramController, UIViewControllerPreviewin
break
}
}
case let .photoUpdated(image):
openMessageByAction = image != nil
default:
break
}
return true
if !openMessageByAction {
return true
}
}
}

View File

@ -251,6 +251,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
dataSignal = combineLatest(loadLimits, loadStickerSaveStatusSignal, loadResourceStatusSignal, chatAvailableMessageActions(postbox: account.postbox, accountPeerId: account.peerId, messageIds: Set(messages.map { $0.id })))
|> map { limitsConfiguration, stickerSaveStatus, resourceStatus, messageActions -> MessageContextMenuData in
var canEdit = false
var restrictEdit: Bool = false
if messages[0].id.namespace == Namespaces.Message.Cloud && !isAction {
let message = messages[0]
@ -267,6 +268,12 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
}
}
if let peer = message.peers[message.id.peerId] as? TelegramChannel {
if peer.hasBannedRights(.banSendMessages) {
restrictEdit = true
}
}
if hasEditRights {
var hasUneditableAttributes = false
for attribute in message.attributes {
@ -297,7 +304,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
if !hasUneditableAttributes {
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
if canPerformEditingActions(limits: limitsConfiguration, accountPeerId: account.peerId, message: message) {
canEdit = true
canEdit = !restrictEdit
}
}
}
@ -424,7 +431,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
}
if !data.messageActions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty && isAction {
actions.append(.context(ContextMenuAction(content: .text(chatPresentationInterfaceState.strings.Conversation_ContextMenuDelete), action: {
interfaceInteraction.deleteMessages(messages)
let _ = deleteMessagesInteractively(postbox: account.postbox, messageIds: messages.map { $0.id }, type: .forEveryone).start()
})))
}

View File

@ -466,6 +466,16 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
super.didLoad()
}
override func transitionNode(messageId: MessageId, media: Media) -> (ASDisplayNode, () -> UIView?)? {
if let imageNode = self.imageNode {
return (imageNode, { [weak imageNode] in
return imageNode?.view.snapshotContentTree(unhide: true)
})
} else {
return nil
}
}
override func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize) -> (ChatMessageBubbleContentProperties, unboundSize: CGSize?, maxWidth: CGFloat, layout: (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation) -> Void))) {
let makeLabelLayout = TextNode.asyncLayout(self.labelNode)
@ -637,6 +647,9 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
return .hashtag(hashtag.peerName, hashtag.hashtag)
}
}
if let imageNode = imageNode, imageNode.frame.contains(point) {
return .openMessage
}
if self.filledBackgroundNode.frame.contains(point.offsetBy(dx: 0.0, dy: -10.0)) {
return .openMessage

View File

@ -547,12 +547,24 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
let hasFilter: Bool = strongSelf.filter.events != .all || strongSelf.filter.query != nil
var isSupergroup: Bool = false
if let peer = strongSelf.peer as? TelegramChannel {
switch peer.info {
case .group:
isSupergroup = true
default:
break
}
}
if displayEmptyNode {
var text: String = ""
if let query = strongSelf.filter.query, hasFilter {
text = strongSelf.presentationData.strings.Channel_AdminLog_EmptyFilterQueryText(query).0
} else {
text = strongSelf.presentationData.strings.Channel_AdminLog_EmptyText
text = isSupergroup ? strongSelf.presentationData.strings.Group_AdminLog_EmptyText : strongSelf.presentationData.strings.Channel_AdminLog_EmptyText
}
strongSelf.emptyNode.setup(title: hasFilter ? strongSelf.presentationData.strings.Channel_AdminLog_EmptyFilterTitle : strongSelf.presentationData.strings.Channel_AdminLog_EmptyTitle, text: text)
}

View File

@ -240,7 +240,7 @@ private final class InnerLanguageSelectionController: UIViewController, UITableV
self.searchController.searchBar.barTintColor = self.presentationData.theme.chatList.backgroundColor
self.searchController.searchBar.tintColor = self.presentationData.theme.rootController.navigationBar.accentTextColor
self.searchController.searchBar.backgroundColor = self.presentationData.theme.chatList.backgroundColor
self.searchController.searchBar.setTextColor(self.presentationData.theme.chatList.titleColor)
self.searchController.searchBar.setTextColor(self.presentationData.theme.chatList.titleColor)
let searchImage = generateImage(CGSize(width: 8.0, height: 28.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))

View File

@ -94,7 +94,7 @@ private enum ApplicationSpecificGlobalNotice: Int32 {
case proxyAdsAcknowledgment = 2
case chatMediaMediaRecordingTips = 3
case profileCallTips = 4
case setPublicChannelLink = 5
var key: ValueBoxKey {
let v = ValueBoxKey(length: 4)
v.setInt32(0, value: self.rawValue)
@ -129,6 +129,10 @@ private struct ApplicationSpecificNoticeKeys {
static func proxyAdsAcknowledgment() -> NoticeEntryKey {
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.proxyAdsAcknowledgment.key)
}
static func setPublicChannelLink() -> NoticeEntryKey {
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.setPublicChannelLink.key)
}
}
struct ApplicationSpecificNotice {
@ -236,6 +240,22 @@ struct ApplicationSpecificNotice {
}
}
static func getSetPublicChannelLink(postbox: Postbox) -> Signal<Bool, NoError> {
return postbox.transaction { transaction -> Bool in
if let value = transaction.getNoticeEntry(key: ApplicationSpecificNoticeKeys.profileCallTips()) as? ApplicationSpecificCounterNotice {
return value.value < 1
} else {
return true
}
}
}
static func markAsSeenSetPublicChannelLink(postbox: Postbox) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Void in
transaction.setNoticeEntry(key: ApplicationSpecificNoticeKeys.profileCallTips(), value: ApplicationSpecificCounterNotice(value: 1))
}
}
static func getProxyAdsAcknowledgment(postbox: Postbox) -> Signal<Bool, NoError> {
return postbox.transaction { transaction -> Bool in
if let _ = transaction.getNoticeEntry(key: ApplicationSpecificNoticeKeys.proxyAdsAcknowledgment()) as? ApplicationSpecificBoolNotice {

View File

@ -17,6 +17,7 @@ private enum ChatMessageGalleryControllerData {
case gallery(GalleryController)
case secretGallery(SecretMediaPreviewController)
case other(Media)
case chatAvatars(AvatarGalleryController, Media)
}
private func chatMessageGalleryControllerData(account: Account, message: Message, navigationController: NavigationController?, standalone: Bool, reverseMessageGalleryOrder: Bool, synchronousLoad: Bool) -> ChatMessageGalleryControllerData? {
@ -24,7 +25,20 @@ private func chatMessageGalleryControllerData(account: Account, message: Message
var otherMedia: Media?
var instantPageMedia: (TelegramMediaWebpage, [InstantPageGalleryEntry])?
for media in message.media {
if let file = media as? TelegramMediaFile {
if let action = media as? TelegramMediaAction {
switch action.action {
case let .photoUpdated(image):
if let peer = messageMainPeer(message), let image = image {
let promise: Promise<[AvatarGalleryEntry]> = Promise([AvatarGalleryEntry.image(image, nil)])
let galleryController = AvatarGalleryController(account: account, peer: peer, remoteEntries: promise, replaceRootController: { controller, ready in
})
return .chatAvatars(galleryController, image)
}
default:
break
}
} else if let file = media as? TelegramMediaFile {
galleryMedia = file
} else if let image = media as? TelegramMediaImage {
galleryMedia = image
@ -311,6 +325,15 @@ func openChatMessage(account: Account, message: Message, standalone: Bool, rever
})
return true
}
case let .chatAvatars(controller, media):
present(controller, AvatarGalleryControllerPresentationArguments(transitionArguments: { entry in
if let selectedTransitionNode = transitionNode(message.id, media) {
return GalleryTransitionArguments(transitionNode: selectedTransitionNode, addToTransitionSurface: addToTransitionSurface)
}
return nil
}))
}
}
return false

View File

@ -2918,6 +2918,7 @@ public final class PresentationStrings {
public let PrivacySettings_DeleteAccountIfAwayFor: String
public let Channel_AdminLog_EmptyFilterText: String
public let Channel_AdminLog_EmptyText: String
public let Group_AdminLog_EmptyText: String
public let PrivacySettings_DeleteAccountTitle: String
public let Passport_Language_ms: String
public let PrivacyLastSeenSettings_CustomShareSettings_Delete: String
@ -7480,6 +7481,7 @@ public final class PresentationStrings {
self.PrivacySettings_DeleteAccountIfAwayFor = getValue(dict, "PrivacySettings.DeleteAccountIfAwayFor")
self.Channel_AdminLog_EmptyFilterText = getValue(dict, "Channel.AdminLog.EmptyFilterText")
self.Channel_AdminLog_EmptyText = getValue(dict, "Channel.AdminLog.EmptyText")
self.Group_AdminLog_EmptyText = getValue(dict, "Group.AdminLog.EmptyText")
self.PrivacySettings_DeleteAccountTitle = getValue(dict, "PrivacySettings.DeleteAccountTitle")
self.Passport_Language_ms = getValue(dict, "Passport.Language.ms")
self.PrivacyLastSeenSettings_CustomShareSettings_Delete = getValue(dict, "PrivacyLastSeenSettings.CustomShareSettings.Delete")

View File

@ -35,6 +35,21 @@ public extension TermsOfServiceControllerTheme {
convenience init(authTheme: AuthorizationTheme) {
self.init(statusBarStyle: authTheme.statusBarStyle, navigationBackground: authTheme.navigationBarBackgroundColor, navigationSeparator: authTheme.navigationBarSeparatorColor, listBackground: authTheme.listBackgroundColor, itemBackground: authTheme.backgroundColor, itemSeparator: authTheme.separatorColor, primary: authTheme.primaryColor, accent: authTheme.accentColor)
}
var presentationTheme: PresentationTheme {
let theme: PresentationTheme
switch itemBackground.argb {
case defaultPresentationTheme.list.itemBlocksBackgroundColor.argb:
theme = defaultPresentationTheme
case defaultDarkPresentationTheme.list.itemBlocksBackgroundColor.argb:
theme = defaultDarkPresentationTheme
case defaultDarkAccentPresentationTheme.list.itemBlocksBackgroundColor.argb:
theme = defaultDarkAccentPresentationTheme
default:
theme = defaultPresentationTheme
}
return theme
}
}
public class TermsOfServiceController: ViewController {
@ -113,12 +128,7 @@ public class TermsOfServiceController: ViewController {
text = strongSelf.strings.PrivacyPolicy_DeclineMessage
declineTitle = strongSelf.strings.PrivacyPolicy_DeclineDeclineAndDelete
}
let theme: PresentationTheme
if strongSelf.theme.itemBackground.argb == 0xffffffff {
theme = defaultPresentationTheme
} else {
theme = defaultDarkPresentationTheme
}
let theme: PresentationTheme = strongSelf.theme.presentationTheme
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: theme), title: strongSelf.strings.PrivacyPolicy_Decline, text: text, actions: [TextAlertAction(type: .destructiveAction, title: declineTitle, action: {
self?.decline()
}), TextAlertAction(type: .defaultAction, title: strongSelf.strings.Common_Cancel, action: {
@ -129,12 +139,7 @@ public class TermsOfServiceController: ViewController {
}
if let ageConfirmation = strongSelf.ageConfirmation {
let theme: PresentationTheme
if strongSelf.theme.itemBackground.argb == 0xffffffff {
theme = defaultPresentationTheme
} else {
theme = defaultDarkPresentationTheme
}
let theme: PresentationTheme = strongSelf.theme.presentationTheme
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: theme), title: strongSelf.strings.PrivacyPolicy_AgeVerificationTitle, text: strongSelf.strings.PrivacyPolicy_AgeVerificationMessage("\(ageConfirmation)").0, actions: [TextAlertAction(type: .genericAction, title: strongSelf.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: strongSelf.strings.PrivacyPolicy_AgeVerificationAgree, action: {
self?.accept(self?.proccessBotNameAfterAccept)
})]), in: .window(.root))

View File

@ -127,6 +127,26 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode {
return nil
}
}
let showMentionActionSheet:(String) -> Void = { [weak self] mention in
guard let strongSelf = self else {
return
}
let theme: PresentationTheme = strongSelf.theme.presentationTheme
let actionSheet = ActionSheetController(presentationTheme: theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: strongSelf.strings.Login_TermsOfService_ProceedBot(mention).0),
ActionSheetButtonItem(title: strongSelf.strings.PrivacyPolicy_Accept, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
setToProcceedBot(mention)
rightAction()
})
]), ActionSheetItemGroup.init(items: [ActionSheetButtonItem(title: strongSelf.strings.Common_Cancel, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})])])
strongSelf.present(actionSheet, nil)
}
self.contentTextNode.tapAttributeAction = { [weak self] attributes in
guard let strongSelf = self else {
return
@ -134,37 +154,9 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode {
if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String {
strongSelf.openUrl(url)
} else if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention {
let theme: PresentationTheme
if strongSelf.theme.itemBackground.argb == 0xffffffff {
theme = defaultPresentationTheme
} else {
theme = defaultDarkPresentationTheme
}
let actionSheet = ActionSheetController(presentationTheme: theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: strongSelf.strings.Login_TermsOfService_ProceedBot(mention.mention).0),
ActionSheetButtonItem(title: strongSelf.strings.Common_OK, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
setToProcceedBot(mention.mention)
})
])])
strongSelf.present(actionSheet, nil)
showMentionActionSheet(mention.mention)
} else if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String {
let theme: PresentationTheme
if strongSelf.theme.itemBackground.argb == 0xffffffff {
theme = defaultPresentationTheme
} else {
theme = defaultDarkPresentationTheme
}
let actionSheet = ActionSheetController(presentationTheme: theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: strongSelf.strings.Login_TermsOfService_ProceedBot(mention).0),
ActionSheetButtonItem(title: strongSelf.strings.Common_OK, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
setToProcceedBot(mention)
})
])])
strongSelf.present(actionSheet, nil)
showMentionActionSheet(mention)
}
}
self.contentTextNode.longTapAttributeAction = { [weak self] attributes in
@ -172,12 +164,7 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode {
return
}
if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String {
let theme: PresentationTheme
if strongSelf.theme.itemBackground.argb == 0xffffffff {
theme = defaultPresentationTheme
} else {
theme = defaultDarkPresentationTheme
}
let theme: PresentationTheme = strongSelf.theme.presentationTheme
let actionSheet = ActionSheetController(presentationTheme: theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: url),
@ -196,37 +183,9 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode {
])])
strongSelf.present(actionSheet, nil)
} else if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention {
let theme: PresentationTheme
if strongSelf.theme.itemBackground.argb == 0xffffffff {
theme = defaultPresentationTheme
} else {
theme = defaultDarkPresentationTheme
}
let actionSheet = ActionSheetController(presentationTheme: theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: strongSelf.strings.Login_TermsOfService_ProceedBot(mention.mention).0),
ActionSheetButtonItem(title: strongSelf.strings.Common_OK, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
setToProcceedBot(mention.mention)
})
])])
strongSelf.present(actionSheet, nil)
showMentionActionSheet(mention.mention)
} else if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String {
let theme: PresentationTheme
if strongSelf.theme.itemBackground.argb == 0xffffffff {
theme = defaultPresentationTheme
} else {
theme = defaultDarkPresentationTheme
}
let actionSheet = ActionSheetController(presentationTheme: theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: strongSelf.strings.Login_TermsOfService_ProceedBot(mention).0),
ActionSheetButtonItem(title: strongSelf.strings.Common_OK, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
setToProcceedBot(mention)
})
])])
strongSelf.present(actionSheet, nil)
showMentionActionSheet(mention)
}
}
}