Recent Actions improvements

This commit is contained in:
Ilya Laktyushin 2024-04-17 21:04:14 +04:00
parent 60652f34ee
commit ff09220634
23 changed files with 440 additions and 85 deletions

View File

@ -12089,3 +12089,5 @@ Sorry for the inconvenience.";
"Map.SharingLocation" = "Sharing Location...";
"Channel.AdminLog.Settings" = "Settings";
"Conversation.ContextMenuBanFull" = "Ban";

View File

@ -1,8 +1,8 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "CounterContollerTitleView",
module_name = "CounterContollerTitleView",
name = "CounterControllerTitleView",
module_name = "CounterControllerTitleView",
srcs = glob([
"Sources/**/*.swift",
]),

View File

@ -4,7 +4,7 @@ import Display
import AsyncDisplayKit
import TelegramPresentationData
public struct CounterContollerTitle: Equatable {
public struct CounterControllerTitle: Equatable {
public var title: String
public var counter: String
@ -14,11 +14,11 @@ public struct CounterContollerTitle: Equatable {
}
}
public final class CounterContollerTitleView: UIView {
public final class CounterControllerTitleView: UIView {
private let titleNode: ImmediateTextNode
private let subtitleNode: ImmediateTextNode
public var title: CounterContollerTitle = CounterContollerTitle(title: "", counter: "") {
public var title: CounterControllerTitle = CounterControllerTitle(title: "", counter: "") {
didSet {
if self.title != oldValue {
self.update()

View File

@ -77,7 +77,7 @@ swift_library(
"//submodules/AuthorizationUI:AuthorizationUI",
"//submodules/InstantPageUI:InstantPageUI",
"//submodules/CheckNode:CheckNode",
"//submodules/CounterContollerTitleView:CounterContollerTitleView",
"//submodules/CounterControllerTitleView:CounterControllerTitleView",
"//submodules/GridMessageSelectionNode:GridMessageSelectionNode",
"//submodules/InstantPageCache:InstantPageCache",
"//submodules/AppBundle:AppBundle",

View File

@ -9,7 +9,7 @@ import TelegramPresentationData
import TelegramUIPreferences
import AccountContext
import ShareController
import CounterContollerTitleView
import CounterControllerTitleView
import WallpaperResources
import OverlayStatusController
import AppBundle
@ -139,8 +139,8 @@ public final class ThemePreviewController: ViewController {
isPreview = true
}
let titleView = CounterContollerTitleView(theme: self.previewTheme)
titleView.title = CounterContollerTitle(title: themeName, counter: hasInstallsCount ? " " : "")
let titleView = CounterControllerTitleView(theme: self.previewTheme)
titleView.title = CounterControllerTitle(title: themeName, counter: hasInstallsCount ? " " : "")
self.navigationItem.titleView = titleView
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed))
@ -154,8 +154,8 @@ public final class ThemePreviewController: ViewController {
self.disposable = (combineLatest(self.theme.get(), self.presentationTheme.get())
|> deliverOnMainQueue).start(next: { [weak self] theme, presentationTheme in
if let strongSelf = self, let theme = theme {
let titleView = CounterContollerTitleView(theme: strongSelf.previewTheme)
titleView.title = CounterContollerTitle(title: themeName, counter: hasInstallsCount ? strongSelf.presentationData.strings.Theme_UsersCount(max(1, theme.installCount ?? 0)) : "")
let titleView = CounterControllerTitleView(theme: strongSelf.previewTheme)
titleView.title = CounterControllerTitle(title: themeName, counter: hasInstallsCount ? strongSelf.presentationData.strings.Theme_UsersCount(max(1, theme.installCount ?? 0)) : "")
strongSelf.navigationItem.titleView = titleView
strongSelf.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationTheme: presentationTheme, presentationStrings: strongSelf.presentationData.strings))
}

View File

@ -201,7 +201,7 @@ swift_library(
"//submodules/QrCode:QrCode",
"//submodules/WallpaperResources:WallpaperResources",
"//submodules/AuthorizationUI:AuthorizationUI",
"//submodules/CounterContollerTitleView:CounterContollerTitleView",
"//submodules/CounterControllerTitleView:CounterControllerTitleView",
"//submodules/GridMessageSelectionNode:GridMessageSelectionNode",
"//submodules/InstantPageCache:InstantPageCache",
"//submodules/PersistentStringHash:PersistentStringHash",

View File

@ -2366,7 +2366,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
}
var hasReply = replyMessage != nil || replyForward != nil || replyStory != nil
if !isInstantVideo, case let .peer(peerId) = item.chatLocation, (peerId == replyMessage?.id.peerId || item.message.threadId == 1), let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum), item.message.associatedThreadInfo != nil {
if !isInstantVideo, case let .peer(peerId) = item.chatLocation, (peerId == replyMessage?.id.peerId || item.message.threadId == 1 || item.associatedData.isRecentActions), let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum), item.message.associatedThreadInfo != nil {
if let threadId = item.message.threadId, let replyMessage = replyMessage, Int64(replyMessage.id.id) == threadId {
hasReply = false
}

View File

@ -481,8 +481,12 @@ public class ChatMessageThreadInfoNode: ASDisplayNode {
}
let titleTopicIconContent: EmojiStatusComponent.Content
var containerSize: CGSize = CGSize(width: 22.0, height: 22.0)
var iconX: CGFloat = 0.0
if arguments.threadId == 1 {
titleTopicIconContent = .image(image: generalThreadIcon)
containerSize = CGSize(width: 18.0, height: 18.0)
iconX = 3.0
} else if let fileId = topicIconId, fileId != 0 {
titleTopicIconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 36.0, height: 36.0), placeholderColor: arguments.presentationData.theme.theme.list.mediaPlaceholderColor, themeColor: arguments.presentationData.theme.theme.list.itemAccentColor, loopMode: .count(1))
} else {
@ -504,7 +508,7 @@ public class ChatMessageThreadInfoNode: ASDisplayNode {
transition: .immediate,
component: AnyComponent(titleTopicIconComponent),
environment: {},
containerSize: CGSize(width: 22.0, height: 22.0)
containerSize: containerSize
)
let iconY: CGFloat
@ -514,7 +518,7 @@ public class ChatMessageThreadInfoNode: ASDisplayNode {
iconY = 0.0
}
titleTopicIconView.frame = CGRect(origin: CGPoint(x: insets.left, y: insets.top + iconY), size: iconSize)
titleTopicIconView.frame = CGRect(origin: CGPoint(x: insets.left + iconX, y: insets.top + iconY), size: iconSize)
}
let textFrame = CGRect(origin: CGPoint(x: iconSize.width + 2.0 + insets.left, y: insets.top), size: textLayout.size)

View File

@ -48,6 +48,7 @@ swift_library(
"//submodules/UndoUI",
"//submodules/WallpaperBackgroundNode",
"//submodules/TextFormat",
"//submodules/CounterControllerTitleView"
],
visibility = [
"//visibility:public",

View File

@ -11,6 +11,7 @@ import AlertUI
import PresentationDataUtils
import ChatPresentationInterfaceState
import ChatNavigationButton
import CounterControllerTitleView
public final class ChatRecentActionsController: TelegramBaseController {
private var controllerNode: ChatRecentActionsControllerNode {
@ -28,10 +29,10 @@ public final class ChatRecentActionsController: TelegramBaseController {
private var presentationDataDisposable: Disposable?
private var didSetPresentationData = false
private var interaction: ChatRecentActionsInteraction!
private var panelInteraction: ChatPanelInterfaceInteraction!
private let titleView: ChatRecentActionsTitleView
private let titleView: CounterControllerTitleView
private var rightBarButton: ChatNavigationButton?
public init(context: AccountContext, peer: Peer, adminPeerId: PeerId?) {
self.context = context
@ -40,7 +41,7 @@ public final class ChatRecentActionsController: TelegramBaseController {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.titleView = ChatRecentActionsTitleView(color: self.presentationData.theme.rootController.navigationBar.primaryTextColor)
self.titleView = CounterControllerTitleView(theme: self.presentationData.theme)
super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData), mediaAccessoryPanelVisibility: .specific(size: .compact), locationBroadcastPanelSource: .none, groupCallPanelSource: .none)
@ -48,18 +49,6 @@ public final class ChatRecentActionsController: TelegramBaseController {
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
self.interaction = ChatRecentActionsInteraction(displayInfoAlert: { [weak self] in
if let strongSelf = self {
let text: String
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.Channel_AdminLog_InfoPanelChannelAlertText
} else {
text = strongSelf.presentationData.strings.Channel_AdminLog_InfoPanelAlertText
}
self?.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: strongSelf.presentationData.strings.Channel_AdminLog_InfoPanelAlertTitle, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}
})
self.panelInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in
}, setupEditMessage: { _, _ in
}, beginMessageSelection: { _, _ in
@ -181,13 +170,10 @@ public final class ChatRecentActionsController: TelegramBaseController {
self.navigationItem.titleView = self.titleView
let rightButton = ChatNavigationButton(action: .search(hasTags: false), buttonItem: UIBarButtonItem(image: PresentationResourcesRootController.navigationCompactSearchIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.activateSearch)))
self.navigationItem.setRightBarButton(rightButton.buttonItem, animated: false)
let rightBarButton = ChatNavigationButton(action: .search(hasTags: false), buttonItem: UIBarButtonItem(image: PresentationResourcesRootController.navigationCompactSearchIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.activateSearch)))
self.rightBarButton = rightBarButton
self.titleView.title = self.presentationData.strings.Channel_AdminLog_TitleAllEvents
self.titleView.pressed = { [weak self] in
self?.openFilterSetup()
}
self.titleView.title = CounterControllerTitle(title: EnginePeer(peer).compactDisplayTitle, counter: self.presentationData.strings.Channel_AdminLog_TitleAllEvents)
let themeEmoticon = self.context.account.postbox.peerView(id: peer.id)
|> map { view -> String? in
@ -238,7 +224,7 @@ public final class ChatRecentActionsController: TelegramBaseController {
}
private func updateThemeAndStrings() {
self.titleView.color = self.presentationData.theme.rootController.navigationBar.primaryTextColor
self.titleView.theme = self.presentationData.theme
self.updateTitle()
let rightButton = ChatNavigationButton(action: .search(hasTags: false), buttonItem: UIBarButtonItem(image: PresentationResourcesRootController.navigationCompactSearchIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.activateSearch)))
@ -251,14 +237,19 @@ public final class ChatRecentActionsController: TelegramBaseController {
}
override public func loadDisplayNode() {
self.displayNode = ChatRecentActionsControllerNode(context: self.context, controller: self, peer: self.peer, presentationData: self.presentationData, interaction: self.interaction, pushController: { [weak self] c in
self.displayNode = ChatRecentActionsControllerNode(context: self.context, controller: self, peer: self.peer, presentationData: self.presentationData, pushController: { [weak self] c in
(self?.navigationController as? NavigationController)?.pushViewController(c)
}, presentController: { [weak self] c, t, a in
self?.present(c, in: t, with: a, blockInteraction: true)
}, getNavigationController: { [weak self] in
return self?.navigationController as? NavigationController
})
self.controllerNode.isEmptyUpdated = { [weak self] isEmpty in
guard let self, let rightBarButton = self.rightBarButton else {
return
}
self.navigationItem.setRightBarButton(isEmpty ? nil : rightBarButton.buttonItem, animated: true)
}
if let adminPeerId = self.initialAdminPeerId {
self.controllerNode.updateFilter(events: .all, adminPeerIds: [adminPeerId])
self.updateTitle()
@ -300,7 +291,7 @@ public final class ChatRecentActionsController: TelegramBaseController {
self.updateTitle()
}
private func openFilterSetup() {
func openFilterSetup() {
self.present(channelRecentActionsFilterController(context: self.context, updatedPresentationData: self.updatedPresentationData, peer: self.peer, events: self.controllerNode.filter.events, adminPeerIds: self.controllerNode.filter.adminPeerIds, apply: { [weak self] events, adminPeerIds in
self?.controllerNode.updateFilter(events: events, adminPeerIds: adminPeerIds)
self?.updateTitle()
@ -308,10 +299,13 @@ public final class ChatRecentActionsController: TelegramBaseController {
}
private func updateTitle() {
let title = EnginePeer(self.peer).compactDisplayTitle
let subtitle: String
if self.controllerNode.filter.isEmpty {
self.titleView.title = self.presentationData.strings.Channel_AdminLog_TitleAllEvents
subtitle = self.presentationData.strings.Channel_AdminLog_TitleAllEvents
} else {
self.titleView.title = self.presentationData.strings.Channel_AdminLog_TitleSelectedEvents
subtitle = self.presentationData.strings.Channel_AdminLog_TitleSelectedEvents
}
self.titleView.title = CounterControllerTitle(title: title, counter: subtitle)
}
}

View File

@ -49,8 +49,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
private let pushController: (ViewController) -> Void
private let presentController: (ViewController, PresentationContextType, Any?) -> Void
private let getNavigationController: () -> NavigationController?
var isEmptyUpdated: (Bool) -> Void = { _ in }
private let interaction: ChatRecentActionsInteraction
private var controllerInteraction: ChatControllerInteraction!
private let galleryHiddenMesageAndMediaDisposable = MetaDisposable()
@ -68,6 +68,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
private let panelBackgroundNode: NavigationBackgroundNode
private let panelSeparatorNode: ASDisplayNode
private let panelButtonNode: HighlightableButtonNode
private let panelInfoButtonNode: HighlightableButtonNode
fileprivate let listNode: ListView
private let loadingNode: ChatLoadingNode
@ -99,12 +100,11 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
private weak var controller: ChatRecentActionsController?
init(context: AccountContext, controller: ChatRecentActionsController, peer: Peer, presentationData: PresentationData, interaction: ChatRecentActionsInteraction, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, PresentationContextType, Any?) -> Void, getNavigationController: @escaping () -> NavigationController?) {
init(context: AccountContext, controller: ChatRecentActionsController, peer: Peer, presentationData: PresentationData, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, PresentationContextType, Any?) -> Void, getNavigationController: @escaping () -> NavigationController?) {
self.context = context
self.controller = controller
self.peer = peer
self.presentationData = presentationData
self.interaction = interaction
self.pushController = pushController
self.presentController = presentController
self.getNavigationController = getNavigationController
@ -118,7 +118,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
self.panelSeparatorNode = ASDisplayNode()
self.panelSeparatorNode.backgroundColor = self.presentationData.theme.chat.inputPanel.panelSeparatorColor
self.panelButtonNode = HighlightableButtonNode()
self.panelButtonNode.setTitle(self.presentationData.strings.Channel_AdminLog_InfoPanelTitle, with: Font.regular(17.0), with: self.presentationData.theme.chat.inputPanel.panelControlAccentColor, for: [])
self.panelButtonNode.setTitle(self.presentationData.strings.Channel_AdminLog_Settings, with: Font.regular(17.0), with: self.presentationData.theme.chat.inputPanel.panelControlAccentColor, for: [])
self.panelInfoButtonNode = HighlightableButtonNode()
self.listNode = ListView()
self.listNode.dynamicBounceEnabled = false
@ -145,8 +146,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
self.addSubnode(self.panelBackgroundNode)
self.addSubnode(self.panelSeparatorNode)
self.addSubnode(self.panelButtonNode)
self.addSubnode(self.panelInfoButtonNode)
self.panelButtonNode.addTarget(self, action: #selector(self.infoButtonPressed), forControlEvents: .touchUpInside)
self.panelButtonNode.addTarget(self, action: #selector(self.settingsButtonPressed), forControlEvents: .touchUpInside)
self.panelInfoButtonNode.addTarget(self, action: #selector(self.infoButtonPressed), forControlEvents: .touchUpInside)
let (adminsDisposable, _) = self.context.peerChannelMemberCategoriesContextsManager.admins(engine: self.context.engine, postbox: self.context.account.postbox, network: self.context.account.network, accountPeerId: context.account.peerId, peerId: self.peer.id, searchQuery: nil, updated: { [weak self] state in
self?.adminsState = state
@ -275,7 +278,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}, activateMessagePinch: { _ in
}, openMessageContextActions: { _, _, _, _ in
}, navigateToMessage: { _, _, _ in }, navigateToMessageStandalone: { _ in
}, navigateToThreadMessage: { _, _, _ in
}, navigateToThreadMessage: { [weak self] peerId, threadId, _ in
if let context = self?.context, let navigationController = self?.getNavigationController() {
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .always).startStandalone()
}
}, tapMessage: nil, clickThroughMessage: { }, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _, _, _, _, _ in return false }, sendEmoji: { _, _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _, _ in return false }, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _, _ in }, openUrl: { [weak self] url in
self?.openUrl(url.url)
}, shareCurrentLocation: {}, shareAccountContact: {}, sendBotCommand: { _, _ in }, openInstantPage: { [weak self] message, associatedData in
@ -674,7 +680,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
self.panelBackgroundNode.updateColor(color: presentationData.theme.chat.inputPanel.panelBackgroundColor, transition: .immediate)
self.panelSeparatorNode.backgroundColor = presentationData.theme.chat.inputPanel.panelSeparatorColor
self.panelButtonNode.setTitle(presentationData.strings.Channel_AdminLog_InfoPanelTitle, with: Font.regular(17.0), with: presentationData.theme.chat.inputPanel.panelControlAccentColor, for: [])
self.panelButtonNode.setTitle(presentationData.strings.Channel_AdminLog_Settings, with: Font.regular(17.0), with: presentationData.theme.chat.inputPanel.panelControlAccentColor, for: [])
self.panelInfoButtonNode.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Recent Actions/Info"), color: presentationData.theme.chat.inputPanel.panelControlAccentColor), for: .normal)
}
func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
@ -695,7 +702,11 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
transition.updateFrame(node: self.panelBackgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - panelHeight), size: CGSize(width: layout.size.width, height: panelHeight)))
self.panelBackgroundNode.update(size: self.panelBackgroundNode.bounds.size, transition: transition)
transition.updateFrame(node: self.panelSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - panelHeight), size: CGSize(width: layout.size.width, height: UIScreenPixel)))
transition.updateFrame(node: self.panelButtonNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - panelHeight), size: CGSize(width: layout.size.width, height: intrinsicPanelHeight)))
let infoButtonSize = CGSize(width: 56.0, height: intrinsicPanelHeight)
transition.updateFrame(node: self.panelButtonNode, frame: CGRect(origin: CGPoint(x: insets.left + infoButtonSize.width, y: layout.size.height - panelHeight), size: CGSize(width: layout.size.width - insets.left - insets.right - infoButtonSize.width * 2.0, height: intrinsicPanelHeight)))
transition.updateFrame(node: self.panelInfoButtonNode, frame: CGRect(origin: CGPoint(x: layout.size.width - insets.right - infoButtonSize.width, y: layout.size.height - panelHeight), size: infoButtonSize))
self.visibleAreaInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: panelHeight, right: 0.0)
@ -788,6 +799,12 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
strongSelf.listNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
}
strongSelf.isLoading = isLoading
var isEmpty = false
if strongSelf.filter.isEmpty && (transition.isEmpty || isLoading) {
isEmpty = true
}
strongSelf.isEmptyUpdated(isEmpty)
}
})
} else {
@ -796,8 +813,22 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}
}
@objc func settingsButtonPressed() {
self.controller?.openFilterSetup()
}
@objc func infoButtonPressed() {
self.interaction.displayInfoAlert()
guard let controller = self.controller else {
return
}
let text: String
if let channel = self.peer as? TelegramChannel, case .broadcast = channel.info {
text = self.presentationData.strings.Channel_AdminLog_InfoPanelChannelAlertText
} else {
text = self.presentationData.strings.Channel_AdminLog_InfoPanelAlertText
}
controller.present(textAlertController(context: self.context, updatedPresentationData: controller.updatedPresentationData, title: self.presentationData.strings.Channel_AdminLog_InfoPanelAlertTitle, text: text, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}
func updateSearchQuery(_ query: String) {
@ -936,6 +967,40 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}
}))
)
actions.append(
.action(ContextMenuActionItem(text: self.presentationData.strings.Conversation_ContextMenuBanFull, textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Ban"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] _, f in
if let strongSelf = self {
f(.default)
strongSelf.banDisposables.set((strongSelf.context.engine.peers.fetchChannelParticipant(peerId: strongSelf.peer.id, participantId: author.id)
|> deliverOnMainQueue).startStrict(next: { participant in
if let strongSelf = self {
let initialUserBannedRights = participant?.banInfo?.rights
strongSelf.banDisposables.set(strongSelf.context.engine.peers.removePeerMember(peerId: strongSelf.peer.id, memberId: author.id).startStandalone(), forKey: author.id)
strongSelf.presentController(UndoOverlayController(
presentationData: strongSelf.presentationData,
content: .actionSucceeded(title: nil, text: "**\(EnginePeer(author).compactDisplayTitle)** was banned.", cancel: strongSelf.presentationData.strings.Undo_Undo, destructive: false),
elevatedLayout: false,
action: { [weak self] action in
guard let self else {
return true
}
switch action {
case .commit:
break
case .undo:
let _ = self.context.engine.peers.updateChannelMemberBannedRights(peerId: self.peer.id, memberId: author.id, rights: initialUserBannedRights).startStandalone()
default:
break
}
return true
}
), .current, nil)
}
}), forKey: author.id)
}
}))
)
}
}

View File

@ -7,14 +7,15 @@ import TelegramPresentationData
import WallpaperBackgroundNode
import ChatPresentationInterfaceState
private let titleFont = Font.medium(16.0)
private let textFont = Font.regular(15.0)
private let titleFont = Font.semibold(15.0)
private let textFont = Font.regular(13.0)
public final class ChatRecentActionsEmptyNode: ASDisplayNode {
private var theme: PresentationTheme
private var chatWallpaper: TelegramWallpaper
private let backgroundNode: NavigationBackgroundNode
private let iconNode: ASImageNode
private let titleNode: TextNode
private let textNode: TextNode
@ -34,6 +35,9 @@ public final class ChatRecentActionsEmptyNode: ASDisplayNode {
self.backgroundNode = NavigationBackgroundNode(color: .clear)
self.iconNode = ASImageNode()
self.iconNode.displaysAsynchronously = false
self.titleNode = TextNode()
self.titleNode.isUserInteractionEnabled = false
@ -45,6 +49,7 @@ public final class ChatRecentActionsEmptyNode: ASDisplayNode {
self.allowsGroupOpacity = true
self.addSubnode(self.backgroundNode)
self.addSubnode(self.iconNode)
self.addSubnode(self.titleNode)
self.addSubnode(self.textNode)
}
@ -63,14 +68,15 @@ public final class ChatRecentActionsEmptyNode: ASDisplayNode {
self.wallpaperBackgroundNode = backgroundNode
self.layoutParams = (size, presentationData)
let themeUpdated = self.theme !== presentationData.theme.theme
self.theme = presentationData.theme.theme
self.chatWallpaper = presentationData.theme.wallpaper
self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate)
let insets = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0)
let insets = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 25.0, right: 16.0)
let maxTextWidth = size.width - insets.left - insets.right - 18.0 * 2.0
let maxTextWidth = min(196.0, size.width - insets.left - insets.right - 18.0 * 2.0)
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
let makeTextLayout = TextNode.asyncLayout(self.textNode)
@ -78,17 +84,28 @@ public final class ChatRecentActionsEmptyNode: ASDisplayNode {
let serviceColor = serviceMessageColorComponents(theme: self.theme, wallpaper: self.chatWallpaper)
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: self.title, font: titleFont, textColor: serviceColor.primaryText), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .center, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets()))
let spacing: CGFloat = titleLayout.size.height.isZero ? 0.0 : 5.0
let spacing: CGFloat = titleLayout.size.height.isZero ? 0.0 : 7.0
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: self.text, font: textFont, textColor: serviceColor.primaryText), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .center, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets()))
let contentSize = CGSize(width: max(titleLayout.size.width, textLayout.size.width) + insets.left + insets.right, height: insets.top + insets.bottom + titleLayout.size.height + spacing + textLayout.size.height)
if themeUpdated || self.iconNode.image == nil {
self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Recent Actions/Placeholder"), color: serviceColor.primaryText)
}
let iconSize = self.iconNode.image?.size ?? .zero
let contentSize = CGSize(width: max(titleLayout.size.width, textLayout.size.width) + insets.left + insets.right, height: 5.0 + insets.bottom + iconSize.height - 2.0 + titleLayout.size.height + spacing + textLayout.size.height)
let backgroundFrame = CGRect(origin: CGPoint(x: floor((size.width - contentSize.width) / 2.0), y: floor((size.height - contentSize.height) / 2.0)), size: contentSize)
transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame)
self.backgroundNode.update(size: self.backgroundNode.bounds.size, cornerRadius: min(14.0, self.backgroundNode.bounds.height / 2.0), transition: transition)
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + floor((contentSize.width - titleLayout.size.width) / 2.0), y: backgroundFrame.minY + insets.top), size: titleLayout.size))
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + floor((contentSize.width - textLayout.size.width) / 2.0), y: backgroundFrame.minY + insets.top + titleLayout.size.height + spacing), size: textLayout.size))
let iconFrame = CGRect(origin: CGPoint(x: backgroundFrame.minX + floor((contentSize.width - iconSize.width) / 2.0), y: backgroundFrame.minY + 5.0), size: iconSize)
transition.updateFrame(node: self.iconNode, frame: iconFrame)
let titleFrame = CGRect(origin: CGPoint(x: backgroundFrame.minX + floor((contentSize.width - titleLayout.size.width) / 2.0), y: iconFrame.maxY - 2.0), size: titleLayout.size)
transition.updateFrame(node: self.titleNode, frame: titleFrame)
let textFrame = CGRect(origin: CGPoint(x: backgroundFrame.minX + floor((contentSize.width - textLayout.size.width) / 2.0), y: titleFrame.maxY + spacing), size: textLayout.size)
transition.updateFrame(node: self.textNode, frame: textFrame)
let _ = titleApply()
let _ = textApply()

View File

@ -404,6 +404,9 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
if let attribute = attribute as? TextEntitiesMessageAttribute {
attributes.append(attribute)
}
if let attribute = attribute as? ReplyMessageAttribute {
attributes.append(attribute)
}
}
for attribute in attributes {
for peerId in attribute.associatedPeerIds {
@ -412,7 +415,10 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
}
}
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
if let peer = self.entry.peers[message.id.peerId] {
peers[peer.id] = peer
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: message.threadId, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: message.associatedThreadInfo, associatedStories: [:])
return ChatMessageItemImpl(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadPeerId: nil, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, savedMessageTags: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
} else {
var peers = SimpleDictionary<PeerId, Peer>()
@ -488,6 +494,9 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
if let attribute = attribute as? TextEntitiesMessageAttribute {
attributes.append(attribute)
}
if let attribute = attribute as? ReplyMessageAttribute {
attributes.append(attribute)
}
}
for attribute in attributes {
for peerId in attribute.associatedPeerIds {
@ -496,7 +505,10 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
}
}
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
if let peer = self.entry.peers[message.id.peerId] {
peers[peer.id] = peer
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: message.threadId, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: message.associatedMessages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: message.associatedThreadInfo, associatedStories: [:])
return ChatMessageItemImpl(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadPeerId: nil, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, savedMessageTags: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.text.isEmpty || !message.text.isEmpty ? .eventLogPreviousMessage(filterOriginalMessageFlags(prev)) : nil)
}
case let .deleteMessage(message):
@ -531,6 +543,9 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
if let attribute = attribute as? TextEntitiesMessageAttribute {
attributes.append(attribute)
}
if let attribute = attribute as? ReplyMessageAttribute {
attributes.append(attribute)
}
}
for attribute in attributes {
for peerId in attribute.associatedPeerIds {
@ -549,7 +564,10 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
if let peer = self.entry.peers[self.entry.event.peerId] {
peers[peer.id] = peer
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: message.id.id), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
if let peer = self.entry.peers[message.id.peerId] {
peers[peer.id] = peer
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: message.id.id), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: message.threadId, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: message.associatedMessages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: message.associatedThreadInfo, associatedStories: [:])
return ChatMessageItemImpl(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadPeerId: nil, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, savedMessageTags: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
}
case .participantJoin, .participantLeave:
@ -1110,6 +1128,9 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
if let attribute = attribute as? TextEntitiesMessageAttribute {
attributes.append(attribute)
}
if let attribute = attribute as? ReplyMessageAttribute {
attributes.append(attribute)
}
}
for attribute in attributes {
for peerId in attribute.associatedPeerIds {
@ -1118,7 +1139,10 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
}
}
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.author, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
if let peer = self.entry.peers[message.id.peerId] {
peers[peer.id] = peer
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.author, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: message.associatedMessages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: message.associatedThreadInfo, associatedStories: [:])
return ChatMessageItemImpl(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadPeerId: nil, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, savedMessageTags: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: nil)
}
case let .linkedPeerUpdated(previous, updated):
@ -1706,6 +1730,9 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
if let attribute = attribute as? TextEntitiesMessageAttribute {
attributes.append(attribute)
}
if let attribute = attribute as? ReplyMessageAttribute {
attributes.append(attribute)
}
}
for attribute in attributes {
for peerId in attribute.associatedPeerIds {
@ -1714,7 +1741,10 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
}
}
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
if let peer = self.entry.peers[message.id.peerId] {
peers[peer.id] = peer
}
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: message.threadId, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: message.associatedMessages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: message.associatedThreadInfo, associatedStories: [:])
return ChatMessageItemImpl(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadPeerId: nil, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, savedMessageTags: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
}
case let .createTopic(info):

View File

@ -28,7 +28,7 @@ swift_library(
"//submodules/MergeLists",
"//submodules/ShareController",
"//submodules/GalleryUI",
"//submodules/CounterContollerTitleView",
"//submodules/CounterControllerTitleView",
"//submodules/LegacyMediaPickerUI",
"//submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode",
"//submodules/TelegramUI/Components/PremiumLockButtonSubtitleComponent",

View File

@ -14,7 +14,7 @@ import AccountContext
import ShareController
import GalleryUI
import HexColor
import CounterContollerTitleView
import CounterControllerTitleView
import UndoUI
import LegacyComponents
import LegacyMediaPickerUI
@ -350,8 +350,8 @@ public class WallpaperGalleryController: ViewController {
self.centralItemAttributesDisposable.add(self.centralItemSubtitle.get().start(next: { [weak self] subtitle in
if let strongSelf = self {
if let subtitle = subtitle {
let titleView = CounterContollerTitleView(theme: strongSelf.presentationData.theme)
titleView.title = CounterContollerTitle(title: strongSelf.presentationData.strings.WallpaperPreview_Title, counter: subtitle)
let titleView = CounterControllerTitleView(theme: strongSelf.presentationData.theme)
titleView.title = CounterControllerTitle(title: strongSelf.presentationData.strings.WallpaperPreview_Title, counter: subtitle)
strongSelf.navigationItem.titleView = titleView
strongSelf.title = nil
} else {

View File

@ -0,0 +1,9 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"provides-namespace" : true
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "question.circle.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,99 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 4.334961 4.334999 cm
0.000000 0.000000 0.000000 scn
10.665000 20.000002 m
5.509422 20.000002 1.330000 15.820580 1.330000 10.665002 c
1.330000 5.509424 5.509422 1.330002 10.665000 1.330002 c
15.820578 1.330002 20.000000 5.509424 20.000000 10.665002 c
20.000000 15.820580 15.820578 20.000002 10.665000 20.000002 c
h
0.000000 10.665002 m
0.000000 16.555119 4.774883 21.330002 10.665000 21.330002 c
16.555117 21.330002 21.330002 16.555119 21.330002 10.665002 c
21.330002 4.774885 16.555117 0.000000 10.665000 0.000000 c
4.774883 0.000000 0.000000 4.774885 0.000000 10.665002 c
h
10.665000 15.138485 m
9.306379 15.138485 8.205000 14.037106 8.205000 12.678485 c
8.205000 12.311215 7.907269 12.013485 7.540000 12.013485 c
7.172730 12.013485 6.875000 12.311215 6.875000 12.678485 c
6.875000 14.771645 8.571840 16.468485 10.665000 16.468485 c
12.758160 16.468485 14.455000 14.771645 14.455000 12.678485 c
14.455000 11.036498 13.411167 9.640008 11.953011 9.113155 c
11.520578 8.956911 11.330000 8.669144 11.330000 8.470152 c
11.330000 7.990985 l
11.330000 7.623715 11.032269 7.325985 10.665000 7.325985 c
10.297730 7.325985 10.000000 7.623715 10.000000 7.990985 c
10.000000 8.470152 l
10.000000 9.467776 10.808081 10.113627 11.501059 10.364010 c
12.449083 10.706545 13.125000 11.614429 13.125000 12.678485 c
13.125000 14.037106 12.023621 15.138485 10.665000 15.138485 c
h
10.664997 4.006662 m
11.240294 4.006662 11.706664 4.473032 11.706664 5.048328 c
11.706664 5.623627 11.240294 6.089996 10.664997 6.089996 c
10.089701 6.089996 9.623331 5.623627 9.623331 5.048328 c
9.623331 4.473032 10.089701 4.006662 10.664997 4.006662 c
h
f*
n
Q
endstream
endobj
3 0 obj
1692
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000001782 00000 n
0000001805 00000 n
0000001978 00000 n
0000002052 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
2111
%%EOF

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "recentactions.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,110 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 23.500000 18.363636 cm
0.000000 0.000000 0.000000 scn
36.636364 54.363636 m
35.330963 54.363636 34.306767 55.443432 33.939365 56.696064 c
32.932384 60.129303 29.758968 62.636364 26.000000 62.636364 c
22.241032 62.636364 19.067616 60.129303 18.060635 56.696064 c
17.693233 55.443432 16.669035 54.363636 15.363634 54.363636 c
7.090909 54.363636 l
3.174709 54.363636 0.000000 51.188931 0.000000 47.272728 c
0.000000 7.090908 l
0.000000 3.174709 3.174708 0.000000 7.090909 0.000000 c
44.909092 0.000000 l
48.825291 0.000000 52.000000 3.174709 52.000000 7.090908 c
52.000000 47.272728 l
52.000000 51.188927 48.825291 54.363636 44.909092 54.363636 c
36.636364 54.363636 l
h
29.545456 54.363636 m
29.545456 52.405537 27.958101 50.818184 26.000000 50.818184 c
24.041901 50.818184 22.454546 52.405537 22.454546 54.363636 c
22.454546 56.321739 24.041901 57.909092 26.000000 57.909092 c
27.958101 57.909092 29.545456 56.321739 29.545456 54.363636 c
h
14.181818 41.363636 m
12.876418 41.363636 11.818182 40.305401 11.818182 39.000000 c
11.818182 37.694599 12.876417 36.636364 14.181818 36.636364 c
37.818184 36.636364 l
39.123581 36.636364 40.181816 37.694599 40.181816 39.000000 c
40.181816 40.305401 39.123581 41.363636 37.818184 41.363636 c
14.181818 41.363636 l
h
14.181818 29.545456 m
12.876418 29.545456 11.818182 28.487217 11.818182 27.181820 c
11.818182 25.876419 12.876417 24.818180 14.181818 24.818180 c
37.818184 24.818180 l
39.123581 24.818180 40.181816 25.876419 40.181816 27.181820 c
40.181816 28.487217 39.123581 29.545456 37.818184 29.545456 c
14.181818 29.545456 l
h
11.818182 15.363636 m
11.818182 16.669041 12.876418 17.727276 14.181818 17.727276 c
28.363640 17.727276 l
29.669039 17.727276 30.727272 16.669041 30.727272 15.363636 c
30.727272 14.058239 29.669035 13.000004 28.363636 13.000004 c
14.181814 13.000004 l
12.876414 13.000004 11.818182 14.058239 11.818182 15.363636 c
h
f*
n
Q
endstream
endobj
3 0 obj
1962
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 100.000000 100.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000002052 00000 n
0000002075 00000 n
0000002250 00000 n
0000002324 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
2383
%%EOF

View File

@ -12,7 +12,7 @@ import AccountContext
import AlertUI
import PresentationDataUtils
import ContactListUI
import CounterContollerTitleView
import CounterControllerTitleView
import EditableTokenListNode
import PremiumUI
import UndoUI
@ -35,7 +35,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
private let isPeerEnabled: ((EnginePeer) -> Bool)?
private let attemptDisabledItemSelection: ((EnginePeer, ChatListDisabledPeerReason) -> Void)?
private let titleView: CounterContollerTitleView
private let titleView: CounterControllerTitleView
private var contactsNode: ContactMultiselectionControllerNode {
return self.displayNode as! ContactMultiselectionControllerNode
@ -100,7 +100,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
self.limit = params.limit
self.presentationData = params.updatedPresentationData?.initial ?? params.context.sharedContext.currentPresentationData.with { $0 }
self.titleView = CounterContollerTitleView(theme: self.presentationData.theme)
self.titleView = CounterControllerTitleView(theme: self.presentationData.theme)
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData))
@ -250,7 +250,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
case let .chats(chatsNode):
count = chatsNode.currentState.selectedPeerIds.count
}
self.titleView.title = CounterContollerTitle(title: self.presentationData.strings.Compose_NewGroupTitle, counter: "\(count)/\(maxCount)")
self.titleView.title = CounterControllerTitle(title: self.presentationData.strings.Compose_NewGroupTitle, counter: "\(count)/\(maxCount)")
if self.rightNavigationButton == nil {
let rightNavigationButton = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.rightNavigationButtonPressed))
self.rightNavigationButton = rightNavigationButton
@ -262,23 +262,23 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
if case let .contacts(contactsNode) = self.contactsNode.contentNode {
count = contactsNode.selectionState?.selectedPeerIndices.count ?? 0
}
self.titleView.title = CounterContollerTitle(title: self.presentationData.strings.Premium_Gift_ContactSelection_Title, counter: "\(count)/\(maxCount)")
self.titleView.title = CounterControllerTitle(title: self.presentationData.strings.Premium_Gift_ContactSelection_Title, counter: "\(count)/\(maxCount)")
case .requestedUsersSelection:
let maxCount: Int32 = self.limit ?? 10
var count = 0
if case let .contacts(contactsNode) = self.contactsNode.contentNode {
count = contactsNode.selectionState?.selectedPeerIndices.count ?? 0
}
self.titleView.title = CounterContollerTitle(title: self.presentationData.strings.RequestPeer_SelectUsers, counter: "\(count)/\(maxCount)")
self.titleView.title = CounterControllerTitle(title: self.presentationData.strings.RequestPeer_SelectUsers, counter: "\(count)/\(maxCount)")
case .channelCreation:
self.titleView.title = CounterContollerTitle(title: self.presentationData.strings.GroupInfo_AddParticipantTitle, counter: "")
self.titleView.title = CounterControllerTitle(title: self.presentationData.strings.GroupInfo_AddParticipantTitle, counter: "")
if self.rightNavigationButton == nil {
let rightNavigationButton = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.rightNavigationButtonPressed))
self.rightNavigationButton = rightNavigationButton
self.navigationItem.rightBarButtonItem = self.rightNavigationButton
}
case .peerSelection:
self.titleView.title = CounterContollerTitle(title: self.presentationData.strings.PrivacyLastSeenSettings_EmpryUsersPlaceholder, counter: "")
self.titleView.title = CounterControllerTitle(title: self.presentationData.strings.PrivacyLastSeenSettings_EmpryUsersPlaceholder, counter: "")
if self.rightNavigationButton == nil {
let rightNavigationButton = UIBarButtonItem(title: self.presentationData.strings.Common_Done, style: .done, target: self, action: #selector(self.rightNavigationButtonPressed))
self.rightNavigationButton = rightNavigationButton
@ -286,7 +286,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
self.navigationItem.rightBarButtonItem = self.rightNavigationButton
}
case let .chatSelection(chatSelection):
self.titleView.title = CounterContollerTitle(title: chatSelection.title, counter: "")
self.titleView.title = CounterControllerTitle(title: chatSelection.title, counter: "")
if self.rightNavigationButton == nil {
let rightNavigationButton = UIBarButtonItem(title: self.presentationData.strings.Common_Done, style: .done, target: self, action: #selector(self.rightNavigationButtonPressed))
self.rightNavigationButton = rightNavigationButton
@ -540,13 +540,13 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
switch strongSelf.mode {
case .groupCreation:
let maxCount: Int32 = strongSelf.limitsConfiguration?.maxSupergroupMemberCount ?? 5000
strongSelf.titleView.title = CounterContollerTitle(title: strongSelf.presentationData.strings.Compose_NewGroupTitle, counter: "\(updatedCount)/\(maxCount)")
strongSelf.titleView.title = CounterControllerTitle(title: strongSelf.presentationData.strings.Compose_NewGroupTitle, counter: "\(updatedCount)/\(maxCount)")
case .premiumGifting:
let maxCount: Int32 = strongSelf.limit ?? 10
strongSelf.titleView.title = CounterContollerTitle(title: strongSelf.presentationData.strings.Premium_Gift_ContactSelection_Title, counter: "\(updatedCount)/\(maxCount)")
strongSelf.titleView.title = CounterControllerTitle(title: strongSelf.presentationData.strings.Premium_Gift_ContactSelection_Title, counter: "\(updatedCount)/\(maxCount)")
case .requestedUsersSelection:
let maxCount: Int32 = strongSelf.limit ?? 10
strongSelf.titleView.title = CounterContollerTitle(title: strongSelf.presentationData.strings.RequestPeer_SelectUsers, counter: "\(updatedCount)/\(maxCount)")
strongSelf.titleView.title = CounterControllerTitle(title: strongSelf.presentationData.strings.RequestPeer_SelectUsers, counter: "\(updatedCount)/\(maxCount)")
case .peerSelection, .channelCreation, .chatSelection:
break
}

View File

@ -18,7 +18,7 @@ swift_library(
"//submodules/PresentationDataUtils:PresentationDataUtils",
"//submodules/AccountContext:AccountContext",
"//submodules/AttachmentUI:AttachmentUI",
"//submodules/CounterContollerTitleView:CounterContollerTitleView",
"//submodules/CounterControllerTitleView:CounterControllerTitleView",
"//submodules/HexColor:HexColor",
"//submodules/PhotoResources:PhotoResources",
"//submodules/ShimmerEffect:ShimmerEffect",

View File

@ -9,7 +9,7 @@ import SwiftSignalKit
import TelegramPresentationData
import AccountContext
import AttachmentUI
import CounterContollerTitleView
import CounterControllerTitleView
import ContextUI
import PresentationDataUtils
import HexColor
@ -1703,7 +1703,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
return self.displayNode as! Node
}
private var titleView: CounterContollerTitleView?
private var titleView: CounterControllerTitleView?
fileprivate let cancelButtonNode: WebAppCancelButtonNode
fileprivate let moreButtonNode: MoreButtonNode
@ -1774,8 +1774,8 @@ public final class WebAppController: ViewController, AttachmentContainable {
self.navigationItem.rightBarButtonItem?.action = #selector(self.moreButtonPressed)
self.navigationItem.rightBarButtonItem?.target = self
let titleView = CounterContollerTitleView(theme: self.presentationData.theme)
titleView.title = CounterContollerTitle(title: params.botName, counter: self.presentationData.strings.Bot_GenericBotStatus)
let titleView = CounterControllerTitleView(theme: self.presentationData.theme)
titleView.title = CounterControllerTitle(title: params.botName, counter: self.presentationData.strings.Bot_GenericBotStatus)
self.navigationItem.titleView = titleView
self.titleView = titleView