mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
9e908c9ea7
commit
ad9f0d6847
@ -33,6 +33,7 @@ public struct AttachmentMainButtonState {
|
||||
}
|
||||
|
||||
public let text: String?
|
||||
public let badge: String?
|
||||
public let font: Font
|
||||
public let background: Background
|
||||
public let textColor: UIColor
|
||||
@ -44,6 +45,7 @@ public struct AttachmentMainButtonState {
|
||||
|
||||
public init(
|
||||
text: String?,
|
||||
badge: String? = nil,
|
||||
font: Font,
|
||||
background: Background,
|
||||
textColor: UIColor,
|
||||
@ -54,6 +56,7 @@ public struct AttachmentMainButtonState {
|
||||
position: Position? = nil
|
||||
) {
|
||||
self.text = text
|
||||
self.badge = badge
|
||||
self.font = font
|
||||
self.background = background
|
||||
self.textColor = textColor
|
||||
|
@ -79,7 +79,7 @@ public enum ContactMultiselectionControllerMode {
|
||||
case channelCreation
|
||||
case chatSelection(ChatSelection)
|
||||
case premiumGifting(birthdays: [EnginePeer.Id: TelegramBirthday]?, selectToday: Bool, hasActions: Bool)
|
||||
case requestedUsersSelection
|
||||
case requestedUsersSelection(isBot: Bool?, isPremium: Bool?)
|
||||
}
|
||||
|
||||
public enum ContactListFilter {
|
||||
|
@ -59,6 +59,7 @@ public final class PeerSelectionControllerParams {
|
||||
public let createNewGroup: (() -> Void)?
|
||||
public let pretendPresentedInModal: Bool
|
||||
public let multipleSelection: Bool
|
||||
public let multipleSelectionLimit: Int32?
|
||||
public let forwardedMessageIds: [EngineMessage.Id]
|
||||
public let hasTypeHeaders: Bool
|
||||
public let selectForumThreads: Bool
|
||||
@ -80,6 +81,7 @@ public final class PeerSelectionControllerParams {
|
||||
createNewGroup: (() -> Void)? = nil,
|
||||
pretendPresentedInModal: Bool = false,
|
||||
multipleSelection: Bool = false,
|
||||
multipleSelectionLimit: Int32? = nil,
|
||||
forwardedMessageIds: [EngineMessage.Id] = [],
|
||||
hasTypeHeaders: Bool = false,
|
||||
selectForumThreads: Bool = false,
|
||||
@ -100,6 +102,7 @@ public final class PeerSelectionControllerParams {
|
||||
self.createNewGroup = createNewGroup
|
||||
self.pretendPresentedInModal = pretendPresentedInModal
|
||||
self.multipleSelection = multipleSelection
|
||||
self.multipleSelectionLimit = multipleSelectionLimit
|
||||
self.forwardedMessageIds = forwardedMessageIds
|
||||
self.hasTypeHeaders = hasTypeHeaders
|
||||
self.selectForumThreads = selectForumThreads
|
||||
|
@ -382,12 +382,102 @@ private final class LoadingProgressNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
private final class BadgeNode: ASDisplayNode {
|
||||
private var fillColor: UIColor
|
||||
private var strokeColor: UIColor
|
||||
private var textColor: UIColor
|
||||
|
||||
private let textNode: ImmediateTextNode
|
||||
private let backgroundNode: ASImageNode
|
||||
|
||||
private let font: UIFont = Font.with(size: 15.0, design: .round, weight: .bold)
|
||||
|
||||
var text: String = "" {
|
||||
didSet {
|
||||
self.textNode.attributedText = NSAttributedString(string: self.text, font: self.font, textColor: self.textColor)
|
||||
self.invalidateCalculatedLayout()
|
||||
}
|
||||
}
|
||||
|
||||
init(fillColor: UIColor, strokeColor: UIColor, textColor: UIColor) {
|
||||
self.fillColor = fillColor
|
||||
self.strokeColor = strokeColor
|
||||
self.textColor = textColor
|
||||
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.isUserInteractionEnabled = false
|
||||
self.textNode.displaysAsynchronously = false
|
||||
|
||||
self.backgroundNode = ASImageNode()
|
||||
self.backgroundNode.isLayerBacked = true
|
||||
self.backgroundNode.displayWithoutProcessing = true
|
||||
self.backgroundNode.displaysAsynchronously = false
|
||||
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 18.0, color: fillColor, strokeColor: nil, strokeWidth: 1.0)
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.backgroundNode)
|
||||
self.addSubnode(self.textNode)
|
||||
|
||||
self.isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
func updateTheme(fillColor: UIColor, strokeColor: UIColor, textColor: UIColor) {
|
||||
self.fillColor = fillColor
|
||||
self.strokeColor = strokeColor
|
||||
self.textColor = textColor
|
||||
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 18.0, color: fillColor, strokeColor: strokeColor, strokeWidth: 1.0)
|
||||
self.textNode.attributedText = NSAttributedString(string: self.text, font: self.font, textColor: self.textColor)
|
||||
}
|
||||
|
||||
func animateBump(incremented: Bool) {
|
||||
if incremented {
|
||||
let firstTransition = ContainedViewLayoutTransition.animated(duration: 0.1, curve: .easeInOut)
|
||||
firstTransition.updateTransformScale(layer: self.backgroundNode.layer, scale: 1.2)
|
||||
firstTransition.updateTransformScale(layer: self.textNode.layer, scale: 1.2, completion: { finished in
|
||||
if finished {
|
||||
let secondTransition = ContainedViewLayoutTransition.animated(duration: 0.1, curve: .easeInOut)
|
||||
secondTransition.updateTransformScale(layer: self.backgroundNode.layer, scale: 1.0)
|
||||
secondTransition.updateTransformScale(layer: self.textNode.layer, scale: 1.0)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
let firstTransition = ContainedViewLayoutTransition.animated(duration: 0.1, curve: .easeInOut)
|
||||
firstTransition.updateTransformScale(layer: self.backgroundNode.layer, scale: 0.8)
|
||||
firstTransition.updateTransformScale(layer: self.textNode.layer, scale: 0.8, completion: { finished in
|
||||
if finished {
|
||||
let secondTransition = ContainedViewLayoutTransition.animated(duration: 0.1, curve: .easeInOut)
|
||||
secondTransition.updateTransformScale(layer: self.backgroundNode.layer, scale: 1.0)
|
||||
secondTransition.updateTransformScale(layer: self.textNode.layer, scale: 1.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func animateOut() {
|
||||
let timingFunction = CAMediaTimingFunctionName.easeInEaseOut.rawValue
|
||||
self.backgroundNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.3, delay: 0.0, timingFunction: timingFunction, removeOnCompletion: true, completion: nil)
|
||||
self.textNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.3, delay: 0.0, timingFunction: timingFunction, removeOnCompletion: true, completion: nil)
|
||||
}
|
||||
|
||||
func update(_ constrainedSize: CGSize) -> CGSize {
|
||||
let badgeSize = self.textNode.updateLayout(constrainedSize)
|
||||
let backgroundSize = CGSize(width: max(18.0, badgeSize.width + 8.0), height: 18.0)
|
||||
let backgroundFrame = CGRect(origin: CGPoint(), size: backgroundSize)
|
||||
self.backgroundNode.frame = backgroundFrame
|
||||
self.textNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels(backgroundFrame.midX - badgeSize.width / 2.0), y: floorToScreenPixels((backgroundFrame.size.height - badgeSize.height) / 2.0) - UIScreenPixel), size: badgeSize)
|
||||
|
||||
return backgroundSize
|
||||
}
|
||||
}
|
||||
|
||||
private final class MainButtonNode: HighlightTrackingButtonNode {
|
||||
private var state: AttachmentMainButtonState
|
||||
private var size: CGSize?
|
||||
|
||||
private let backgroundAnimationNode: ASImageNode
|
||||
fileprivate let textNode: ImmediateTextNode
|
||||
private var badgeNode: BadgeNode?
|
||||
private let statusNode: SemanticStatusNode
|
||||
private var progressNode: ASImageNode?
|
||||
|
||||
@ -616,6 +706,7 @@ private final class MainButtonNode: HighlightTrackingButtonNode {
|
||||
progressNode.image = generateIndefiniteActivityIndicatorImage(color: state.textColor, diameter: diameter, lineWidth: 3.0)
|
||||
}
|
||||
|
||||
var textFrame: CGRect = .zero
|
||||
if let text = state.text {
|
||||
let font: UIFont
|
||||
switch state.font {
|
||||
@ -627,13 +718,7 @@ private final class MainButtonNode: HighlightTrackingButtonNode {
|
||||
self.textNode.attributedText = NSAttributedString(string: text, font: font, textColor: state.textColor)
|
||||
|
||||
let textSize = self.textNode.updateLayout(size)
|
||||
let textFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: floorToScreenPixels((size.height - textSize.height) / 2.0)), size: textSize)
|
||||
if self.textNode.frame.width.isZero {
|
||||
self.textNode.frame = textFrame
|
||||
} else {
|
||||
self.textNode.bounds = CGRect(origin: .zero, size: textSize)
|
||||
transition.updatePosition(node: self.textNode, position: textFrame.center)
|
||||
}
|
||||
textFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: floorToScreenPixels((size.height - textSize.height) / 2.0)), size: textSize)
|
||||
|
||||
switch state.background {
|
||||
case let .color(backgroundColor):
|
||||
@ -669,6 +754,40 @@ private final class MainButtonNode: HighlightTrackingButtonNode {
|
||||
}
|
||||
}
|
||||
|
||||
if let badge = state.badge {
|
||||
let badgeNode: BadgeNode
|
||||
var badgeTransition = transition
|
||||
if let current = self.badgeNode {
|
||||
badgeNode = current
|
||||
} else {
|
||||
badgeTransition = .immediate
|
||||
var textColor: UIColor
|
||||
switch state.background {
|
||||
case let .color(backgroundColor):
|
||||
textColor = backgroundColor
|
||||
case .premium:
|
||||
textColor = UIColor(rgb: 0x0077ff)
|
||||
}
|
||||
badgeNode = BadgeNode(fillColor: state.textColor, strokeColor: .clear, textColor: textColor)
|
||||
self.badgeNode = badgeNode
|
||||
self.addSubnode(badgeNode)
|
||||
}
|
||||
badgeNode.text = badge
|
||||
let badgeSize = badgeNode.update(CGSize(width: 100.0, height: 100.0))
|
||||
textFrame.origin.x -= badgeSize.width / 2.0
|
||||
badgeTransition.updateFrame(node: badgeNode, frame: CGRect(origin: CGPoint(x: textFrame.maxX + 6.0, y: textFrame.minY + floorToScreenPixels((textFrame.height - badgeSize.height) * 0.5)), size: badgeSize))
|
||||
} else if let badgeNode = self.badgeNode {
|
||||
self.badgeNode = nil
|
||||
badgeNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
if self.textNode.frame.width.isZero {
|
||||
self.textNode.frame = textFrame
|
||||
} else {
|
||||
self.textNode.bounds = CGRect(origin: .zero, size: textFrame.size)
|
||||
transition.updatePosition(node: self.textNode, position: textFrame.center)
|
||||
}
|
||||
|
||||
if previousState.progress != state.progress {
|
||||
if state.progress == .center {
|
||||
self.transitionToProgress()
|
||||
|
@ -2491,6 +2491,9 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
case let .user(userType):
|
||||
if case let .user(user) = peer {
|
||||
match = true
|
||||
if user.id.isVerificationCodes {
|
||||
match = false
|
||||
}
|
||||
if let isBot = userType.isBot {
|
||||
if isBot != (user.botInfo != nil) {
|
||||
match = false
|
||||
|
@ -878,14 +878,10 @@ private final class ChatListMediaPreviewNode: ASDisplayNode {
|
||||
if file.isInstantVideo {
|
||||
isRound = true
|
||||
}
|
||||
if file.isSticker || file.isAnimatedSticker {
|
||||
self.playIcon.isHidden = true
|
||||
} else {
|
||||
if file.isAnimated {
|
||||
self.playIcon.isHidden = true
|
||||
} else {
|
||||
if file.isVideo && !file.isAnimated {
|
||||
self.playIcon.isHidden = false
|
||||
}
|
||||
} else {
|
||||
self.playIcon.isHidden = true
|
||||
}
|
||||
if let mediaDimensions = file.dimensions {
|
||||
dimensions = mediaDimensions.cgSize
|
||||
@ -2646,6 +2642,9 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
} else if contentImageIsDisplayedAsAvatar && (file.isSticker || file.isVideoSticker) {
|
||||
let fitSize = contentImageSize
|
||||
contentImageSpecs.append(ContentImageSpec(message: message, media: .file(file), size: fitSize))
|
||||
} else if !file.previewRepresentations.isEmpty, let _ = file.dimensions {
|
||||
let fitSize = contentImageSize
|
||||
contentImageSpecs.append(ContentImageSpec(message: message, media: .file(file), size: fitSize))
|
||||
}
|
||||
break inner
|
||||
} else if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content {
|
||||
|
@ -2464,6 +2464,9 @@ public final class ChatListNode: ListView {
|
||||
case let .user(userType):
|
||||
if case let .user(user) = peer {
|
||||
match = true
|
||||
if user.id.isVerificationCodes {
|
||||
match = false
|
||||
}
|
||||
if let isBot = userType.isBot {
|
||||
if isBot != (user.botInfo != nil) {
|
||||
match = false
|
||||
|
@ -59,7 +59,7 @@ public final class CounterControllerTitleView: UIView {
|
||||
let primaryTextColor = self.primaryTextColor ?? self.theme.rootController.navigationBar.primaryTextColor
|
||||
let secondaryTextColor = self.secondaryTextColor ?? self.theme.rootController.navigationBar.secondaryTextColor
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.title.title, font: Font.semibold(17.0), textColor: primaryTextColor)
|
||||
self.subtitleNode.attributedText = NSAttributedString(string: self.title.counter, font: Font.regular(13.0), textColor: secondaryTextColor)
|
||||
self.subtitleNode.attributedText = NSAttributedString(string: self.title.counter, font: Font.with(size: 13.0, traits: .monospacedNumbers), textColor: secondaryTextColor)
|
||||
|
||||
self.accessibilityLabel = self.title.title
|
||||
self.accessibilityValue = self.title.counter
|
||||
|
@ -381,7 +381,11 @@ const CGFloat TGPhotoEditorSliderViewInternalMargin = 7.0f;
|
||||
|
||||
- (void)setValue:(CGFloat)value animated:(BOOL)__unused animated
|
||||
{
|
||||
if (_lowerBoundValue > FLT_EPSILON) {
|
||||
_value = MIN(MAX(_lowerBoundValue, MAX(value, _minimumValue)), _maximumValue);
|
||||
} else {
|
||||
_value = MIN(MAX(value, _minimumValue), _maximumValue);
|
||||
}
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
|
@ -298,8 +298,23 @@ final class StickerPackEmojisItemNode: GridItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
private var visibleRect: CGRect?
|
||||
override func updateAbsoluteRect(_ absoluteRect: CGRect, within containerSize: CGSize) {
|
||||
var y: CGFloat
|
||||
if absoluteRect.minY > 0.0 {
|
||||
y = 0.0
|
||||
} else {
|
||||
y = absoluteRect.minY * -1.0
|
||||
}
|
||||
var rect = CGRect(origin: CGPoint(x: 0.0, y: y), size: CGSize(width: containerSize.width, height: containerSize.height))
|
||||
rect.size.height += 96.0
|
||||
self.visibleRect = rect
|
||||
|
||||
self.updateVisibleItems(attemptSynchronousLoads: false, transition: .immediate)
|
||||
}
|
||||
|
||||
func updateVisibleItems(attemptSynchronousLoads: Bool, transition: ContainedViewLayoutTransition) {
|
||||
guard let item = self.item, !self.size.width.isZero else {
|
||||
guard let item = self.item, !self.size.width.isZero, let visibleRect = self.visibleRect else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -321,17 +336,26 @@ final class StickerPackEmojisItemNode: GridItemNode {
|
||||
self.containerNode.frame = CGRect(origin: CGPoint(x: 0.0, y: item.title != nil ? 61.0 : 0.0), size: CGSize(width: itemLayout.width, height: itemLayout.height))
|
||||
|
||||
for index in 0 ..< items.count {
|
||||
var itemFrame = itemLayout.frame(itemIndex: index)
|
||||
if !visibleRect.intersects(itemFrame) {
|
||||
continue
|
||||
}
|
||||
let item = items[index]
|
||||
let itemId = EmojiKeyboardItemLayer.Key(
|
||||
groupId: 0,
|
||||
itemId: .animation(.file(item.file.fileId))
|
||||
)
|
||||
validIds.insert(itemId)
|
||||
|
||||
let itemDimensions = item.file.dimensions?.cgSize ?? CGSize(width: 512.0, height: 512.0)
|
||||
let itemNativeFitSize = itemDimensions.fitted(CGSize(width: nativeItemSize, height: nativeItemSize))
|
||||
let itemVisibleFitSize = itemDimensions.fitted(CGSize(width: itemLayout.visibleItemSize, height: itemLayout.visibleItemSize))
|
||||
|
||||
validIds.insert(itemId)
|
||||
|
||||
itemFrame.origin.x += floor((itemFrame.width - itemVisibleFitSize.width) / 2.0)
|
||||
itemFrame.origin.y += floor((itemFrame.height - itemVisibleFitSize.height) / 2.0)
|
||||
itemFrame.size = itemVisibleFitSize
|
||||
|
||||
var updateItemLayerPlaceholder = false
|
||||
var itemTransition = transition
|
||||
let itemLayer: EmojiKeyboardItemLayer
|
||||
@ -426,12 +450,6 @@ final class StickerPackEmojisItemNode: GridItemNode {
|
||||
itemLayer.layerTintColor = color.cgColor
|
||||
}
|
||||
|
||||
var itemFrame = itemLayout.frame(itemIndex: index)
|
||||
|
||||
itemFrame.origin.x += floor((itemFrame.width - itemVisibleFitSize.width) / 2.0)
|
||||
itemFrame.origin.y += floor((itemFrame.height - itemVisibleFitSize.height) / 2.0)
|
||||
itemFrame.size = itemVisibleFitSize
|
||||
|
||||
let itemPosition = CGPoint(x: itemFrame.midX, y: itemFrame.midY)
|
||||
let itemBounds = CGRect(origin: CGPoint(), size: itemFrame.size)
|
||||
itemTransition.updatePosition(layer: itemLayer, position: itemPosition)
|
||||
|
@ -34,6 +34,7 @@ swift_library(
|
||||
"//submodules/ContextUI",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/TelegramUI/Components/Chat/ForwardAccessoryPanelNode",
|
||||
"//submodules/CounterControllerTitleView",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -9,6 +9,7 @@ import ProgressNavigationButtonNode
|
||||
import AccountContext
|
||||
import SearchUI
|
||||
import ChatListUI
|
||||
import CounterControllerTitleView
|
||||
|
||||
public final class PeerSelectionControllerImpl: ViewController, PeerSelectionController {
|
||||
private let context: AccountContext
|
||||
@ -64,6 +65,7 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
||||
private let forwardedMessageIds: [EngineMessage.Id]
|
||||
private let hasTypeHeaders: Bool
|
||||
private let requestPeerType: [ReplyMarkupButtonRequestPeerType]?
|
||||
let multipleSelectionLimit: Int32?
|
||||
private let hasCreation: Bool
|
||||
let immediatelyActivateMultipleSelection: Bool
|
||||
|
||||
@ -81,6 +83,7 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
||||
}
|
||||
}
|
||||
|
||||
private(set) var titleView: CounterControllerTitleView?
|
||||
private var searchContentNode: NavigationBarSearchContentNode?
|
||||
var tabContainerNode: ChatListFilterTabContainerNode?
|
||||
private var tabContainerData: ([ChatListFilterTabEntry], Bool, Int32?)?
|
||||
@ -107,6 +110,7 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
||||
self.requestPeerType = params.requestPeerType
|
||||
self.hasCreation = params.hasCreation
|
||||
self.immediatelyActivateMultipleSelection = params.immediatelyActivateMultipleSelection
|
||||
self.multipleSelectionLimit = params.multipleSelectionLimit
|
||||
|
||||
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData))
|
||||
|
||||
@ -133,7 +137,13 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
||||
}
|
||||
}
|
||||
|
||||
if let maxCount = params.multipleSelectionLimit {
|
||||
self.titleView = CounterControllerTitleView(theme: self.presentationData.theme)
|
||||
self.titleView?.title = CounterControllerTitle(title: self.customTitle ?? self.presentationData.strings.Conversation_ForwardTitle, counter: "0/\(maxCount)")
|
||||
self.navigationItem.titleView = self.titleView
|
||||
} else {
|
||||
self.title = self.customTitle ?? self.presentationData.strings.Conversation_ForwardTitle
|
||||
}
|
||||
|
||||
if params.forumPeerId == nil {
|
||||
self.navigationPresentation = .modal
|
||||
|
@ -24,6 +24,7 @@ import SolidRoundedButtonNode
|
||||
import ContextUI
|
||||
import TextFormat
|
||||
import ForwardAccessoryPanelNode
|
||||
import CounterControllerTitleView
|
||||
|
||||
final class PeerSelectionControllerNode: ASDisplayNode {
|
||||
private let context: AccountContext
|
||||
@ -215,6 +216,9 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
||||
} else {
|
||||
self.mainContainerNode = nil
|
||||
self.chatListNode = ChatListNode(context: context, location: chatListLocation, previewing: false, fillPreloadItems: false, mode: chatListMode, theme: self.presentationData.theme, fontSize: presentationData.listsFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, animationCache: self.animationCache, animationRenderer: self.animationRenderer, disableAnimations: true, isInlineMode: false, autoSetReady: true, isMainTab: false)
|
||||
if let multipleSelectionLimit = controller.multipleSelectionLimit {
|
||||
self.chatListNode?.selectionLimit = multipleSelectionLimit
|
||||
}
|
||||
}
|
||||
|
||||
super.init()
|
||||
@ -926,7 +930,17 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
||||
} else if let chatListNode = self.chatListNode {
|
||||
chatListNode.selectionCountChanged = { [weak self] count in
|
||||
if let self {
|
||||
if let _ = self.controller?.multipleSelectionLimit {
|
||||
self.countPanelNode?.buttonTitle = self.presentationData.strings.Premium_Gift_ContactSelection_Proceed
|
||||
} else {
|
||||
self.countPanelNode?.buttonTitle = self.presentationData.strings.ShareMenu_Send
|
||||
}
|
||||
self.countPanelNode?.count = count
|
||||
|
||||
if let titleView = self.controller?.titleView, let maxCount = self.controller?.multipleSelectionLimit {
|
||||
titleView.title = CounterControllerTitle(title: titleView.title.title, counter: "\(count)/\(maxCount)")
|
||||
}
|
||||
|
||||
if let (layout, navigationBarHeight, actualNavigationBarHeight) = self.containerLayout {
|
||||
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, actualNavigationBarHeight: actualNavigationBarHeight, transition: .animated(duration: 0.3, curve: .spring))
|
||||
}
|
||||
@ -1789,10 +1803,11 @@ private final class PeersCountPanelNode: ASDisplayNode {
|
||||
|
||||
private var validLayout: (CGFloat, CGFloat, CGFloat)?
|
||||
|
||||
var buttonTitle: String = ""
|
||||
var count: Int = 0 {
|
||||
didSet {
|
||||
if self.count != oldValue && self.count > 0 {
|
||||
self.button.title = self.strings.ShareMenu_Send
|
||||
self.button.title = self.buttonTitle
|
||||
self.button.badge = "\(self.count)"
|
||||
|
||||
if let (width, sideInset, bottomInset) = self.validLayout {
|
||||
|
@ -4060,10 +4060,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
strongSelf.present(controller, in: .window(.root))
|
||||
}
|
||||
|
||||
if case .user = peerType, maxQuantity > 1 {
|
||||
if case let .user(requestUser) = peerType, maxQuantity > 1, requestUser.isBot == nil && requestUser.isPremium == nil {
|
||||
let presentationData = self.presentationData
|
||||
var reachedLimitImpl: ((Int32) -> Void)?
|
||||
let controller = context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(context: context, mode: .requestedUsersSelection, isPeerEnabled: { peer in
|
||||
let controller = context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(context: context, mode: .requestedUsersSelection(isBot: requestUser.isBot, isPremium: requestUser.isPremium), isPeerEnabled: { peer in
|
||||
if case let .user(user) = peer, user.botInfo == nil {
|
||||
return true
|
||||
} else {
|
||||
@ -4105,7 +4105,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
var createNewGroupImpl: (() -> Void)?
|
||||
let controller = self.context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: self.context, filter: [.excludeRecent, .doNotSearchMessages], requestPeerType: [peerType], hasContactSelector: false, createNewGroup: {
|
||||
createNewGroupImpl?()
|
||||
}, hasCreation: true))
|
||||
}, multipleSelection: maxQuantity > 1, multipleSelectionLimit: maxQuantity > 1 ? maxQuantity : nil, hasCreation: true, immediatelyActivateMultipleSelection: maxQuantity > 1))
|
||||
|
||||
controller.peerSelected = { [weak self, weak controller] peer, _ in
|
||||
guard let strongSelf = self else {
|
||||
@ -4126,6 +4126,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
})
|
||||
}
|
||||
}
|
||||
controller.multiplePeersSelected = { [weak controller] peers, _, _, _, _, _ in
|
||||
let peerIds = peers.map { $0.id }
|
||||
let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerIds: peerIds).startStandalone()
|
||||
controller?.dismiss()
|
||||
}
|
||||
createNewGroupImpl = { [weak controller] in
|
||||
switch peerType {
|
||||
case .user:
|
||||
|
Loading…
x
Reference in New Issue
Block a user