mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Group boosts
This commit is contained in:
parent
1b2b7dc403
commit
b4b90b090c
65 changed files with 3569 additions and 1969 deletions
|
|
@ -10987,6 +10987,7 @@ Sorry for the inconvenience.";
|
|||
"ContactList.Context.Delete" = "Delete Contact";
|
||||
"ContactList.Context.Select" = "Select";
|
||||
|
||||
"ContactList.DeleteConfirmationSingle" = "Delete Contact";
|
||||
"ContactList.DeleteConfirmation_1" = "Delete %@ Contact";
|
||||
"ContactList.DeleteConfirmation_any" = "Delete %@ Contacts";
|
||||
|
||||
|
|
@ -11082,3 +11083,12 @@ Sorry for the inconvenience.";
|
|||
"GroupInfo.Permissions.DontRestrictBoosters" = "Do Not Restrict Boosters";
|
||||
"GroupInfo.Permissions.DontRestrictBoostersInfo" = "Choose how many boosts a user must give to the group to bypass restrictions on sending messages.";
|
||||
"GroupInfo.Permissions.DontRestrictBoostersEnableInfo" = "Turn this on to always allow users who boosted your group to send messages and media.";
|
||||
|
||||
"Notification.Boost.Times_1" = "%@ time";
|
||||
"Notification.Boost.Times_any" = "%@ times";
|
||||
|
||||
"Notification.Boost.Single" = "%1$@ boosted the group";
|
||||
"Notification.Boost.Multiple" = "%1$@ boosted the group %2$@";
|
||||
|
||||
"Notification.Boost.SingleYou" = "You boosted the group";
|
||||
"Notification.Boost.MultipleYou" = "You boosted the group %1$@";
|
||||
|
|
|
|||
|
|
@ -739,7 +739,6 @@ public enum InstalledStickerPacksControllerMode {
|
|||
case modal
|
||||
case masks
|
||||
case emoji
|
||||
case groupEmoji(selectedPack: StickerPackCollectionInfo?, completion: (StickerPackCollectionInfo?) -> Void)
|
||||
}
|
||||
|
||||
public let defaultContactLabel: String = "_$!<Mobile>!$_"
|
||||
|
|
|
|||
|
|
@ -981,6 +981,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
|||
}, hideTranslationPanel: {
|
||||
}, openPremiumGift: {
|
||||
}, openPremiumRequiredForMessaging: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, requestLayout: { _ in
|
||||
}, chatController: {
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ private final class CameraContext {
|
|||
transform = CGAffineTransformTranslate(transform, 0.0, -size.height)
|
||||
ciImage = ciImage.transformed(by: transform)
|
||||
}
|
||||
ciImage = ciImage.clampedToExtent().applyingGaussianBlur(sigma: Camera.isDualCameraSupported ? 100.0 : 40.0).cropped(to: CGRect(origin: .zero, size: size))
|
||||
ciImage = ciImage.clampedToExtent().applyingGaussianBlur(sigma: Camera.isDualCameraSupported(forRoundVideo: true) ? 100.0 : 40.0).cropped(to: CGRect(origin: .zero, size: size))
|
||||
if let cgImage = self.ciContext.createCGImage(ciImage, from: ciImage.extent) {
|
||||
let uiImage = UIImage(cgImage: cgImage, scale: 1.0, orientation: .right)
|
||||
if front {
|
||||
|
|
@ -1056,15 +1056,18 @@ public final class Camera {
|
|||
}
|
||||
}
|
||||
|
||||
public static var isDualCameraSupported: Bool {
|
||||
public static func isDualCameraSupported(forRoundVideo: Bool = false) -> Bool {
|
||||
if #available(iOS 13.0, *), AVCaptureMultiCamSession.isMultiCamSupported && !DeviceModel.current.isIpad {
|
||||
if forRoundVideo && DeviceModel.current == .iPhoneXR {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e
|
||||
public final class CameraHolder {
|
||||
public let camera: Camera
|
||||
public let previewView: CameraPreviewView
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ public final class ChatPanelInterfaceInteraction {
|
|||
public let openPremiumGift: () -> Void
|
||||
public let openPremiumRequiredForMessaging: () -> Void
|
||||
public let updateHistoryFilter: ((ChatPresentationInterfaceState.HistoryFilter?) -> ChatPresentationInterfaceState.HistoryFilter?) -> Void
|
||||
public let openBoostToUnrestrict: () -> Void
|
||||
public let requestLayout: (ContainedViewLayoutTransition) -> Void
|
||||
public let chatController: () -> ViewController?
|
||||
public let statuses: ChatPanelInterfaceInteractionStatuses?
|
||||
|
|
@ -281,6 +282,7 @@ public final class ChatPanelInterfaceInteraction {
|
|||
hideTranslationPanel: @escaping () -> Void,
|
||||
openPremiumGift: @escaping () -> Void,
|
||||
openPremiumRequiredForMessaging: @escaping () -> Void,
|
||||
openBoostToUnrestrict: @escaping () -> Void,
|
||||
updateHistoryFilter: @escaping ((ChatPresentationInterfaceState.HistoryFilter?) -> ChatPresentationInterfaceState.HistoryFilter?) -> Void,
|
||||
requestLayout: @escaping (ContainedViewLayoutTransition) -> Void,
|
||||
chatController: @escaping () -> ViewController?,
|
||||
|
|
@ -389,6 +391,7 @@ public final class ChatPanelInterfaceInteraction {
|
|||
self.hideTranslationPanel = hideTranslationPanel
|
||||
self.openPremiumGift = openPremiumGift
|
||||
self.openPremiumRequiredForMessaging = openPremiumRequiredForMessaging
|
||||
self.openBoostToUnrestrict = openBoostToUnrestrict
|
||||
self.updateHistoryFilter = updateHistoryFilter
|
||||
self.requestLayout = requestLayout
|
||||
|
||||
|
|
@ -505,6 +508,7 @@ public final class ChatPanelInterfaceInteraction {
|
|||
}, hideTranslationPanel: {
|
||||
}, openPremiumGift: {
|
||||
}, openPremiumRequiredForMessaging: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, requestLayout: { _ in
|
||||
}, chatController: {
|
||||
|
|
|
|||
|
|
@ -183,9 +183,6 @@ public final class MultilineTextWithEntitiesComponent: Component {
|
|||
}
|
||||
}
|
||||
|
||||
let size = self.textNode.updateLayout(availableSize)
|
||||
self.textNode.frame = CGRect(origin: .zero, size: size)
|
||||
|
||||
self.textNode.visibility = true
|
||||
if let context = component.context, let animationCache = component.animationCache, let animationRenderer = component.animationRenderer, let placeholderColor = component.placeholderColor {
|
||||
self.textNode.arguments = TextNodeWithEntities.Arguments(
|
||||
|
|
@ -197,6 +194,9 @@ public final class MultilineTextWithEntitiesComponent: Component {
|
|||
)
|
||||
}
|
||||
|
||||
let size = self.textNode.updateLayout(availableSize)
|
||||
self.textNode.frame = CGRect(origin: .zero, size: size)
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -589,7 +589,15 @@ public class ContactsController: ViewController {
|
|||
public func requestDeleteContacts(peerIds: [EnginePeer.Id]) {
|
||||
let actionSheet = ActionSheetController(presentationData: self.presentationData)
|
||||
var items: [ActionSheetItem] = []
|
||||
items.append(ActionSheetButtonItem(title: self.presentationData.strings.ContactList_DeleteConfirmation(Int32(peerIds.count)), color: .destructive, action: { [weak self, weak actionSheet] in
|
||||
|
||||
let actionTitle: String
|
||||
if peerIds.count > 1 {
|
||||
actionTitle = self.presentationData.strings.ContactList_DeleteConfirmation(Int32(peerIds.count))
|
||||
} else {
|
||||
actionTitle = self.presentationData.strings.ContactList_DeleteConfirmationSingle
|
||||
}
|
||||
|
||||
items.append(ActionSheetButtonItem(title: actionTitle, color: .destructive, action: { [weak self, weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
|
||||
guard let self else {
|
||||
|
|
|
|||
|
|
@ -1115,6 +1115,7 @@ public class StickerPickerScreen: ViewController {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1169,6 +1170,7 @@ public class StickerPickerScreen: ViewController {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1199,6 +1201,7 @@ public class StickerPickerScreen: ViewController {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1440,6 +1443,7 @@ public class StickerPickerScreen: ViewController {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1470,6 +1474,7 @@ public class StickerPickerScreen: ViewController {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public final class ItemListStickerPackItem: ListViewItem, ItemListItem {
|
|||
let editing: ItemListStickerPackItemEditing
|
||||
let enabled: Bool
|
||||
let playAnimatedStickers: Bool
|
||||
let style: ItemListStyle
|
||||
public let sectionId: ItemListSectionId
|
||||
let action: (() -> Void)?
|
||||
let setPackIdWithRevealedOptions: (ItemCollectionId?, ItemCollectionId?) -> Void
|
||||
|
|
@ -55,7 +56,7 @@ public final class ItemListStickerPackItem: ListViewItem, ItemListItem {
|
|||
let removePack: () -> Void
|
||||
let toggleSelected: () -> Void
|
||||
|
||||
public init(presentationData: ItemListPresentationData, context: AccountContext, packInfo: StickerPackCollectionInfo, itemCount: String, topItem: StickerPackItem?, unread: Bool, control: ItemListStickerPackItemControl, editing: ItemListStickerPackItemEditing, enabled: Bool, playAnimatedStickers: Bool, sectionId: ItemListSectionId, action: (() -> Void)?, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping () -> Void, removePack: @escaping () -> Void, toggleSelected: @escaping () -> Void) {
|
||||
public init(presentationData: ItemListPresentationData, context: AccountContext, packInfo: StickerPackCollectionInfo, itemCount: String, topItem: StickerPackItem?, unread: Bool, control: ItemListStickerPackItemControl, editing: ItemListStickerPackItemEditing, enabled: Bool, playAnimatedStickers: Bool, style: ItemListStyle = .blocks, sectionId: ItemListSectionId, action: (() -> Void)?, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping () -> Void, removePack: @escaping () -> Void, toggleSelected: @escaping () -> Void) {
|
||||
self.presentationData = presentationData
|
||||
self.context = context
|
||||
self.packInfo = packInfo
|
||||
|
|
@ -66,6 +67,7 @@ public final class ItemListStickerPackItem: ListViewItem, ItemListItem {
|
|||
self.editing = editing
|
||||
self.enabled = enabled
|
||||
self.playAnimatedStickers = playAnimatedStickers
|
||||
self.style = style
|
||||
self.sectionId = sectionId
|
||||
self.action = action
|
||||
self.setPackIdWithRevealedOptions = setPackIdWithRevealedOptions
|
||||
|
|
@ -410,8 +412,20 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
|||
let verticalInset: CGFloat = 11.0
|
||||
let titleSpacing: CGFloat = 2.0
|
||||
|
||||
let insets = itemListNeighborsGroupedInsets(neighbors, params)
|
||||
let separatorHeight = UIScreenPixel
|
||||
let insets: UIEdgeInsets
|
||||
let itemBackgroundColor: UIColor
|
||||
let itemSeparatorColor: UIColor
|
||||
switch item.style {
|
||||
case .plain:
|
||||
itemBackgroundColor = item.presentationData.theme.list.plainBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemPlainSeparatorColor
|
||||
insets = itemListNeighborsPlainInsets(neighbors)
|
||||
case .blocks:
|
||||
itemBackgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemBlocksSeparatorColor
|
||||
insets = itemListNeighborsGroupedInsets(neighbors, params)
|
||||
}
|
||||
|
||||
var editableControlSizeAndApply: (CGFloat, (CGFloat) -> ItemListEditableControlNode)?
|
||||
var reorderControlSizeAndApply: (CGFloat, (CGFloat, Bool, ContainedViewLayoutTransition) -> ItemListEditableReorderControlNode)?
|
||||
|
|
@ -543,9 +557,9 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
|||
}
|
||||
|
||||
if let _ = updatedTheme {
|
||||
strongSelf.topStripeNode.backgroundColor = item.presentationData.theme.list.itemBlocksSeparatorColor
|
||||
strongSelf.bottomStripeNode.backgroundColor = item.presentationData.theme.list.itemBlocksSeparatorColor
|
||||
strongSelf.backgroundNode.backgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
|
||||
strongSelf.topStripeNode.backgroundColor = itemSeparatorColor
|
||||
strongSelf.bottomStripeNode.backgroundColor = itemSeparatorColor
|
||||
strongSelf.backgroundNode.backgroundColor = itemBackgroundColor
|
||||
strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -652,7 +652,7 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
|
|||
let slowModeTimeout = state.modifiedSlowmodeTimeout ?? (cachedData.slowModeTimeout ?? 0)
|
||||
|
||||
if !canSendText || !canSendMedia || slowModeTimeout > 0 {
|
||||
let unrestrictBoosters = state.modifiedUnrestrictBoosters ?? (cachedData.boostsUnrestrict ?? 0)
|
||||
let unrestrictBoosters = state.modifiedUnrestrictBoosters ?? (cachedData.boostsToUnrestrict ?? 0)
|
||||
let unrestrictEnabled = unrestrictBoosters > 0
|
||||
|
||||
entries.append(.unrestrictBoostersSwitch(presentationData.theme, presentationData.strings.GroupInfo_Permissions_DontRestrictBoosters, unrestrictEnabled))
|
||||
|
|
@ -780,6 +780,9 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
|||
let updateDefaultRightsDisposable = MetaDisposable()
|
||||
actionsDisposable.add(updateDefaultRightsDisposable)
|
||||
|
||||
let updateUnrestrictBoostersDisposable = MetaDisposable()
|
||||
actionsDisposable.add(updateUnrestrictBoostersDisposable)
|
||||
|
||||
let peerView = Promise<PeerView>()
|
||||
peerView.set(sourcePeerId.get()
|
||||
|> mapToSignal(context.account.viewTracker.peerView))
|
||||
|
|
@ -1144,6 +1147,12 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
|||
return state
|
||||
}
|
||||
|
||||
let _ = (peerView.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { view in
|
||||
updateUnrestrictBoostersDisposable.set((context.engine.peers.updateChannelBoostsToUnlockRestrictions(peerId: view.peerId, boosts: value)
|
||||
|> deliverOnMainQueue).start())
|
||||
})
|
||||
}, toggleIsOptionExpanded: { flags in
|
||||
updateState { state in
|
||||
var state = state
|
||||
|
|
|
|||
|
|
@ -231,21 +231,7 @@ private final class PageIndicatorView: UIView {
|
|||
private func updateDotPosition(currentPage: Int, animated: Bool) {
|
||||
let duration = animated ? self.animationDuration : 0
|
||||
|
||||
if !animated {
|
||||
if currentPage == 0 {
|
||||
let x = -self.scrollView.contentInset.left
|
||||
self.moveScrollView(x: x)
|
||||
} else {
|
||||
for _ in 0 ..< currentPage {
|
||||
let x = self.scrollView.contentOffset.x + self.itemSize
|
||||
self.moveScrollView(x: x, duration: duration)
|
||||
}
|
||||
if currentPage == self.pageCount - 1 {
|
||||
let x = self.scrollView.contentSize.width - self.scrollView.bounds.width + self.scrollView.contentInset.right
|
||||
self.moveScrollView(x: x, duration: duration)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let action: (Int, Double) -> Void = { currentPage, duration in
|
||||
if currentPage == 0 {
|
||||
let x = -self.scrollView.contentInset.left
|
||||
self.moveScrollView(x: x, duration: duration)
|
||||
|
|
@ -260,6 +246,18 @@ private final class PageIndicatorView: UIView {
|
|||
self.moveScrollView(x: x, duration: duration)
|
||||
}
|
||||
}
|
||||
|
||||
if !animated {
|
||||
if currentPage == 0 {
|
||||
action(currentPage, 0)
|
||||
} else {
|
||||
for i in 0 ..< currentPage {
|
||||
action(i, 0)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
action(currentPage, duration)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateDotSize(currentPage: Int, animated: Bool) {
|
||||
|
|
|
|||
|
|
@ -466,6 +466,8 @@ private final class SheetContent: CombinedComponent {
|
|||
|
||||
final class State: ComponentState {
|
||||
var cachedChevronImage: (UIImage, PresentationTheme)?
|
||||
var cachedIconImage: UIImage?
|
||||
|
||||
private(set) var peer: EnginePeer?
|
||||
private(set) var memberPeer: EnginePeer?
|
||||
|
||||
|
|
@ -511,6 +513,10 @@ private final class SheetContent: CombinedComponent {
|
|||
}
|
||||
|
||||
static var body: Body {
|
||||
let iconBackground = Child(Image.self)
|
||||
let icon = Child(BundleIconComponent.self)
|
||||
//let icon = Child(LottieComponent.self)
|
||||
|
||||
let peerShortcut = Child(Button.self)
|
||||
let text = Child(BalancedTextComponent.self)
|
||||
let alternateText = Child(List<Empty>.self)
|
||||
|
|
@ -658,7 +664,7 @@ private final class SheetContent: CombinedComponent {
|
|||
}
|
||||
isCurrent = true
|
||||
case let .unrestrict(unrestrictCount):
|
||||
textString = "Boost the group \(unrestrictCount) times to remove messaging restrictions. Your boosts will help \(peerName) to unlock new features."
|
||||
textString = "Boost the group **\(unrestrictCount)** times to remove messaging restrictions. Your boosts will help **\(peerName)** to unlock new features."
|
||||
isCurrent = true
|
||||
default:
|
||||
if let remaining {
|
||||
|
|
@ -674,7 +680,7 @@ private final class SheetContent: CombinedComponent {
|
|||
isCurrent = mode == .current
|
||||
}
|
||||
case .features:
|
||||
textString = ""
|
||||
textString = "By gaining **boosts**, your group reaches higher levels and unlocks more features."
|
||||
}
|
||||
|
||||
let defaultTitle = strings.ChannelBoost_Level("\(level)").string
|
||||
|
|
@ -733,7 +739,48 @@ private final class SheetContent: CombinedComponent {
|
|||
}
|
||||
|
||||
if case .features = component.mode {
|
||||
contentSize.height += 17.0
|
||||
contentSize.height -= 14.0
|
||||
|
||||
let iconSize = CGSize(width: 90.0, height: 90.0)
|
||||
let gradientImage: UIImage
|
||||
if let current = state.cachedIconImage {
|
||||
gradientImage = current
|
||||
} else {
|
||||
gradientImage = generateFilledCircleImage(diameter: iconSize.width, color: theme.actionSheet.controlAccentColor)!
|
||||
context.state.cachedIconImage = gradientImage
|
||||
}
|
||||
|
||||
let iconBackground = iconBackground.update(
|
||||
component: Image(image: gradientImage),
|
||||
availableSize: iconSize,
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(iconBackground
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + iconBackground.size.height / 2.0))
|
||||
)
|
||||
|
||||
let icon = icon.update(
|
||||
component: BundleIconComponent(
|
||||
name: "Premium/BoostLarge",
|
||||
tintColor: .white
|
||||
),
|
||||
availableSize: CGSize(width: 90.0, height: 90.0),
|
||||
transition: .immediate
|
||||
)
|
||||
// let icon = icon.update(
|
||||
// component: LottieComponent(
|
||||
// content: LottieComponent.AppBundleContent(name: iconName),
|
||||
// playOnce: state.playOnce
|
||||
// ),
|
||||
// availableSize: CGSize(width: 70, height: 70),
|
||||
// transition: .immediate
|
||||
// )
|
||||
|
||||
context.add(icon
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + iconBackground.size.height / 2.0))
|
||||
)
|
||||
contentSize.height += iconSize.height
|
||||
contentSize.height += 52.0
|
||||
} else {
|
||||
let limit = limit.update(
|
||||
component: PremiumLimitDisplayComponent(
|
||||
|
|
@ -760,83 +807,83 @@ private final class SheetContent: CombinedComponent {
|
|||
)
|
||||
|
||||
contentSize.height += limit.size.height + 23.0
|
||||
}
|
||||
|
||||
if myBoostCount > 0 {
|
||||
let alternateTitle = isCurrent ? strings.ChannelBoost_YouBoostedChannelText(peerName).string : strings.ChannelBoost_YouBoostedOtherChannelText
|
||||
|
||||
if myBoostCount > 0 {
|
||||
let alternateTitle = isCurrent ? strings.ChannelBoost_YouBoostedChannelText(peerName).string : strings.ChannelBoost_YouBoostedOtherChannelText
|
||||
|
||||
var alternateBadge: String?
|
||||
if myBoostCount > 1 {
|
||||
alternateBadge = "X\(myBoostCount)"
|
||||
}
|
||||
|
||||
let alternateText = alternateText.update(
|
||||
component: List(
|
||||
[
|
||||
AnyComponentWithIdentity(
|
||||
id: "title",
|
||||
component: AnyComponent(
|
||||
BoostedTitleContent(text: NSAttributedString(string: alternateTitle, font: Font.semibold(15.0), textColor: textColor), badge: alternateBadge)
|
||||
)
|
||||
),
|
||||
AnyComponentWithIdentity(
|
||||
id: "text",
|
||||
component: AnyComponent(
|
||||
BalancedTextComponent(
|
||||
text: .markdown(text: textString, attributes: markdownAttributes),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.1
|
||||
)
|
||||
var alternateBadge: String?
|
||||
if myBoostCount > 1 {
|
||||
alternateBadge = "X\(myBoostCount)"
|
||||
}
|
||||
|
||||
let alternateText = alternateText.update(
|
||||
component: List(
|
||||
[
|
||||
AnyComponentWithIdentity(
|
||||
id: "title",
|
||||
component: AnyComponent(
|
||||
BoostedTitleContent(text: NSAttributedString(string: alternateTitle, font: Font.semibold(15.0), textColor: textColor), badge: alternateBadge)
|
||||
)
|
||||
),
|
||||
AnyComponentWithIdentity(
|
||||
id: "text",
|
||||
component: AnyComponent(
|
||||
BalancedTextComponent(
|
||||
text: .markdown(text: textString, attributes: markdownAttributes),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.1
|
||||
)
|
||||
)
|
||||
],
|
||||
centerAlignment: true
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(alternateText
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + alternateText.size.height / 2.0))
|
||||
.appear(Transition.Appear({ _, view, transition in
|
||||
transition.animatePosition(view: view, from: CGPoint(x: 0.0, y: 64.0), to: .zero, additive: true)
|
||||
transition.animateAlpha(view: view, from: 0.0, to: 1.0)
|
||||
)
|
||||
],
|
||||
centerAlignment: true
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(alternateText
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + alternateText.size.height / 2.0))
|
||||
.appear(Transition.Appear({ _, view, transition in
|
||||
transition.animatePosition(view: view, from: CGPoint(x: 0.0, y: 64.0), to: .zero, additive: true)
|
||||
transition.animateAlpha(view: view, from: 0.0, to: 1.0)
|
||||
}))
|
||||
.disappear(Transition.Disappear({ view, transition, completion in
|
||||
view.superview?.sendSubviewToBack(view)
|
||||
transition.animatePosition(view: view, from: .zero, to: CGPoint(x: 0.0, y: -64.0), additive: true)
|
||||
transition.setAlpha(view: view, alpha: 0.0, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
}))
|
||||
.disappear(Transition.Disappear({ view, transition, completion in
|
||||
view.superview?.sendSubviewToBack(view)
|
||||
transition.animatePosition(view: view, from: .zero, to: CGPoint(x: 0.0, y: -64.0), additive: true)
|
||||
transition.setAlpha(view: view, alpha: 0.0, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
}))
|
||||
)
|
||||
contentSize.height += alternateText.size.height + 13.0
|
||||
} else {
|
||||
let text = text.update(
|
||||
component: BalancedTextComponent(
|
||||
text: .markdown(text: textString, attributes: markdownAttributes),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(text
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + text.size.height / 2.0))
|
||||
.appear(Transition.Appear({ _, view, transition in
|
||||
transition.animatePosition(view: view, from: CGPoint(x: 0.0, y: 64.0), to: .zero, additive: true)
|
||||
transition.animateAlpha(view: view, from: 0.0, to: 1.0)
|
||||
)
|
||||
contentSize.height += alternateText.size.height + 20.0
|
||||
} else {
|
||||
let text = text.update(
|
||||
component: BalancedTextComponent(
|
||||
text: .markdown(text: textString, attributes: markdownAttributes),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(text
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + text.size.height / 2.0))
|
||||
.appear(Transition.Appear({ _, view, transition in
|
||||
transition.animatePosition(view: view, from: CGPoint(x: 0.0, y: 64.0), to: .zero, additive: true)
|
||||
transition.animateAlpha(view: view, from: 0.0, to: 1.0)
|
||||
}))
|
||||
.disappear(Transition.Disappear({ view, transition, completion in
|
||||
view.superview?.sendSubviewToBack(view)
|
||||
transition.animatePosition(view: view, from: .zero, to: CGPoint(x: 0.0, y: -64.0), additive: true)
|
||||
transition.setAlpha(view: view, alpha: 0.0, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
}))
|
||||
.disappear(Transition.Disappear({ view, transition, completion in
|
||||
view.superview?.sendSubviewToBack(view)
|
||||
transition.animatePosition(view: view, from: .zero, to: CGPoint(x: 0.0, y: -64.0), additive: true)
|
||||
transition.setAlpha(view: view, alpha: 0.0, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
}))
|
||||
)
|
||||
contentSize.height += text.size.height + 13.0
|
||||
}
|
||||
)
|
||||
contentSize.height += text.size.height + 20.0
|
||||
}
|
||||
|
||||
if case .owner = component.mode, let status = component.status {
|
||||
|
|
@ -886,7 +933,6 @@ private final class SheetContent: CombinedComponent {
|
|||
iconPosition: .left,
|
||||
action: {
|
||||
component.boost()
|
||||
component.dismiss()
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: (context.availableSize.width - 8.0 - sideInset * 2.0) / 2.0, height: 50.0),
|
||||
|
|
@ -1296,6 +1342,8 @@ private final class BoostLevelsContainerComponent: CombinedComponent {
|
|||
)
|
||||
|
||||
let titleString: String
|
||||
var titleFont = Font.semibold(17.0)
|
||||
|
||||
switch component.mode {
|
||||
case let .owner(subject):
|
||||
if let status = component.status, let _ = status.nextLevelBoosts {
|
||||
|
|
@ -1352,12 +1400,13 @@ private final class BoostLevelsContainerComponent: CombinedComponent {
|
|||
}
|
||||
case .features:
|
||||
//TODO:localize
|
||||
titleString = "Features"
|
||||
titleString = "Additional Features"
|
||||
titleFont = Font.semibold(20.0)
|
||||
}
|
||||
|
||||
|
||||
let title = title.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: titleString, font: Font.semibold(17.0), textColor: theme.rootController.navigationBar.primaryTextColor)),
|
||||
text: .plain(NSAttributedString(string: titleString, font: titleFont, textColor: theme.rootController.navigationBar.primaryTextColor)),
|
||||
horizontalAlignment: .center,
|
||||
truncationType: .end,
|
||||
maximumNumberOfLines: 1
|
||||
|
|
@ -1366,7 +1415,29 @@ private final class BoostLevelsContainerComponent: CombinedComponent {
|
|||
transition: context.transition
|
||||
)
|
||||
|
||||
let topPanelAlpha: CGFloat = min(30.0, state.topContentOffset) / 30.0
|
||||
let topPanelAlpha: CGFloat
|
||||
let titleOriginY: CGFloat
|
||||
let titleScale: CGFloat
|
||||
if case .features = component.mode {
|
||||
if state.topContentOffset > 78.0 {
|
||||
topPanelAlpha = min(30.0, state.topContentOffset - 78.0) / 30.0
|
||||
} else {
|
||||
topPanelAlpha = 0.0
|
||||
}
|
||||
|
||||
let titleTopOriginY = topPanel.size.height / 2.0
|
||||
let titleBottomOriginY: CGFloat = 146.0
|
||||
let titleOriginDelta = titleTopOriginY - titleBottomOriginY
|
||||
|
||||
let fraction = min(1.0, state.topContentOffset / abs(titleOriginDelta))
|
||||
titleOriginY = titleBottomOriginY + fraction * titleOriginDelta
|
||||
titleScale = 1.0 - max(0.0, fraction * 0.2)
|
||||
} else {
|
||||
topPanelAlpha = min(30.0, state.topContentOffset) / 30.0
|
||||
titleOriginY = topPanel.size.height / 2.0
|
||||
titleScale = 1.0
|
||||
}
|
||||
|
||||
context.add(topPanel
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: topPanel.size.height / 2.0))
|
||||
.opacity(topPanelAlpha)
|
||||
|
|
@ -1376,7 +1447,8 @@ private final class BoostLevelsContainerComponent: CombinedComponent {
|
|||
.opacity(topPanelAlpha)
|
||||
)
|
||||
context.add(title
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: topPanel.size.height / 2.0))
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: titleOriginY))
|
||||
.scale(titleScale)
|
||||
)
|
||||
|
||||
if let openStats = component.openStats {
|
||||
|
|
@ -1615,6 +1687,9 @@ public class PremiumBoostLevelsScreen: ViewController {
|
|||
|
||||
private var dismissOffset: CGFloat?
|
||||
func containerLayoutUpdated(layout: ContainerViewLayout, transition: Transition) {
|
||||
guard !self.isDismissing else {
|
||||
return
|
||||
}
|
||||
self.currentLayout = layout
|
||||
|
||||
self.dim.frame = CGRect(origin: CGPoint(x: 0.0, y: -layout.size.height), size: CGSize(width: layout.size.width, height: layout.size.height * 3.0))
|
||||
|
|
@ -1725,15 +1800,17 @@ public class PremiumBoostLevelsScreen: ViewController {
|
|||
|
||||
controller.dismiss(animated: true)
|
||||
|
||||
let boostController = PremiumBoostLevelsScreen(
|
||||
context: controller.context,
|
||||
peerId: controller.peerId,
|
||||
mode: .user(mode: .current),
|
||||
status: controller.status,
|
||||
myBoostStatus: nil,
|
||||
forceDark: controller.forceDark
|
||||
)
|
||||
navigationController.pushViewController(boostController, animated: true)
|
||||
Queue.mainQueue().justDispatch {
|
||||
let boostController = PremiumBoostLevelsScreen(
|
||||
context: controller.context,
|
||||
peerId: controller.peerId,
|
||||
mode: .user(mode: .current),
|
||||
status: controller.status,
|
||||
myBoostStatus: nil,
|
||||
forceDark: controller.forceDark
|
||||
)
|
||||
navigationController.pushViewController(boostController, animated: true)
|
||||
}
|
||||
},
|
||||
copyLink: { [weak self, weak controller] link in
|
||||
guard let self else {
|
||||
|
|
|
|||
|
|
@ -317,12 +317,6 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
|||
|
||||
if !component.isCompleted {
|
||||
if let products = component.products {
|
||||
let gradientColors: [UIColor] = [
|
||||
UIColor(rgb: 0x8e77ff),
|
||||
UIColor(rgb: 0x9a6fff),
|
||||
UIColor(rgb: 0xb36eee)
|
||||
]
|
||||
|
||||
let shortestOptionPrice: (Int64, NSDecimalNumber)
|
||||
if let product = products.last {
|
||||
shortestOptionPrice = (Int64(Float(product.storeProduct.priceCurrencyAndAmount.amount) / Float(product.months)), product.storeProduct.priceValue.dividing(by: NSDecimalNumber(value: product.months)))
|
||||
|
|
@ -352,14 +346,20 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
|||
var accessibilitySubtitle = ""
|
||||
var pricePerMonth = environment.strings.Premium_PricePerMonth(product.storeProduct.pricePerMonth(Int(product.months))).string
|
||||
|
||||
var labelPrice = pricePerMonth
|
||||
if component.peers.count > 1 {
|
||||
subtitle = "\(product.storeProduct.price) x \(component.peers.count)"
|
||||
pricePerMonth = product.storeProduct.multipliedPrice(count: component.peers.count)
|
||||
|
||||
subtitle = ""
|
||||
labelPrice = "\(product.storeProduct.price) x \(component.peers.count)"
|
||||
} else {
|
||||
if discountValue > 0 {
|
||||
subtitle = "**\(defaultPrice)** \(product.price)"
|
||||
accessibilitySubtitle = product.price
|
||||
}
|
||||
|
||||
subtitle = ""
|
||||
labelPrice = product.price
|
||||
}
|
||||
|
||||
items.append(SectionGroupComponent.Item(
|
||||
|
|
@ -369,13 +369,13 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
|||
PremiumOptionComponent(
|
||||
title: giftTitle,
|
||||
subtitle: subtitle,
|
||||
labelPrice: pricePerMonth,
|
||||
labelPrice: labelPrice,
|
||||
discount: discount,
|
||||
multiple: component.peers.count > 1,
|
||||
selected: product.id == component.selectedProductId,
|
||||
primaryTextColor: textColor,
|
||||
secondaryTextColor: subtitleColor,
|
||||
accentColor: gradientColors[i],
|
||||
accentColor: environment.theme.list.itemAccentColor,
|
||||
checkForegroundColor: environment.theme.list.itemCheckColors.foregroundColor,
|
||||
checkBorderColor: environment.theme.list.itemCheckColors.strokeColor
|
||||
)
|
||||
|
|
|
|||
|
|
@ -643,9 +643,9 @@ public enum PremiumPerk: CaseIterable {
|
|||
case .messageTags:
|
||||
return "Premium/Perk/MessageTags"
|
||||
case .lastSeen:
|
||||
return "Premium/Perk/Wallpapers"
|
||||
return "Premium/Perk/LastSeen"
|
||||
case .messagePrivacy:
|
||||
return "Premium/Perk/MessageTags"
|
||||
return "Premium/Perk/MessagePrivacy"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -864,7 +864,6 @@ final class PremiumOptionComponent: CombinedComponent {
|
|||
transition: context.transition
|
||||
)
|
||||
|
||||
var discountOffset: CGFloat = 0.0
|
||||
let discountSize: CGSize
|
||||
if !component.discount.isEmpty {
|
||||
let discount = discount.update(
|
||||
|
|
@ -872,7 +871,7 @@ final class PremiumOptionComponent: CombinedComponent {
|
|||
text: .plain(
|
||||
NSAttributedString(
|
||||
string: component.discount,
|
||||
font: Font.with(size: component.multiple ? 13.0 : 14.0, design: .round, weight: .semibold, traits: []),
|
||||
font: Font.with(size: 14.0, design: .round, weight: .semibold, traits: []),
|
||||
textColor: .white
|
||||
)
|
||||
),
|
||||
|
|
@ -893,13 +892,7 @@ final class PremiumOptionComponent: CombinedComponent {
|
|||
transition: context.transition
|
||||
)
|
||||
|
||||
let discountPosition: CGPoint
|
||||
if component.multiple {
|
||||
discountOffset = discountSize.width + 6.0
|
||||
discountPosition = CGPoint(x: insets.left + discountSize.width / 2.0, y: insets.top + title.size.height + discountSize.height / 2.0)
|
||||
} else {
|
||||
discountPosition = CGPoint(x: insets.left + title.size.width + 6.0 + discountSize.width / 2.0, y: insets.top + title.size.height / 2.0)
|
||||
}
|
||||
let discountPosition = CGPoint(x: insets.left + title.size.width + 6.0 + discountSize.width / 2.0, y: insets.top + title.size.height / 2.0)
|
||||
|
||||
context.add(discountBackground
|
||||
.position(discountPosition)
|
||||
|
|
@ -938,7 +931,7 @@ final class PremiumOptionComponent: CombinedComponent {
|
|||
transition: context.transition
|
||||
)
|
||||
context.add(subtitle
|
||||
.position(CGPoint(x: insets.left + subtitle.size.width / 2.0 + discountOffset, y: insets.top + title.size.height + spacing + subtitle.size.height / 2.0))
|
||||
.position(CGPoint(x: insets.left + subtitle.size.width / 2.0, y: insets.top + title.size.height + spacing + subtitle.size.height / 2.0))
|
||||
)
|
||||
subtitleSize = subtitle.size
|
||||
|
||||
|
|
@ -1894,11 +1887,6 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||
let layoutOptions = {
|
||||
if let products = state.products, products.count > 1, state.isPremium == false || (!context.component.justBought && state.canUpgrade) {
|
||||
var optionsItems: [SectionGroupComponent.Item] = []
|
||||
let gradientColors: [UIColor] = [
|
||||
UIColor(rgb: 0x8e77ff),
|
||||
UIColor(rgb: 0x9a6fff),
|
||||
UIColor(rgb: 0xb36eee)
|
||||
]
|
||||
|
||||
let shortestOptionPrice: (Int64, NSDecimalNumber)
|
||||
if let product = products.first(where: { $0.id.hasSuffix(".monthly") }) {
|
||||
|
|
@ -1967,7 +1955,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||
selected: !product.isCurrent && product.id == state.selectedProductId,
|
||||
primaryTextColor: textColor,
|
||||
secondaryTextColor: subtitleColor,
|
||||
accentColor: gradientColors[i],
|
||||
accentColor: environment.theme.list.itemAccentColor,
|
||||
checkForegroundColor: environment.theme.list.itemCheckColors.foregroundColor,
|
||||
checkBorderColor: environment.theme.list.itemCheckColors.strokeColor
|
||||
)
|
||||
|
|
|
|||
|
|
@ -771,7 +771,7 @@ public class PremiumLimitsListScreen: ViewController {
|
|||
position: .top,
|
||||
model: .island,
|
||||
videoFile: configuration.videos["last_seen"],
|
||||
decoration: .tag
|
||||
decoration: .badgeStars
|
||||
)),
|
||||
title: strings.Premium_LastSeen,
|
||||
text: strings.Premium_LastSeenInfo,
|
||||
|
|
@ -790,7 +790,7 @@ public class PremiumLimitsListScreen: ViewController {
|
|||
position: .top,
|
||||
model: .island,
|
||||
videoFile: configuration.videos["message_privacy"],
|
||||
decoration: .tag
|
||||
decoration: .swirlStars
|
||||
)),
|
||||
title: strings.Premium_MessagePrivacy,
|
||||
text: strings.Premium_MessagePrivacyInfo,
|
||||
|
|
|
|||
|
|
@ -582,7 +582,6 @@ final class StoriesPageComponent: CombinedComponent {
|
|||
let topPanel = Child(BlurredBackgroundComponent.self)
|
||||
let topSeparator = Child(Rectangle.self)
|
||||
let title = Child(MultilineTextComponent.self)
|
||||
let secondaryTitle = Child(MultilineTextComponent.self)
|
||||
|
||||
let resetScroll = ActionSlot<Void>()
|
||||
|
||||
|
|
@ -664,17 +663,6 @@ final class StoriesPageComponent: CombinedComponent {
|
|||
availableSize: context.availableSize,
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let secondaryTitle = secondaryTitle.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: strings.Premium_Stories_AdditionalTitle, font: Font.semibold(17.0), textColor: theme.rootController.navigationBar.primaryTextColor)),
|
||||
horizontalAlignment: .center,
|
||||
truncationType: .end,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: context.availableSize,
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let topPanelAlpha: CGFloat
|
||||
if state.topContentOffset > 78.0 {
|
||||
|
|
@ -699,23 +687,9 @@ final class StoriesPageComponent: CombinedComponent {
|
|||
let titleOriginY: CGFloat = titleBottomOriginY + fraction * titleOriginDelta
|
||||
let titleScale = 1.0 - max(0.0, fraction * 0.2)
|
||||
|
||||
let titleAlpha: CGFloat
|
||||
if fraction > 0.78 {
|
||||
titleAlpha = max(0.0, 1.0 - (fraction - 0.78) / 0.16)
|
||||
} else {
|
||||
titleAlpha = 1.0
|
||||
}
|
||||
let secondaryTitleAlpha: CGFloat = 1.0 - titleAlpha
|
||||
|
||||
context.add(title
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: titleOriginY))
|
||||
.scale(titleScale)
|
||||
.opacity(titleAlpha)
|
||||
)
|
||||
|
||||
context.add(secondaryTitle
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: titleOriginY))
|
||||
.opacity(secondaryTitleAlpha)
|
||||
)
|
||||
|
||||
return scroll.size
|
||||
|
|
|
|||
|
|
@ -1656,6 +1656,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1704,6 +1705,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
groupId: AnyHashable(info.id),
|
||||
title: info.title,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1762,6 +1764,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1793,6 +1796,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
|
|||
|
|
@ -510,7 +510,7 @@ private func namespaceForMode(_ mode: InstalledStickerPacksControllerMode) -> It
|
|||
return Namespaces.ItemCollection.CloudStickerPacks
|
||||
case .masks:
|
||||
return Namespaces.ItemCollection.CloudMaskPacks
|
||||
case .emoji, .groupEmoji:
|
||||
case .emoji:
|
||||
return Namespaces.ItemCollection.CloudEmojiPacks
|
||||
}
|
||||
}
|
||||
|
|
@ -574,11 +574,6 @@ private func installedStickerPacksControllerEntries(context: AccountContext, pre
|
|||
|
||||
entries.append(.suggestAnimatedEmoji(presentationData.strings.StickerPacksSettings_SuggestAnimatedEmoji, stickerSettings.suggestAnimatedEmoji))
|
||||
entries.append(.suggestAnimatedEmojiInfo(presentationData.theme, presentationData.strings.StickerPacksSettings_SuggestAnimatedEmojiInfo))
|
||||
case .groupEmoji:
|
||||
entries.append(.info(presentationData.theme, "All members will be able to use these emoji in the group, even if they don't have Telegram Premium.\n"))
|
||||
|
||||
//TODO:localize
|
||||
entries.append(.packsTitle(presentationData.theme, "CHOOSE EMOJI PACK".uppercased()))
|
||||
}
|
||||
|
||||
if let stickerPacksView = view.views[.itemCollectionInfos(namespaces: [namespaceForMode(mode)])] as? ItemCollectionInfosView {
|
||||
|
|
@ -624,27 +619,21 @@ private func installedStickerPacksControllerEntries(context: AccountContext, pre
|
|||
}
|
||||
}
|
||||
|
||||
if case .groupEmoji = mode {
|
||||
|
||||
} else {
|
||||
var markdownString: String
|
||||
switch mode {
|
||||
case .general, .modal:
|
||||
markdownString = presentationData.strings.StickerPacksSettings_ManagingHelp
|
||||
case .masks:
|
||||
markdownString = presentationData.strings.MaskStickerSettings_Info
|
||||
case .emoji:
|
||||
markdownString = presentationData.strings.EmojiStickerSettings_Info
|
||||
case .groupEmoji:
|
||||
markdownString = ""
|
||||
}
|
||||
let entities = generateTextEntities(markdownString, enabledTypes: [.mention])
|
||||
if let entity = entities.first {
|
||||
markdownString.insert(contentsOf: "]()", at: markdownString.index(markdownString.startIndex, offsetBy: entity.range.upperBound))
|
||||
markdownString.insert(contentsOf: "[", at: markdownString.index(markdownString.startIndex, offsetBy: entity.range.lowerBound))
|
||||
}
|
||||
entries.append(.packsInfo(presentationData.theme, markdownString))
|
||||
var markdownString: String
|
||||
switch mode {
|
||||
case .general, .modal:
|
||||
markdownString = presentationData.strings.StickerPacksSettings_ManagingHelp
|
||||
case .masks:
|
||||
markdownString = presentationData.strings.MaskStickerSettings_Info
|
||||
case .emoji:
|
||||
markdownString = presentationData.strings.EmojiStickerSettings_Info
|
||||
}
|
||||
let entities = generateTextEntities(markdownString, enabledTypes: [.mention])
|
||||
if let entity = entities.first {
|
||||
markdownString.insert(contentsOf: "]()", at: markdownString.index(markdownString.startIndex, offsetBy: entity.range.upperBound))
|
||||
markdownString.insert(contentsOf: "[", at: markdownString.index(markdownString.startIndex, offsetBy: entity.range.lowerBound))
|
||||
}
|
||||
entries.append(.packsInfo(presentationData.theme, markdownString))
|
||||
|
||||
return entries
|
||||
}
|
||||
|
|
@ -917,7 +906,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
|||
archivedPromise.set(.single(nil) |> then(context.engine.stickers.archivedStickerPacks(namespace: .masks) |> map(Optional.init)))
|
||||
quickReaction = .single(nil)
|
||||
emojiCount.set(.single(0))
|
||||
case .emoji, .groupEmoji:
|
||||
case .emoji:
|
||||
featured.set(.single([]))
|
||||
archivedPromise.set(.single(nil) |> then(context.engine.stickers.archivedStickerPacks(namespace: .emoji) |> map(Optional.init)))
|
||||
quickReaction = .single(nil)
|
||||
|
|
@ -1070,8 +1059,6 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
|||
} else {
|
||||
if case .modal = mode {
|
||||
rightNavigationButton = nil
|
||||
} else if case .groupEmoji = mode {
|
||||
rightNavigationButton = nil
|
||||
} else {
|
||||
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Edit), style: .regular, enabled: true, action: {
|
||||
updateState {
|
||||
|
|
@ -1093,9 +1080,6 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
|||
title = presentationData.strings.MaskStickerSettings_Title
|
||||
case .emoji:
|
||||
title = presentationData.strings.EmojiPacksSettings_Title
|
||||
case .groupEmoji:
|
||||
//TODO:localize
|
||||
title = "Group Emoji Pack"
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
|
||||
|
|
@ -1250,48 +1234,43 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
|||
packs.insert(packReference, at: 0)
|
||||
}
|
||||
if let mainStickerPack = mainStickerPack {
|
||||
//TODO:localize
|
||||
presentControllerImpl?(StickerPackScreen(context: context, mode: .settings, mainStickerPack: mainStickerPack, stickerPacks: [mainStickerPack], mainActionTitle: "Set as Group Emoji Pack", parentNavigationController: controller?.navigationController as? NavigationController, actionPerformed: { actions in
|
||||
if case .groupEmoji = mode {
|
||||
|
||||
} else {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
var animateInAsReplacement = false
|
||||
if let navigationController = navigationControllerImpl?() {
|
||||
for controller in navigationController.overlayControllers {
|
||||
if let controller = controller as? UndoOverlayController {
|
||||
controller.dismissWithCommitActionAndReplacementAnimation()
|
||||
animateInAsReplacement = true
|
||||
}
|
||||
presentControllerImpl?(StickerPackScreen(context: context, mode: .settings, mainStickerPack: mainStickerPack, stickerPacks: [mainStickerPack], parentNavigationController: controller?.navigationController as? NavigationController, actionPerformed: { actions in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
var animateInAsReplacement = false
|
||||
if let navigationController = navigationControllerImpl?() {
|
||||
for controller in navigationController.overlayControllers {
|
||||
if let controller = controller as? UndoOverlayController {
|
||||
controller.dismissWithCommitActionAndReplacementAnimation()
|
||||
animateInAsReplacement = true
|
||||
}
|
||||
}
|
||||
if let (info, items, action) = actions.first {
|
||||
switch action {
|
||||
case .add:
|
||||
navigationControllerImpl?()?.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: presentationData.strings.StickerPackActionInfo_AddedTitle, text: presentationData.strings.StickerPackActionInfo_AddedText(info.title).string, undo: false, info: info, topItem: items.first, context: context), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in
|
||||
return true
|
||||
}))
|
||||
case let .remove(positionInList):
|
||||
let removedTitle: String
|
||||
let removedText: String
|
||||
if info.id.namespace == Namespaces.ItemCollection.CloudEmojiPacks {
|
||||
removedTitle = presentationData.strings.EmojiPackActionInfo_RemovedTitle
|
||||
removedText = presentationData.strings.EmojiPackActionInfo_RemovedText(info.title).string
|
||||
} else if info.id.namespace == Namespaces.ItemCollection.CloudMaskPacks {
|
||||
removedTitle = presentationData.strings.MaskPackActionInfo_RemovedTitle
|
||||
removedText = presentationData.strings.MaskPackActionInfo_RemovedText(info.title).string
|
||||
} else {
|
||||
removedTitle = presentationData.strings.StickerPackActionInfo_RemovedTitle
|
||||
removedText = presentationData.strings.StickerPackActionInfo_RemovedText(info.title).string
|
||||
}
|
||||
|
||||
navigationControllerImpl?()?.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: removedTitle, text: removedText, undo: true, info: info, topItem: items.first, context: context), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { action in
|
||||
if case .undo = action {
|
||||
let _ = context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: positionInList).start()
|
||||
}
|
||||
return true
|
||||
}))
|
||||
}
|
||||
if let (info, items, action) = actions.first {
|
||||
switch action {
|
||||
case .add:
|
||||
navigationControllerImpl?()?.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: presentationData.strings.StickerPackActionInfo_AddedTitle, text: presentationData.strings.StickerPackActionInfo_AddedText(info.title).string, undo: false, info: info, topItem: items.first, context: context), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in
|
||||
return true
|
||||
}))
|
||||
case let .remove(positionInList):
|
||||
let removedTitle: String
|
||||
let removedText: String
|
||||
if info.id.namespace == Namespaces.ItemCollection.CloudEmojiPacks {
|
||||
removedTitle = presentationData.strings.EmojiPackActionInfo_RemovedTitle
|
||||
removedText = presentationData.strings.EmojiPackActionInfo_RemovedText(info.title).string
|
||||
} else if info.id.namespace == Namespaces.ItemCollection.CloudMaskPacks {
|
||||
removedTitle = presentationData.strings.MaskPackActionInfo_RemovedTitle
|
||||
removedText = presentationData.strings.MaskPackActionInfo_RemovedText(info.title).string
|
||||
} else {
|
||||
removedTitle = presentationData.strings.StickerPackActionInfo_RemovedTitle
|
||||
removedText = presentationData.strings.StickerPackActionInfo_RemovedText(info.title).string
|
||||
}
|
||||
|
||||
navigationControllerImpl?()?.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: removedTitle, text: removedText, undo: true, info: info, topItem: items.first, context: context), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { action in
|
||||
if case .undo = action {
|
||||
let _ = context.engine.stickers.addStickerPackInteractively(info: info, items: items, positionInList: positionInList).start()
|
||||
}
|
||||
return true
|
||||
}))
|
||||
}
|
||||
}
|
||||
}), nil)
|
||||
|
|
|
|||
|
|
@ -476,6 +476,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[508332649] = { return Api.Message.parse_message($0) }
|
||||
dict[-1868117372] = { return Api.Message.parse_messageEmpty($0) }
|
||||
dict[721967202] = { return Api.Message.parse_messageService($0) }
|
||||
dict[-872240531] = { return Api.MessageAction.parse_messageActionBoostApply($0) }
|
||||
dict[-988359047] = { return Api.MessageAction.parse_messageActionBotAllowed($0) }
|
||||
dict[-1781355374] = { return Api.MessageAction.parse_messageActionChannelCreate($0) }
|
||||
dict[-365344535] = { return Api.MessageAction.parse_messageActionChannelMigrateFrom($0) }
|
||||
|
|
|
|||
|
|
@ -664,6 +664,7 @@ public extension Api {
|
|||
}
|
||||
public extension Api {
|
||||
enum MessageAction: TypeConstructorDescription {
|
||||
case messageActionBoostApply(boosts: Int32)
|
||||
case messageActionBotAllowed(flags: Int32, domain: String?, app: Api.BotApp?)
|
||||
case messageActionChannelCreate(title: String)
|
||||
case messageActionChannelMigrateFrom(title: String, chatId: Int64)
|
||||
|
|
@ -708,6 +709,12 @@ public extension Api {
|
|||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .messageActionBoostApply(let boosts):
|
||||
if boxed {
|
||||
buffer.appendInt32(-872240531)
|
||||
}
|
||||
serializeInt32(boosts, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .messageActionBotAllowed(let flags, let domain, let app):
|
||||
if boxed {
|
||||
buffer.appendInt32(-988359047)
|
||||
|
|
@ -1032,6 +1039,8 @@ public extension Api {
|
|||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .messageActionBoostApply(let boosts):
|
||||
return ("messageActionBoostApply", [("boosts", boosts as Any)])
|
||||
case .messageActionBotAllowed(let flags, let domain, let app):
|
||||
return ("messageActionBotAllowed", [("flags", flags as Any), ("domain", domain as Any), ("app", app as Any)])
|
||||
case .messageActionChannelCreate(let title):
|
||||
|
|
@ -1117,6 +1126,17 @@ public extension Api {
|
|||
}
|
||||
}
|
||||
|
||||
public static func parse_messageActionBoostApply(_ reader: BufferReader) -> MessageAction? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.MessageAction.messageActionBoostApply(boosts: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageActionBotAllowed(_ reader: BufferReader) -> MessageAction? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
|
|||
}
|
||||
|
||||
switch action {
|
||||
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults:
|
||||
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply:
|
||||
break
|
||||
case let .messageActionChannelMigrateFrom(_, chatId):
|
||||
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId)))
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
|
|||
return TelegramMediaAction(action: .giveawayLaunched)
|
||||
case let .messageActionGiveawayResults(winners, unclaimed):
|
||||
return TelegramMediaAction(action: .giveawayResults(winners: winners, unclaimed: unclaimed))
|
||||
case let .messageActionBoostApply(boosts):
|
||||
return TelegramMediaAction(action: .boostsApplied(boosts: boosts))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -260,7 +260,8 @@ public final class CachedChannelData: CachedPeerData {
|
|||
public let membersHidden: EnginePeerCachedInfoItem<PeerMembersHidden>
|
||||
public let viewForumAsMessages: EnginePeerCachedInfoItem<Bool>
|
||||
public let wallpaper: TelegramWallpaper?
|
||||
public let boostsUnrestrict: Int32?
|
||||
public let boostsToUnrestrict: Int32?
|
||||
public let appliedBoosts: Int32?
|
||||
public let emojiPack: StickerPackCollectionInfo?
|
||||
|
||||
public let peerIds: Set<PeerId>
|
||||
|
|
@ -303,7 +304,8 @@ public final class CachedChannelData: CachedPeerData {
|
|||
self.membersHidden = .unknown
|
||||
self.viewForumAsMessages = .unknown
|
||||
self.wallpaper = nil
|
||||
self.boostsUnrestrict = nil
|
||||
self.boostsToUnrestrict = nil
|
||||
self.appliedBoosts = nil
|
||||
self.emojiPack = nil
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +341,8 @@ public final class CachedChannelData: CachedPeerData {
|
|||
membersHidden: EnginePeerCachedInfoItem<PeerMembersHidden>,
|
||||
viewForumAsMessages: EnginePeerCachedInfoItem<Bool>,
|
||||
wallpaper: TelegramWallpaper?,
|
||||
boostsUnrestrict: Int32?,
|
||||
boostsToUnrestrict: Int32?,
|
||||
appliedBoosts: Int32?,
|
||||
emojiPack: StickerPackCollectionInfo?
|
||||
) {
|
||||
self.isNotAccessible = isNotAccessible
|
||||
|
|
@ -373,7 +376,8 @@ public final class CachedChannelData: CachedPeerData {
|
|||
self.membersHidden = membersHidden
|
||||
self.viewForumAsMessages = viewForumAsMessages
|
||||
self.wallpaper = wallpaper
|
||||
self.boostsUnrestrict = boostsUnrestrict
|
||||
self.boostsToUnrestrict = boostsToUnrestrict
|
||||
self.appliedBoosts = appliedBoosts
|
||||
self.emojiPack = emojiPack
|
||||
|
||||
var peerIds = Set<PeerId>()
|
||||
|
|
@ -402,137 +406,141 @@ public final class CachedChannelData: CachedPeerData {
|
|||
}
|
||||
|
||||
public func withUpdatedIsNotAccessible(_ isNotAccessible: Bool) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedAbout(_ about: String?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedStickerPack(_ stickerPack: StickerPackCollectionInfo?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedMinAvailableMessageId(_ minAvailableMessageId: MessageId?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedMigrationReference(_ migrationReference: ChannelMigrationReference?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedLinkedDiscussionPeerId(_ linkedDiscussionPeerId: LinkedDiscussionPeerId) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedSlowModeTimeout(_ slowModeTimeout: Int32?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedSlowModeValidUntilTimestamp(_ slowModeValidUntilTimestamp: Int32?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedStatsDatacenterId(_ statsDatacenterId: Int32) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedInvitedBy(_ invitedBy: PeerId?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedInvitedOn(_ invitedOn: Int32?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedPhoto(_ photo: TelegramMediaImage?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedActiveCall(_ activeCall: ActiveCall?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedCallJoinPeerId(_ callJoinPeerId: PeerId?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedAutoremoveTimeout(_ autoremoveTimeout: CachedPeerAutoremoveTimeout) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedPendingSuggestions(_ pendingSuggestions: [String]) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedThemeEmoticon(_ themeEmoticon: String?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedInviteRequestsPending(_ inviteRequestsPending: Int32?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedSendAsPeerId(_ sendAsPeerId: PeerId?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedAllowedReactions(_ allowedReactions: EnginePeerCachedInfoItem<PeerAllowedReactions>) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedMembersHidden(_ membersHidden: EnginePeerCachedInfoItem<PeerMembersHidden>) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedViewForumAsMessages(_ viewForumAsMessages: EnginePeerCachedInfoItem<Bool>) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedWallpaper(_ wallpaper: TelegramWallpaper?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedBoostsUnrestrict(_ boostsUnrestrict: Int32?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: boostsUnrestrict, emojiPack: self.emojiPack)
|
||||
public func withUpdatedBoostsToUnrestrict(_ boostsToUnrestrict: Int32?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdateAppliedBoosts(_ appliedBoosts: Int32?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: appliedBoosts, emojiPack: self.emojiPack)
|
||||
}
|
||||
|
||||
public func withUpdatedEmojiPack(_ emojiPack: StickerPackCollectionInfo?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsUnrestrict: self.boostsUnrestrict, emojiPack: emojiPack)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: self.allowedReactions, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: emojiPack)
|
||||
}
|
||||
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.isNotAccessible = decoder.decodeInt32ForKey("isNotAccessible", orElse: 0) != 0
|
||||
self.flags = CachedChannelFlags(rawValue: decoder.decodeInt32ForKey("f", orElse: 0))
|
||||
|
|
@ -648,7 +656,9 @@ public final class CachedChannelData: CachedPeerData {
|
|||
}
|
||||
}
|
||||
|
||||
self.boostsUnrestrict = decoder.decodeOptionalInt32ForKey("bu")
|
||||
self.boostsToUnrestrict = decoder.decodeOptionalInt32ForKey("bu")
|
||||
|
||||
self.appliedBoosts = decoder.decodeOptionalInt32ForKey("ab")
|
||||
|
||||
if let emojiPack = decoder.decodeObjectForKey("ep", decoder: { StickerPackCollectionInfo(decoder: $0) }) as? StickerPackCollectionInfo {
|
||||
self.emojiPack = emojiPack
|
||||
|
|
@ -821,12 +831,18 @@ public final class CachedChannelData: CachedPeerData {
|
|||
encoder.encodeNil(forKey: "wp")
|
||||
}
|
||||
|
||||
if let boostsUnrestrict = self.boostsUnrestrict {
|
||||
encoder.encodeInt32(boostsUnrestrict, forKey: "bu")
|
||||
if let boostsToUnrestrict = self.boostsToUnrestrict {
|
||||
encoder.encodeInt32(boostsToUnrestrict, forKey: "bu")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "bu")
|
||||
}
|
||||
|
||||
if let appliedBoosts = self.appliedBoosts {
|
||||
encoder.encodeInt32(appliedBoosts, forKey: "ab")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "ab")
|
||||
}
|
||||
|
||||
if let emojiPack = self.emojiPack {
|
||||
encoder.encodeObject(emojiPack, forKey: "ep")
|
||||
} else {
|
||||
|
|
@ -958,12 +974,19 @@ public final class CachedChannelData: CachedPeerData {
|
|||
if other.viewForumAsMessages != self.viewForumAsMessages {
|
||||
return false
|
||||
}
|
||||
|
||||
if other.wallpaper != self.wallpaper {
|
||||
return false
|
||||
}
|
||||
if other.boostsUnrestrict != self.boostsUnrestrict {
|
||||
|
||||
if other.boostsToUnrestrict != self.boostsToUnrestrict {
|
||||
return false
|
||||
}
|
||||
|
||||
if other.appliedBoosts != self.appliedBoosts {
|
||||
return false
|
||||
}
|
||||
|
||||
if other.emojiPack != self.emojiPack {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
case giveawayLaunched
|
||||
case joinedChannel
|
||||
case giveawayResults(winners: Int32, unclaimed: Int32)
|
||||
case boostsApplied(boosts: Int32)
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
|
||||
|
|
@ -232,6 +233,8 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
self = .joinedChannel
|
||||
case 39:
|
||||
self = .giveawayResults(winners: decoder.decodeInt32ForKey("winners", orElse: 0), unclaimed: decoder.decodeInt32ForKey("unclaimed", orElse: 0))
|
||||
case 40:
|
||||
self = .boostsApplied(boosts: decoder.decodeInt32ForKey("boosts", orElse: 0))
|
||||
default:
|
||||
self = .unknown
|
||||
}
|
||||
|
|
@ -451,6 +454,9 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
encoder.encodeInt32(39, forKey: "_rawValue")
|
||||
encoder.encodeInt32(winners, forKey: "winners")
|
||||
encoder.encodeInt32(unclaimed, forKey: "unclaimed")
|
||||
case let .boostsApplied(boosts):
|
||||
encoder.encodeInt32(40, forKey: "_rawValue")
|
||||
encoder.encodeInt32(boosts, forKey: "boosts")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,3 +183,33 @@ func _internal_updateDefaultChannelMemberBannedRights(account: Account, peerId:
|
|||
|> switchToLatest
|
||||
}
|
||||
|
||||
func _internal_updateChannelBoostsToUnlockRestrictions(account: Account, peerId: PeerId, boosts: Int32) -> Signal<Never, NoError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Never, NoError> in
|
||||
guard let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) else {
|
||||
return .complete()
|
||||
}
|
||||
return account.network.request(Api.functions.channels.setBoostsToUnblockRestrictions(channel: inputChannel, boosts: boosts))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Never, NoError> in
|
||||
guard let result = result else {
|
||||
return .complete()
|
||||
}
|
||||
account.stateManager.addUpdates(result)
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData in
|
||||
if let cachedData = cachedData as? CachedChannelData {
|
||||
return cachedData.withUpdatedBoostsToUnrestrict(boosts)
|
||||
}
|
||||
return cachedData
|
||||
})
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
|> switchToLatest
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -352,6 +352,10 @@ public extension TelegramEngine {
|
|||
public func updateDefaultChannelMemberBannedRights(peerId: PeerId, rights: TelegramChatBannedRights) -> Signal<Never, NoError> {
|
||||
return _internal_updateDefaultChannelMemberBannedRights(account: self.account, peerId: peerId, rights: rights)
|
||||
}
|
||||
|
||||
public func updateChannelBoostsToUnlockRestrictions(peerId: PeerId, boosts: Int32) -> Signal<Never, NoError> {
|
||||
return _internal_updateChannelBoostsToUnlockRestrictions(account: self.account, peerId: peerId, boosts: boosts)
|
||||
}
|
||||
|
||||
public func createChannel(title: String, description: String?, username: String? = nil) -> Signal<PeerId, CreateChannelError> {
|
||||
return _internal_createChannel(account: self.account, title: title, description: description, username: username)
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||
}
|
||||
|
||||
switch fullChat {
|
||||
case let .channelFull(flags, flags2, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, _, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, _, inputCall, ttl, pendingSuggestions, groupcallDefaultJoinAs, themeEmoticon, requestsPending, _, defaultSendAs, allowedReactions, _, wallpaper, _, boostsUnrestrict, emojiSet):
|
||||
case let .channelFull(flags, flags2, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, _, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, _, inputCall, ttl, pendingSuggestions, groupcallDefaultJoinAs, themeEmoticon, requestsPending, _, defaultSendAs, allowedReactions, _, wallpaper, appliedBoosts, boostsUnrestrict, emojiSet):
|
||||
var channelFlags = CachedChannelFlags()
|
||||
if (flags & (1 << 3)) != 0 {
|
||||
channelFlags.insert(.canDisplayParticipants)
|
||||
|
|
@ -674,7 +674,8 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||
.withUpdatedMembersHidden(.known(PeerMembersHidden(value: membersHidden)))
|
||||
.withUpdatedViewForumAsMessages(.known(forumViewAsMessages))
|
||||
.withUpdatedWallpaper(wallpaper)
|
||||
.withUpdatedBoostsUnrestrict(boostsUnrestrict)
|
||||
.withUpdatedBoostsToUnrestrict(boostsUnrestrict)
|
||||
.withUpdateAppliedBoosts(appliedBoosts)
|
||||
.withUpdatedEmojiPack(emojiPack)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ public enum PresentationResourceKey: Int32 {
|
|||
case chatTitleLockIcon
|
||||
case chatTitleMuteIcon
|
||||
case chatPanelLockIcon
|
||||
case chatPanelBoostIcon
|
||||
|
||||
case chatBubbleVerticalLineIncomingImage
|
||||
case chatBubbleVerticalLineOutgoingImage
|
||||
|
|
|
|||
|
|
@ -84,6 +84,12 @@ public struct PresentationResourcesChat {
|
|||
})
|
||||
}
|
||||
|
||||
public static func chatPanelBoostIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatPanelBoostIcon.rawValue, { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Premium/BoostChannel"), color: theme.chat.inputPanel.panelControlAccentColor)
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatTitleMuteIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatTitleMuteIcon.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 9.0, height: 9.0), rotatedContext: { size, context in
|
||||
|
|
|
|||
|
|
@ -959,6 +959,25 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||
} else {
|
||||
attributedString = parseMarkdownIntoAttributedString(strings.Notification_GiveawayResults(winners), attributes: MarkdownAttributes(body: bodyAttributes, bold: boldAttributes, link: bodyAttributes, linkAttribute: { _ in return nil }))
|
||||
}
|
||||
case let .boostsApplied(boosts):
|
||||
if message.author?.id == accountPeerId {
|
||||
if boosts == 1 {
|
||||
attributedString = NSAttributedString(string: strings.Notification_Boost_SingleYou, font: titleFont, textColor: primaryTextColor)
|
||||
} else {
|
||||
let boostsString = strings.Notification_Boost_Times(boosts)
|
||||
attributedString = NSAttributedString(string: strings.Notification_Boost_MultipleYou(boostsString).string, font: titleFont, textColor: primaryTextColor)
|
||||
}
|
||||
} else {
|
||||
let peerName = message.author?.compactDisplayTitle ?? ""
|
||||
if boosts == 1 {
|
||||
let resultTitleString = strings.Notification_Boost_Single(peerName)
|
||||
attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
|
||||
} else {
|
||||
let boostsString = strings.Notification_Boost_Times(boosts)
|
||||
let resultTitleString = strings.Notification_Boost_Multiple(peerName, boostsString)
|
||||
attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
|
||||
}
|
||||
}
|
||||
case .unknown:
|
||||
attributedString = nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -428,6 +428,7 @@ final class AvatarEditorScreenComponent: Component {
|
|||
groupId: "emoji",
|
||||
title: "Emoji",
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -448,6 +449,7 @@ final class AvatarEditorScreenComponent: Component {
|
|||
groupId: "stickers",
|
||||
title: "Stickers",
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -505,6 +507,7 @@ final class AvatarEditorScreenComponent: Component {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -538,6 +541,7 @@ final class AvatarEditorScreenComponent: Component {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
|
|||
|
|
@ -1061,7 +1061,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||
.disappear(.default(scale: true))
|
||||
)
|
||||
|
||||
if !isTablet && Camera.isDualCameraSupported {
|
||||
if !isTablet && Camera.isDualCameraSupported(forRoundVideo: false) {
|
||||
let dualButton = dualButton.update(
|
||||
component: CameraButton(
|
||||
content: AnyComponentWithIdentity(
|
||||
|
|
@ -1513,7 +1513,7 @@ public class CameraScreen: ViewController {
|
|||
self.previewBlurView = BlurView()
|
||||
self.previewBlurView.isUserInteractionEnabled = false
|
||||
|
||||
var isDualCameraEnabled = Camera.isDualCameraSupported
|
||||
var isDualCameraEnabled = Camera.isDualCameraSupported(forRoundVideo: false)
|
||||
if isDualCameraEnabled {
|
||||
if let isDualCameraEnabledValue = UserDefaults.standard.object(forKey: "TelegramStoryCameraIsDualEnabled") as? NSNumber {
|
||||
isDualCameraEnabled = isDualCameraEnabledValue.boolValue
|
||||
|
|
|
|||
|
|
@ -564,7 +564,12 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||
false
|
||||
)
|
||||
actionButtonMinWidthAndFinalizeLayout = (buttonWidth, continueLayout)
|
||||
actualWidth = max(actualWidth, buttonWidth)
|
||||
|
||||
var buttonInset: CGFloat = 0.0
|
||||
if let buttonIconImage {
|
||||
buttonInset += buttonIconImage.size.width + 2.0
|
||||
}
|
||||
actualWidth = max(actualWidth, buttonWidth + buttonInset * 2.0)
|
||||
} else {
|
||||
actionButtonMinWidthAndFinalizeLayout = nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -321,6 +321,11 @@ public class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
}
|
||||
let (addButtonWidth, addContinueLayout) = makeAddButtonLayout(constrainedSize.width, 10.0, nil, false, addTitle.uppercased(), mainColor, false, false)
|
||||
|
||||
|
||||
let showAddButton = !(!canAdd && canMessage)
|
||||
let showMessageButton = canMessage
|
||||
let buttonCount = (showAddButton ? 1 : 0) + (showMessageButton ? 1 : 0)
|
||||
|
||||
let maxButtonWidth = max(messageButtonWidth, addButtonWidth)
|
||||
var maxContentWidth: CGFloat = avatarSize.width + 7.0
|
||||
if let statusSuggestedWidthAndContinue = statusSuggestedWidthAndContinue {
|
||||
|
|
@ -328,7 +333,7 @@ public class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
}
|
||||
maxContentWidth = max(maxContentWidth, 7.0 + avatarSize.width + 7.0 + titleLayout.size.width + 7.0)
|
||||
maxContentWidth = max(maxContentWidth, 7.0 + avatarSize.width + 7.0 + textLayout.size.width + 7.0)
|
||||
maxContentWidth = max(maxContentWidth, maxButtonWidth * 2.0)
|
||||
maxContentWidth = max(maxContentWidth, maxButtonWidth * CGFloat(buttonCount))
|
||||
maxContentWidth = max(maxContentWidth, 220.0)
|
||||
|
||||
let contentWidth = maxContentWidth + layoutConstants.text.bubbleInsets.right * 2.0
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ public final class ChatRecentActionsController: TelegramBaseController {
|
|||
}, hideTranslationPanel: {
|
||||
}, openPremiumGift: {
|
||||
}, openPremiumRequiredForMessaging: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, requestLayout: { _ in
|
||||
}, chatController: {
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||
public let displayGiveawayParticipationStatus: (EngineMessage.Id) -> Void
|
||||
public let openPremiumStatusInfo: (EnginePeer.Id, UIView, Int64?, PeerNameColor) -> Void
|
||||
public let openRecommendedChannelContextMenu: (EnginePeer, UIView, ContextGesture?) -> Void
|
||||
public let openGroupBoostInfo: (EnginePeer.Id, Int) -> Void
|
||||
public let openGroupBoostInfo: (EnginePeer.Id?, Int) -> Void
|
||||
|
||||
public let requestMessageUpdate: (MessageId, Bool) -> Void
|
||||
public let cancelInteractiveKeyboardGestures: () -> Void
|
||||
|
|
@ -354,7 +354,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||
displayGiveawayParticipationStatus: @escaping (EngineMessage.Id) -> Void,
|
||||
openPremiumStatusInfo: @escaping (EnginePeer.Id, UIView, Int64?, PeerNameColor) -> Void,
|
||||
openRecommendedChannelContextMenu: @escaping (EnginePeer, UIView, ContextGesture?) -> Void,
|
||||
openGroupBoostInfo: @escaping (EnginePeer.Id, Int) -> Void,
|
||||
openGroupBoostInfo: @escaping (EnginePeer.Id?, Int) -> Void,
|
||||
requestMessageUpdate: @escaping (MessageId, Bool) -> Void,
|
||||
cancelInteractiveKeyboardGestures: @escaping () -> Void,
|
||||
dismissTextInput: @escaping () -> Void,
|
||||
|
|
|
|||
|
|
@ -639,7 +639,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||
}
|
||||
}
|
||||
|
||||
if file.isPremiumEmoji && !hasPremium {
|
||||
if file.isPremiumEmoji && !hasPremium && groupId != AnyHashable("peerSpecific") {
|
||||
var animateInAsReplacement = false
|
||||
if let currentUndoOverlayController = strongSelf.currentUndoOverlayController {
|
||||
currentUndoOverlayController.dismissWithCommitActionAndReplacementAnimation()
|
||||
|
|
@ -959,6 +959,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1007,6 +1008,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||
groupId: AnyHashable(info.id),
|
||||
title: info.title,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1065,6 +1067,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1095,6 +1098,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1365,6 +1369,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -1395,6 +1400,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
|
|||
|
|
@ -578,6 +578,7 @@ public final class EmojiStatusSelectionController: ViewController {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -632,6 +633,7 @@ public final class EmojiStatusSelectionController: ViewController {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -663,6 +665,7 @@ public final class EmojiStatusSelectionController: ViewController {
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
|
|||
|
|
@ -771,6 +771,8 @@ private final class GroupHeaderLayer: UIView {
|
|||
private var tintSubtitleLayer: SimpleLayer?
|
||||
private var lockIconLayer: SimpleLayer?
|
||||
private var tintLockIconLayer: SimpleLayer?
|
||||
private var badgeLayer: SimpleLayer?
|
||||
private var tintBadgeLayer: SimpleLayer?
|
||||
private(set) var clearIconLayer: SimpleLayer?
|
||||
private var tintClearIconLayer: SimpleLayer?
|
||||
private var separatorLayer: SimpleLayer?
|
||||
|
|
@ -816,6 +818,7 @@ private final class GroupHeaderLayer: UIView {
|
|||
actionButtonTitle: String?,
|
||||
title: String,
|
||||
subtitle: String?,
|
||||
badge: String?,
|
||||
isPremiumLocked: Bool,
|
||||
hasClear: Bool,
|
||||
embeddedItems: [EmojiPagerContentComponent.Item]?,
|
||||
|
|
@ -831,7 +834,7 @@ private final class GroupHeaderLayer: UIView {
|
|||
self.theme = theme
|
||||
themeUpdated = true
|
||||
}
|
||||
|
||||
|
||||
let needsVibrancy = !theme.overallDarkAppearance || forceNeedsVibrancy
|
||||
|
||||
let textOffsetY: CGFloat
|
||||
|
|
@ -978,10 +981,72 @@ private final class GroupHeaderLayer: UIView {
|
|||
self.tintTextLayer.isHidden = !needsVibrancy
|
||||
self.currentTextLayout = (title, color, textConstrainedWidth, textSize)
|
||||
}
|
||||
|
||||
var badgeSize: CGSize = .zero
|
||||
if let badge {
|
||||
func generateBadgeImage(color: UIColor) -> UIImage? {
|
||||
let string = NSAttributedString(string: badge, font: Font.semibold(11.0), textColor: .white)
|
||||
let stringBounds = string.boundingRect(with: CGSize(width: 120, height: 18.0), options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
||||
|
||||
let badgeSize = CGSize(width: stringBounds.width + 8.0, height: 16.0)
|
||||
return generateImage(badgeSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
context.setFillColor(color.cgColor)
|
||||
context.addPath(UIBezierPath(roundedRect: CGRect(origin: .zero, size: badgeSize), cornerRadius: badgeSize.height / 2.0).cgPath)
|
||||
context.fillPath()
|
||||
|
||||
context.setBlendMode(.clear)
|
||||
|
||||
UIGraphicsPushContext(context)
|
||||
|
||||
string.draw(with: CGRect(origin: CGPoint(x: floorToScreenPixels((badgeSize.width - stringBounds.size.width) / 2.0), y: floorToScreenPixels((badgeSize.height - stringBounds.size.height) / 2.0)), size: stringBounds.size), options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
||||
|
||||
UIGraphicsPopContext()
|
||||
})
|
||||
}
|
||||
|
||||
let badgeLayer: SimpleLayer
|
||||
if let current = self.badgeLayer {
|
||||
badgeLayer = current
|
||||
} else {
|
||||
badgeLayer = SimpleLayer()
|
||||
self.badgeLayer = badgeLayer
|
||||
self.layer.addSublayer(badgeLayer)
|
||||
|
||||
if let image = generateBadgeImage(color: color.withMultipliedAlpha(0.66)) {
|
||||
badgeLayer.contents = image.cgImage
|
||||
badgeLayer.bounds = CGRect(origin: .zero, size: image.size)
|
||||
}
|
||||
}
|
||||
badgeSize = badgeLayer.bounds.size
|
||||
|
||||
let tintBadgeLayer: SimpleLayer
|
||||
if let current = self.tintBadgeLayer {
|
||||
tintBadgeLayer = current
|
||||
} else {
|
||||
tintBadgeLayer = SimpleLayer()
|
||||
self.tintBadgeLayer = tintBadgeLayer
|
||||
self.tintContentLayer.addSublayer(tintBadgeLayer)
|
||||
|
||||
if let image = generateBadgeImage(color: .white) {
|
||||
tintBadgeLayer.contents = image.cgImage
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let badgeLayer = self.badgeLayer {
|
||||
self.badgeLayer = nil
|
||||
badgeLayer.removeFromSuperlayer()
|
||||
}
|
||||
if let tintBadgeLayer = self.tintBadgeLayer {
|
||||
self.tintBadgeLayer = nil
|
||||
tintBadgeLayer.removeFromSuperlayer()
|
||||
}
|
||||
}
|
||||
|
||||
let textFrame: CGRect
|
||||
if subtitle == nil {
|
||||
textFrame = CGRect(origin: CGPoint(x: titleHorizontalOffset + floor((constrainedSize.width - titleHorizontalOffset - textSize.width) / 2.0), y: textOffsetY), size: textSize)
|
||||
textFrame = CGRect(origin: CGPoint(x: titleHorizontalOffset + floor((constrainedSize.width - titleHorizontalOffset - (textSize.width + badgeSize.width)) / 2.0), y: textOffsetY), size: textSize)
|
||||
} else {
|
||||
textFrame = CGRect(origin: CGPoint(x: titleHorizontalOffset, y: textOffsetY), size: textSize)
|
||||
}
|
||||
|
|
@ -989,6 +1054,11 @@ private final class GroupHeaderLayer: UIView {
|
|||
self.tintTextLayer.frame = textFrame
|
||||
self.tintTextLayer.isHidden = !needsTintText
|
||||
|
||||
if let badgeLayer = self.badgeLayer, let tintBadgeLayer = self.tintBadgeLayer {
|
||||
badgeLayer.frame = CGRect(origin: CGPoint(x: textFrame.maxX + 4.0, y: 0.0), size: badgeLayer.frame.size)
|
||||
tintBadgeLayer.frame = badgeLayer.frame
|
||||
}
|
||||
|
||||
if isPremiumLocked {
|
||||
let lockIconLayer: SimpleLayer
|
||||
if let current = self.lockIconLayer {
|
||||
|
|
@ -2536,6 +2606,7 @@ public final class EmojiPagerContentComponent: Component {
|
|||
public let groupId: AnyHashable
|
||||
public let title: String?
|
||||
public let subtitle: String?
|
||||
public let badge: String?
|
||||
public let actionButtonTitle: String?
|
||||
public let isFeatured: Bool
|
||||
public let isPremiumLocked: Bool
|
||||
|
|
@ -2553,6 +2624,7 @@ public final class EmojiPagerContentComponent: Component {
|
|||
groupId: AnyHashable,
|
||||
title: String?,
|
||||
subtitle: String?,
|
||||
badge: String?,
|
||||
actionButtonTitle: String?,
|
||||
isFeatured: Bool,
|
||||
isPremiumLocked: Bool,
|
||||
|
|
@ -2569,6 +2641,7 @@ public final class EmojiPagerContentComponent: Component {
|
|||
self.groupId = groupId
|
||||
self.title = title
|
||||
self.subtitle = subtitle
|
||||
self.badge = badge
|
||||
self.actionButtonTitle = actionButtonTitle
|
||||
self.isFeatured = isFeatured
|
||||
self.isPremiumLocked = isPremiumLocked
|
||||
|
|
@ -2598,6 +2671,9 @@ public final class EmojiPagerContentComponent: Component {
|
|||
if lhs.subtitle != rhs.subtitle {
|
||||
return false
|
||||
}
|
||||
if lhs.badge != rhs.badge {
|
||||
return false
|
||||
}
|
||||
if lhs.actionButtonTitle != rhs.actionButtonTitle {
|
||||
return false
|
||||
}
|
||||
|
|
@ -5540,6 +5616,7 @@ public final class EmojiPagerContentComponent: Component {
|
|||
actionButtonTitle: actionButtonTitle,
|
||||
title: title,
|
||||
subtitle: itemGroup.subtitle,
|
||||
badge: itemGroup.badge,
|
||||
isPremiumLocked: itemGroup.isPremiumLocked,
|
||||
hasClear: itemGroup.hasClear,
|
||||
embeddedItems: itemGroup.isEmbedded ? itemGroup.items : nil,
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ public extension EmojiPagerContentComponent {
|
|||
var id: AnyHashable
|
||||
var title: String?
|
||||
var subtitle: String?
|
||||
var badge: String?
|
||||
var isPremiumLocked: Bool
|
||||
var isFeatured: Bool
|
||||
var collapsedLineCount: Int?
|
||||
|
|
@ -241,7 +242,7 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: strings.EmojiInput_SectionTitleEmoji, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: strings.EmojiInput_SectionTitleEmoji, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -317,7 +318,7 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
|
||||
let title = context.sharedContext.currentPresentationData.with({ $0 }).strings.EmojiInput_TrendingEmoji
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: title, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 0, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: title, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 0, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -373,7 +374,7 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
|
||||
var existingIds = Set<MediaId>()
|
||||
|
|
@ -432,7 +433,7 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: topStatusTitle?.uppercased(), subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: topStatusTitle?.uppercased(), subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
|
||||
var existingIds = Set<MediaId>()
|
||||
|
|
@ -592,7 +593,7 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: topStatusTitle?.uppercased(), subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: topStatusTitle?.uppercased(), subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
|
||||
var existingIds = Set<MediaId>()
|
||||
|
|
@ -738,7 +739,7 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -816,7 +817,7 @@ public extension EmojiPagerContentComponent {
|
|||
}
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -874,7 +875,7 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: popularTitle, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: hasRecent && subject != .quickReaction, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: popularTitle, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: hasRecent && subject != .quickReaction, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
} else {
|
||||
let groupId = "recent"
|
||||
|
|
@ -886,7 +887,7 @@ public extension EmojiPagerContentComponent {
|
|||
}
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -958,7 +959,7 @@ public extension EmojiPagerContentComponent {
|
|||
popularInsertIndex += 1
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: popularTitle, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: hasRecent && subject != .quickReaction, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: popularTitle, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: hasRecent && subject != .quickReaction, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1023,7 +1024,7 @@ public extension EmojiPagerContentComponent {
|
|||
}
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
} else if [.profilePhoto, .groupPhoto].contains(subject) {
|
||||
|
|
@ -1031,7 +1032,7 @@ public extension EmojiPagerContentComponent {
|
|||
|
||||
let groupId = "recent"
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: topStatusTitle?.uppercased(), subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: []))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: topStatusTitle?.uppercased(), subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: []))
|
||||
|
||||
if let featuredAvatarEmoji = featuredAvatarEmoji {
|
||||
for item in featuredAvatarEmoji.items {
|
||||
|
|
@ -1100,7 +1101,7 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
|
||||
if let featuredBackgroundIconEmoji {
|
||||
|
|
@ -1208,15 +1209,11 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: strings.Emoji_FrequentlyUsed, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: true, headerItem: nil, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: strings.Emoji_FrequentlyUsed, subtitle: nil, badge: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: true, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !hasPremium {
|
||||
maybeAppendUnicodeEmoji()
|
||||
}
|
||||
|
||||
|
||||
var itemCollectionMapping: [ItemCollectionId: StickerPackCollectionInfo] = [:]
|
||||
for (id, info, _) in view.collectionInfos {
|
||||
if let info = info as? StickerPackCollectionInfo {
|
||||
|
|
@ -1260,13 +1257,18 @@ public extension EmojiPagerContentComponent {
|
|||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: peerSpecificPack.peer.compactDisplayTitle, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
//TODO:localize
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: peerSpecificPack.info.title, subtitle: nil, badge: "GROUP EMOJI", isPremiumLocked: false, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
|
||||
let supergroupId: AnyHashable = peerSpecificPack.info.id
|
||||
skippedCollectionIds.insert(supergroupId)
|
||||
}
|
||||
|
||||
if !hasPremium {
|
||||
maybeAppendUnicodeEmoji()
|
||||
}
|
||||
|
||||
if areCustomEmojiEnabled {
|
||||
for entry in view.entries {
|
||||
|
|
@ -1364,7 +1366,7 @@ public extension EmojiPagerContentComponent {
|
|||
break inner
|
||||
}
|
||||
}
|
||||
itemGroups.append(ItemGroup(supergroupId: supergroupId, id: groupId, title: title, subtitle: nil, isPremiumLocked: isPremiumLocked, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: headerItem, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: supergroupId, id: groupId, title: title, subtitle: nil, badge: nil, isPremiumLocked: isPremiumLocked, isFeatured: false, collapsedLineCount: nil, isClearable: false, headerItem: headerItem, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1453,7 +1455,7 @@ public extension EmojiPagerContentComponent {
|
|||
isFeatured = false
|
||||
}
|
||||
|
||||
itemGroups.append(ItemGroup(supergroupId: supergroupId, id: groupId, title: featuredEmojiPack.info.title, subtitle: nil, isPremiumLocked: isPremiumLocked, isFeatured: isFeatured, collapsedLineCount: 3, isClearable: false, headerItem: headerItem, items: [resultItem]))
|
||||
itemGroups.append(ItemGroup(supergroupId: supergroupId, id: groupId, title: featuredEmojiPack.info.title, subtitle: nil, badge: nil, isPremiumLocked: isPremiumLocked, isFeatured: isFeatured, collapsedLineCount: 3, isClearable: false, headerItem: headerItem, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1508,6 +1510,7 @@ public extension EmojiPagerContentComponent {
|
|||
groupId: group.id,
|
||||
title: group.title,
|
||||
subtitle: group.subtitle,
|
||||
badge: group.badge,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: group.isFeatured,
|
||||
isPremiumLocked: group.isPremiumLocked,
|
||||
|
|
@ -1994,6 +1997,7 @@ public extension EmojiPagerContentComponent {
|
|||
groupId: group.id,
|
||||
title: group.title,
|
||||
subtitle: group.subtitle,
|
||||
badge: nil,
|
||||
actionButtonTitle: group.actionButtonTitle,
|
||||
isFeatured: group.isFeatured,
|
||||
isPremiumLocked: group.isPremiumLocked,
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
|
|||
groupId: AnyHashable(groupItem.info.id),
|
||||
title: groupItem.info.title,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: self.presentationData.strings.EmojiInput_AddPack(groupItem.info.title).string,
|
||||
isFeatured: true,
|
||||
isPremiumLocked: !self.hasPremiumForInstallation,
|
||||
|
|
@ -286,6 +287,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -340,6 +342,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
@ -373,6 +376,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
|
|||
groupId: "search",
|
||||
title: nil,
|
||||
subtitle: nil,
|
||||
badge: nil,
|
||||
actionButtonTitle: nil,
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ swift_library(
|
|||
"//submodules/AccountContext:AccountContext",
|
||||
"//submodules/StickerPackPreviewUI:StickerPackPreviewUI",
|
||||
"//submodules/ItemListStickerPackItem:ItemListStickerPackItem",
|
||||
"//submodules/SearchBarNode:SearchBarNode",
|
||||
"//submodules/SearchUI:SearchUI",
|
||||
"//submodules/MergeLists:MergeLists",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ private enum GroupStickerPackSearchState: Equatable {
|
|||
|
||||
private struct GroupStickerPackSetupControllerState: Equatable {
|
||||
var isSaving: Bool
|
||||
var searchingPacks: Bool
|
||||
}
|
||||
|
||||
private func groupStickerPackSetupControllerEntries(context: AccountContext, presentationData: PresentationData, searchText: String, view: CombinedView, initialData: InitialStickerPackData?, searchState: GroupStickerPackSearchState, stickerSettings: StickerSettings, emoji: Bool) -> [GroupStickerPackEntry] {
|
||||
|
|
@ -276,10 +277,10 @@ private func groupStickerPackSetupControllerEntries(context: AccountContext, pre
|
|||
case .searching:
|
||||
entries.append(.currentPack(0, presentationData.theme, presentationData.strings, .searching))
|
||||
case let .found(data):
|
||||
entries.append(.currentPack(0, presentationData.theme, presentationData.strings, .found(packInfo: data.info, topItem: data.item, subtitle: presentationData.strings.StickerPack_StickerCount(data.info.count))))
|
||||
entries.append(.currentPack(0, presentationData.theme, presentationData.strings, .found(packInfo: data.info, topItem: data.item, subtitle: emoji ? presentationData.strings.StickerPack_EmojiCount(data.info.count) : presentationData.strings.StickerPack_StickerCount(data.info.count))))
|
||||
}
|
||||
entries.append(.searchInfo(presentationData.theme, emoji ? "All members will be able to use these emoji in the group, even if they don't have Telegram Premium." : presentationData.strings.Channel_Stickers_CreateYourOwn))
|
||||
entries.append(.packsTitle(presentationData.theme, emoji ? "CHOOSE FROM YOUR EMOJI" : presentationData.strings.Channel_Stickers_YourStickers))
|
||||
entries.append(.packsTitle(presentationData.theme, emoji ? "CHOOSE EMOJI PACK" : presentationData.strings.Channel_Stickers_YourStickers))
|
||||
|
||||
let namespace = emoji ? Namespaces.ItemCollection.CloudEmojiPacks : Namespaces.ItemCollection.CloudStickerPacks
|
||||
if let stickerPacksView = view.views[.itemCollectionInfos(namespaces: [namespace])] as? ItemCollectionInfosView {
|
||||
|
|
@ -291,7 +292,15 @@ private func groupStickerPackSetupControllerEntries(context: AccountContext, pre
|
|||
if case let .found(found) = searchState {
|
||||
selected = found.info.id == info.id
|
||||
}
|
||||
entries.append(.pack(index, presentationData.theme, presentationData.strings, info, entry.firstItem as? StickerPackItem, presentationData.strings.StickerPack_StickerCount(info.count == 0 ? entry.count : info.count), context.sharedContext.energyUsageSettings.loopStickers, selected))
|
||||
let count = info.count == 0 ? entry.count : info.count
|
||||
|
||||
let thumbnail: StickerPackItem?
|
||||
if let thumbnailRep = info.thumbnail {
|
||||
thumbnail = StickerPackItem(index: ItemCollectionItemIndex(index: 0, id: 0), file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: thumbnailRep.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: info.immediateThumbnailData, mimeType: "", size: nil, attributes: []), indexKeys: [])
|
||||
} else {
|
||||
thumbnail = entry.firstItem as? StickerPackItem
|
||||
}
|
||||
entries.append(.pack(index, presentationData.theme, presentationData.strings, info, thumbnail, emoji ? presentationData.strings.StickerPack_EmojiCount(count) : presentationData.strings.StickerPack_StickerCount(count), context.sharedContext.energyUsageSettings.loopStickers, selected))
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
|
|
@ -302,7 +311,7 @@ private func groupStickerPackSetupControllerEntries(context: AccountContext, pre
|
|||
}
|
||||
|
||||
public func groupStickerPackSetupController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, emoji: Bool = false, currentPackInfo: StickerPackCollectionInfo?, completion: ((StickerPackCollectionInfo?) -> Void)? = nil) -> ViewController {
|
||||
let initialState = GroupStickerPackSetupControllerState(isSaving: false)
|
||||
let initialState = GroupStickerPackSetupControllerState(isSaving: false, searchingPacks: false)
|
||||
|
||||
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
||||
let stateValue = Atomic(value: initialState)
|
||||
|
|
@ -433,10 +442,15 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
var rightNavigationButton: ItemListNavigationButton?
|
||||
if let _ = completion {
|
||||
rightNavigationButton = ItemListNavigationButton(content: .icon(.search), style: .regular, enabled: true, action: {})
|
||||
rightNavigationButton = ItemListNavigationButton(content: .icon(.search), style: .regular, enabled: true, action: {
|
||||
updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.searchingPacks = true
|
||||
return updatedState
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if initialData != nil {
|
||||
if state.isSaving {
|
||||
|
|
@ -467,7 +481,7 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres
|
|||
return state
|
||||
}
|
||||
saveDisposable.set((context.engine.peers.updateGroupSpecificStickerset(peerId: peerId, info: info)
|
||||
|> deliverOnMainQueue).start(error: { _ in
|
||||
|> deliverOnMainQueue).start(error: { _ in
|
||||
updateState { state in
|
||||
var state = state
|
||||
state.isSaving = false
|
||||
|
|
@ -483,6 +497,21 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres
|
|||
}
|
||||
}
|
||||
|
||||
var searchItem: ItemListControllerSearch?
|
||||
if state.searchingPacks {
|
||||
searchItem = GroupStickerSearchItem(context: context, cancel: {
|
||||
updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.searchingPacks = false
|
||||
return updatedState
|
||||
}
|
||||
}, select: { pack in
|
||||
arguments.selectStickerPack(pack)
|
||||
}, dismissInput: {
|
||||
dismissInputImpl?()
|
||||
})
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(emoji ? "Group Emoji Pack" : presentationData.strings.Channel_Info_Stickers), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
|
||||
|
||||
let hasData = initialData != nil
|
||||
|
|
@ -493,7 +522,7 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres
|
|||
emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme)
|
||||
}
|
||||
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: groupStickerPackSetupControllerEntries(context: context, presentationData: presentationData, searchText: searchState.0, view: view, initialData: initialData, searchState: searchState.1, stickerSettings: stickerSettings, emoji: emoji), style: .blocks, emptyStateItem: emptyStateItem, animateChanges: hasData && hadData)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: groupStickerPackSetupControllerEntries(context: context, presentationData: presentationData, searchText: searchState.0, view: view, initialData: initialData, searchState: searchState.1, stickerSettings: stickerSettings, emoji: emoji), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: hasData && hadData)
|
||||
return (controllerState, (listState, arguments))
|
||||
} |> afterDisposed {
|
||||
actionsDisposable.dispose()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,328 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import MergeLists
|
||||
import AccountContext
|
||||
import SearchUI
|
||||
import ItemListUI
|
||||
import ItemListStickerPackItem
|
||||
|
||||
private final class GroupStickerSearchContainerInteraction {
|
||||
let packSelected: (StickerPackCollectionInfo) -> Void
|
||||
|
||||
init(packSelected: @escaping (StickerPackCollectionInfo) -> Void) {
|
||||
self.packSelected = packSelected
|
||||
}
|
||||
}
|
||||
|
||||
private final class GroupStickerSearchEntry: Comparable, Identifiable {
|
||||
let index: Int
|
||||
let pack: StickerPackCollectionInfo
|
||||
let topItem: ItemCollectionItem?
|
||||
|
||||
init(index: Int, pack: StickerPackCollectionInfo, topItem: ItemCollectionItem?) {
|
||||
self.index = index
|
||||
self.pack = pack
|
||||
self.topItem = topItem
|
||||
}
|
||||
|
||||
var stableId: ItemCollectionId {
|
||||
return self.pack.id
|
||||
}
|
||||
|
||||
static func ==(lhs: GroupStickerSearchEntry, rhs: GroupStickerSearchEntry) -> Bool {
|
||||
return lhs.index == rhs.index && lhs.pack == rhs.pack
|
||||
}
|
||||
|
||||
static func <(lhs: GroupStickerSearchEntry, rhs: GroupStickerSearchEntry) -> Bool {
|
||||
return lhs.index < rhs.index
|
||||
}
|
||||
|
||||
func item(context: AccountContext, presentationData: PresentationData, interaction: GroupStickerSearchContainerInteraction) -> ListViewItem {
|
||||
let pack = self.pack
|
||||
let count = presentationData.strings.StickerPack_EmojiCount(pack.count)
|
||||
|
||||
return ItemListStickerPackItem(presentationData: ItemListPresentationData(presentationData), context: context, packInfo: pack, itemCount: count, topItem: self.topItem as? StickerPackItem, unread: false, control: .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: true, style: .plain, sectionId: 0, action: {
|
||||
interaction.packSelected(pack)
|
||||
}, setPackIdWithRevealedOptions: { _, _ in
|
||||
}, addPack: {
|
||||
}, removePack: {
|
||||
}, toggleSelected: {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct GroupStickerSearchContainerTransition {
|
||||
let deletions: [ListViewDeleteItem]
|
||||
let insertions: [ListViewInsertItem]
|
||||
let updates: [ListViewUpdateItem]
|
||||
let isSearching: Bool
|
||||
let isEmpty: Bool
|
||||
let query: String
|
||||
}
|
||||
|
||||
private func groupStickerSearchContainerPreparedRecentTransition(from fromEntries: [GroupStickerSearchEntry], to toEntries: [GroupStickerSearchEntry], isSearching: Bool, isEmpty: Bool, query: String, context: AccountContext, presentationData: PresentationData, interaction: GroupStickerSearchContainerInteraction) -> GroupStickerSearchContainerTransition {
|
||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||
|
||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
||||
|
||||
return GroupStickerSearchContainerTransition(deletions: deletions, insertions: insertions, updates: updates, isSearching: isSearching, isEmpty: isEmpty, query: query)
|
||||
}
|
||||
|
||||
public final class GroupStickerSearchContainerNode: SearchDisplayControllerContentNode {
|
||||
private let context: AccountContext
|
||||
private let packSelected: (StickerPackCollectionInfo) -> Void
|
||||
|
||||
private let listNode: ListView
|
||||
|
||||
private let emptyResultsTitleNode: ImmediateTextNode
|
||||
private let emptyResultsTextNode: ImmediateTextNode
|
||||
|
||||
private var enqueuedTransitions: [(GroupStickerSearchContainerTransition, Bool)] = []
|
||||
private var validLayout: (ContainerViewLayout, CGFloat)?
|
||||
|
||||
private let searchQuery = Promise<String?>()
|
||||
private let searchDisposable = MetaDisposable()
|
||||
|
||||
private let forceTheme: PresentationTheme?
|
||||
private var presentationData: PresentationData
|
||||
private var presentationDataDisposable: Disposable?
|
||||
|
||||
private let removeMemberDisposable = MetaDisposable()
|
||||
|
||||
private let presentationDataPromise: Promise<PresentationData>
|
||||
|
||||
private var _hasDim: Bool = false
|
||||
override public var hasDim: Bool {
|
||||
return _hasDim
|
||||
}
|
||||
|
||||
public init(context: AccountContext, forceTheme: PresentationTheme?, packSelected: @escaping (StickerPackCollectionInfo) -> Void, updateActivity: @escaping (Bool) -> Void, pushController: @escaping (ViewController) -> Void) {
|
||||
self.context = context
|
||||
self.packSelected = packSelected
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.presentationData = presentationData
|
||||
|
||||
self.forceTheme = forceTheme
|
||||
if let forceTheme = self.forceTheme {
|
||||
self.presentationData = self.presentationData.withUpdated(theme: forceTheme)
|
||||
}
|
||||
self.presentationDataPromise = Promise(self.presentationData)
|
||||
|
||||
self.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
|
||||
}
|
||||
|
||||
self.emptyResultsTitleNode = ImmediateTextNode()
|
||||
self.emptyResultsTitleNode.displaysAsynchronously = false
|
||||
self.emptyResultsTitleNode.attributedText = NSAttributedString(string: self.presentationData.strings.ChatList_Search_NoResults, font: Font.semibold(17.0), textColor: self.presentationData.theme.list.freeTextColor)
|
||||
self.emptyResultsTitleNode.textAlignment = .center
|
||||
self.emptyResultsTitleNode.isHidden = true
|
||||
|
||||
self.emptyResultsTextNode = ImmediateTextNode()
|
||||
self.emptyResultsTextNode.displaysAsynchronously = false
|
||||
self.emptyResultsTextNode.maximumNumberOfLines = 0
|
||||
self.emptyResultsTextNode.textAlignment = .center
|
||||
self.emptyResultsTextNode.isHidden = true
|
||||
|
||||
super.init()
|
||||
|
||||
self.listNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
||||
self.listNode.isHidden = true
|
||||
|
||||
self._hasDim = true
|
||||
|
||||
self.addSubnode(self.listNode)
|
||||
|
||||
self.addSubnode(self.emptyResultsTitleNode)
|
||||
self.addSubnode(self.emptyResultsTextNode)
|
||||
|
||||
let interaction = GroupStickerSearchContainerInteraction(packSelected: { [weak self] pack in
|
||||
packSelected(pack)
|
||||
self?.listNode.clearHighlightAnimated(true)
|
||||
})
|
||||
|
||||
let foundItems = self.searchQuery.get()
|
||||
|> mapToSignal { query -> Signal<[GroupStickerSearchEntry]?, NoError> in
|
||||
guard let query, !query.isEmpty else {
|
||||
return .single(nil)
|
||||
}
|
||||
return context.engine.stickers.searchEmojiSets(query: query)
|
||||
|> mapToSignal { localResult in
|
||||
return context.engine.stickers.searchEmojiSetsRemotely(query: query)
|
||||
|> map { remoteResult -> [GroupStickerSearchEntry]? in
|
||||
let mergedResult = localResult.merge(with: remoteResult)
|
||||
var entries: [GroupStickerSearchEntry] = []
|
||||
var index = 0
|
||||
for info in mergedResult.infos {
|
||||
if let pack = info.1 as? StickerPackCollectionInfo {
|
||||
entries.append(GroupStickerSearchEntry(index: index, pack: pack, topItem: info.2))
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
return entries
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let previousSearchItems = Atomic<[GroupStickerSearchEntry]?>(value: nil)
|
||||
self.searchDisposable.set((combineLatest(self.searchQuery.get(), foundItems, self.presentationDataPromise.get())
|
||||
|> deliverOnMainQueue).start(next: { [weak self] query, entries, presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousEntries = previousSearchItems.swap(entries)
|
||||
updateActivity(false)
|
||||
let firstTime = previousEntries == nil
|
||||
let transition = groupStickerSearchContainerPreparedRecentTransition(from: previousEntries ?? [], to: entries ?? [], isSearching: entries != nil, isEmpty: entries?.isEmpty ?? false, query: query ?? "", context: context, presentationData: presentationData, interaction: interaction)
|
||||
strongSelf.enqueueTransition(transition, firstTime: firstTime)
|
||||
}
|
||||
}))
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
var presentationData = presentationData
|
||||
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
let previousStrings = strongSelf.presentationData.strings
|
||||
|
||||
if let forceTheme = strongSelf.forceTheme {
|
||||
presentationData = presentationData.withUpdated(theme: forceTheme)
|
||||
}
|
||||
|
||||
strongSelf.presentationData = presentationData
|
||||
|
||||
if previousTheme !== presentationData.theme || previousStrings !== presentationData.strings {
|
||||
strongSelf.updateThemeAndStrings(theme: presentationData.theme, strings: presentationData.strings)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.listNode.beganInteractiveDragging = { [weak self] _ in
|
||||
self?.dismissInput?()
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.searchDisposable.dispose()
|
||||
self.presentationDataDisposable?.dispose()
|
||||
}
|
||||
|
||||
private func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
|
||||
self.listNode.backgroundColor = theme.chatList.backgroundColor
|
||||
}
|
||||
|
||||
override public func searchTextUpdated(text: String) {
|
||||
if text.isEmpty {
|
||||
self.searchQuery.set(.single(nil))
|
||||
} else {
|
||||
self.searchQuery.set(.single(text))
|
||||
}
|
||||
}
|
||||
|
||||
private func enqueueTransition(_ transition: GroupStickerSearchContainerTransition, firstTime: Bool) {
|
||||
enqueuedTransitions.append((transition, firstTime))
|
||||
|
||||
if let _ = self.validLayout {
|
||||
while !self.enqueuedTransitions.isEmpty {
|
||||
self.dequeueTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func dequeueTransition() {
|
||||
if let (transition, firstTime) = self.enqueuedTransitions.first {
|
||||
self.enqueuedTransitions.remove(at: 0)
|
||||
|
||||
var options = ListViewDeleteAndInsertOptions()
|
||||
options.insert(.PreferSynchronousDrawing)
|
||||
options.insert(.PreferSynchronousResourceLoading)
|
||||
if firstTime {
|
||||
} else {
|
||||
//options.insert(.AnimateAlpha)
|
||||
}
|
||||
|
||||
let isSearching = transition.isSearching
|
||||
self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
strongSelf.listNode.isHidden = !isSearching
|
||||
|
||||
strongSelf.emptyResultsTextNode.attributedText = NSAttributedString(string: strongSelf.presentationData.strings.ChatList_Search_NoResultsQueryDescription(transition.query).string, font: Font.regular(15.0), textColor: strongSelf.presentationData.theme.list.freeTextColor)
|
||||
|
||||
let emptyResults = transition.isSearching && transition.isEmpty
|
||||
strongSelf.emptyResultsTitleNode.isHidden = !emptyResults
|
||||
strongSelf.emptyResultsTextNode.isHidden = !emptyResults
|
||||
|
||||
if let (layout, navigationBarHeight) = strongSelf.validLayout {
|
||||
strongSelf.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
super.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: transition)
|
||||
|
||||
let hadValidLayout = self.validLayout == nil
|
||||
self.validLayout = (layout, navigationBarHeight)
|
||||
|
||||
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
|
||||
|
||||
var insets = layout.insets(options: [.input])
|
||||
insets.top += navigationBarHeight
|
||||
insets.left += layout.safeInsets.left
|
||||
insets.right += layout.safeInsets.right
|
||||
|
||||
self.listNode.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: layout.size, insets: insets, duration: duration, curve: curve), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
|
||||
let padding: CGFloat = 16.0
|
||||
let emptyTitleSize = self.emptyResultsTitleNode.updateLayout(CGSize(width: layout.size.width - layout.safeInsets.left - layout.safeInsets.right - padding * 2.0, height: CGFloat.greatestFiniteMagnitude))
|
||||
let emptyTextSize = self.emptyResultsTextNode.updateLayout(CGSize(width: layout.size.width - layout.safeInsets.left - layout.safeInsets.right - padding * 2.0, height: CGFloat.greatestFiniteMagnitude))
|
||||
|
||||
let emptyTextSpacing: CGFloat = 8.0
|
||||
let emptyTotalHeight = emptyTitleSize.height + emptyTextSize.height + emptyTextSpacing
|
||||
let emptyTitleY = navigationBarHeight + floorToScreenPixels((layout.size.height - navigationBarHeight - max(insets.bottom, layout.intrinsicInsets.bottom) - emptyTotalHeight) / 2.0)
|
||||
|
||||
transition.updateFrame(node: self.emptyResultsTitleNode, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left + padding + (layout.size.width - layout.safeInsets.left - layout.safeInsets.right - padding * 2.0 - emptyTitleSize.width) / 2.0, y: emptyTitleY), size: emptyTitleSize))
|
||||
transition.updateFrame(node: self.emptyResultsTextNode, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left + padding + (layout.size.width - layout.safeInsets.left - layout.safeInsets.right - padding * 2.0 - emptyTextSize.width) / 2.0, y: emptyTitleY + emptyTitleSize.height + emptyTextSpacing), size: emptyTextSize))
|
||||
|
||||
if !hadValidLayout {
|
||||
while !self.enqueuedTransitions.isEmpty {
|
||||
self.dequeueTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public func scrollToTop() {
|
||||
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
}
|
||||
|
||||
@objc func dimTapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||
if case .ended = recognizer.state {
|
||||
self.cancel?()
|
||||
}
|
||||
}
|
||||
|
||||
override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
guard let result = self.view.hitTest(point, with: event) else {
|
||||
return nil
|
||||
}
|
||||
if result === self.view {
|
||||
return nil
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import TelegramCore
|
||||
import SwiftSignalKit
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
|
||||
final class GroupStickerSearchItem: ItemListControllerSearch {
|
||||
let context: AccountContext
|
||||
let cancel: () -> Void
|
||||
let select: (StickerPackCollectionInfo) -> Void
|
||||
let dismissInput: () -> Void
|
||||
|
||||
private var updateActivity: ((Bool) -> Void)?
|
||||
private var activity: ValuePromise<Bool> = ValuePromise(ignoreRepeated: false)
|
||||
private let activityDisposable = MetaDisposable()
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
cancel: @escaping () -> Void,
|
||||
select: @escaping (StickerPackCollectionInfo) -> Void,
|
||||
dismissInput: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.cancel = cancel
|
||||
self.select = select
|
||||
self.dismissInput = dismissInput
|
||||
self.activityDisposable.set((self.activity.get() |> mapToSignal { value -> Signal<Bool, NoError> in
|
||||
if value {
|
||||
return .single(value) |> delay(0.2, queue: Queue.mainQueue())
|
||||
} else {
|
||||
return .single(value)
|
||||
}
|
||||
}).start(next: { [weak self] value in
|
||||
self?.updateActivity?(value)
|
||||
}))
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.activityDisposable.dispose()
|
||||
}
|
||||
|
||||
func isEqual(to: ItemListControllerSearch) -> Bool {
|
||||
if let to = to as? GroupStickerSearchItem {
|
||||
if self.context !== to.context {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func titleContentNode(current: (NavigationBarContentNode & ItemListControllerSearchNavigationContentNode)?) -> NavigationBarContentNode & ItemListControllerSearchNavigationContentNode {
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
if let current = current as? GroupStickerSearchNavigationContentNode {
|
||||
current.updateTheme(presentationData.theme)
|
||||
return current
|
||||
} else {
|
||||
return GroupStickerSearchNavigationContentNode(theme: presentationData.theme, strings: presentationData.strings, cancel: self.cancel, updateActivity: { [weak self] value in
|
||||
self?.updateActivity = value
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func node(current: ItemListControllerSearchNode?, titleContentNode: (NavigationBarContentNode & ItemListControllerSearchNavigationContentNode)?) -> ItemListControllerSearchNode {
|
||||
return GroupStickerSearchItemNode(context: self.context, packSelected: self.select, cancel: self.cancel, updateActivity: { [weak self] value in
|
||||
self?.activity.set(value)
|
||||
}, pushController: { c in
|
||||
|
||||
}, dismissInput: self.dismissInput)
|
||||
}
|
||||
}
|
||||
|
||||
private final class GroupStickerSearchItemNode: ItemListControllerSearchNode {
|
||||
private let containerNode: GroupStickerSearchContainerNode
|
||||
|
||||
init(context: AccountContext, packSelected: @escaping (StickerPackCollectionInfo) -> Void, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, pushController: @escaping (ViewController) -> Void, dismissInput: @escaping () -> Void) {
|
||||
self.containerNode = GroupStickerSearchContainerNode(context: context, forceTheme: nil, packSelected: { pack in
|
||||
packSelected(pack)
|
||||
cancel()
|
||||
}, updateActivity: updateActivity, pushController: pushController)
|
||||
self.containerNode.cancel = {
|
||||
cancel()
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
|
||||
self.containerNode.dismissInput = {
|
||||
dismissInput()
|
||||
}
|
||||
}
|
||||
|
||||
override func queryUpdated(_ query: String) {
|
||||
self.containerNode.searchTextUpdated(text: query)
|
||||
}
|
||||
|
||||
override func scrollToTop() {
|
||||
self.containerNode.scrollToTop()
|
||||
}
|
||||
|
||||
override func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight), size: CGSize(width: layout.size.width, height: layout.size.height - navigationBarHeight)))
|
||||
self.containerNode.containerLayoutUpdated(layout.withUpdatedSize(CGSize(width: layout.size.width, height: layout.size.height - navigationBarHeight)), navigationBarHeight: 0.0, transition: transition)
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
if let result = self.containerNode.hitTest(self.view.convert(point, to: self.containerNode.view), with: event) {
|
||||
return result
|
||||
}
|
||||
|
||||
return super.hitTest(point, with: event)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import SearchBarNode
|
||||
|
||||
private let searchBarFont = Font.regular(17.0)
|
||||
|
||||
final class GroupStickerSearchNavigationContentNode: NavigationBarContentNode, ItemListControllerSearchNavigationContentNode {
|
||||
private var theme: PresentationTheme
|
||||
private let strings: PresentationStrings
|
||||
|
||||
private let cancel: () -> Void
|
||||
|
||||
private let searchBar: SearchBarNode
|
||||
|
||||
private var queryUpdated: ((String) -> Void)?
|
||||
var activity: Bool = false {
|
||||
didSet {
|
||||
self.searchBar.activity = activity
|
||||
}
|
||||
}
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, cancel: @escaping () -> Void, updateActivity: @escaping(@escaping(Bool)->Void) -> Void) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
|
||||
self.cancel = cancel
|
||||
|
||||
self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), strings: strings, fieldStyle: .modern, displayBackground: false)
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.searchBar)
|
||||
|
||||
self.searchBar.cancel = { [weak self] in
|
||||
self?.searchBar.deactivate(clear: false)
|
||||
self?.cancel()
|
||||
}
|
||||
|
||||
self.searchBar.textUpdated = { [weak self] query, _ in
|
||||
self?.queryUpdated?(query)
|
||||
}
|
||||
|
||||
updateActivity({ [weak self] value in
|
||||
self?.activity = value
|
||||
})
|
||||
|
||||
self.updatePlaceholder()
|
||||
}
|
||||
|
||||
func setQueryUpdated(_ f: @escaping (String) -> Void) {
|
||||
self.queryUpdated = f
|
||||
}
|
||||
|
||||
func updateTheme(_ theme: PresentationTheme) {
|
||||
self.theme = theme
|
||||
self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: self.theme), strings: self.strings)
|
||||
self.updatePlaceholder()
|
||||
}
|
||||
|
||||
func updatePlaceholder() {
|
||||
self.searchBar.placeholderString = NSAttributedString(string: self.strings.Common_Search, font: searchBarFont, textColor: self.theme.rootController.navigationSearchBar.inputPlaceholderTextColor)
|
||||
}
|
||||
|
||||
override var nominalHeight: CGFloat {
|
||||
return 54.0
|
||||
}
|
||||
|
||||
override func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
let searchBarFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - self.nominalHeight), size: CGSize(width: size.width, height: 54.0))
|
||||
self.searchBar.frame = searchBarFrame
|
||||
self.searchBar.updateLayout(boundingSize: searchBarFrame.size, leftInset: leftInset, rightInset: rightInset, transition: transition)
|
||||
}
|
||||
|
||||
func activate() {
|
||||
self.searchBar.activate()
|
||||
}
|
||||
|
||||
func deactivate() {
|
||||
self.searchBar.deactivate(clear: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -14,6 +14,10 @@ private func fullEntityMediaPath(_ path: String) -> String {
|
|||
}
|
||||
|
||||
public final class DrawingStickerEntity: DrawingEntity, Codable {
|
||||
public enum DecodingError: Error {
|
||||
case generic
|
||||
}
|
||||
|
||||
public enum Content: Equatable {
|
||||
public enum ImageType: Equatable {
|
||||
case sticker
|
||||
|
|
@ -262,7 +266,7 @@ public final class DrawingStickerEntity: DrawingEntity, Codable {
|
|||
} else if let file = try container.decodeIfPresent(TelegramMediaFile.self, forKey: .videoFile) {
|
||||
self.content = .video(file)
|
||||
} else {
|
||||
fatalError()
|
||||
throw DrawingStickerEntity.DecodingError.generic
|
||||
}
|
||||
self.referenceDrawingSize = try container.decode(CGSize.self, forKey: .referenceDrawingSize)
|
||||
self.position = try container.decode(CGPoint.self, forKey: .position)
|
||||
|
|
|
|||
|
|
@ -414,6 +414,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
|
|||
}, hideTranslationPanel: {
|
||||
}, openPremiumGift: {
|
||||
}, openPremiumRequiredForMessaging: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, requestLayout: { _ in
|
||||
}, chatController: {
|
||||
|
|
|
|||
|
|
@ -728,6 +728,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
}, hideTranslationPanel: {
|
||||
}, openPremiumGift: {
|
||||
}, openPremiumRequiredForMessaging: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, requestLayout: { _ in
|
||||
}, chatController: {
|
||||
|
|
|
|||
|
|
@ -1461,11 +1461,24 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
}
|
||||
if case .channels = component.stateContext.subject {
|
||||
if case let .channel(channel) = peer, channel.addressName == nil, index == nil {
|
||||
let title: String
|
||||
let text: String
|
||||
|
||||
switch channel.info {
|
||||
case .broadcast:
|
||||
title = environment.strings.BoostGift_Channels_PrivateChannel_Title
|
||||
text = environment.strings.BoostGift_Channels_PrivateChannel_Text
|
||||
case .group:
|
||||
//TODO:localize
|
||||
title = "Group is Private"
|
||||
text = "Are you sure you want to add a private group? Users won't be able to join it without an invite link."
|
||||
}
|
||||
|
||||
let alertController = textAlertController(
|
||||
context: component.context,
|
||||
forceTheme: environment.theme,
|
||||
title: environment.strings.BoostGift_Channels_PrivateChannel_Title,
|
||||
text: environment.strings.BoostGift_Channels_PrivateChannel_Text,
|
||||
title: title,
|
||||
text: text,
|
||||
actions: [
|
||||
TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {}),
|
||||
TextAlertAction(type: .defaultAction, title: environment.strings.BoostGift_Channels_PrivateChannel_Add, action: {
|
||||
|
|
@ -2382,9 +2395,10 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
subtitle = environment.strings.BoostGift_Subscribers_Subtitle("\(10)").string
|
||||
actionButtonTitle = environment.strings.BoostGift_Subscribers_Save
|
||||
case .channels:
|
||||
title = environment.strings.BoostGift_Channels_Title
|
||||
subtitle = environment.strings.BoostGift_Channels_Subtitle("\(component.context.userLimits.maxGiveawayChannelsCount)").string
|
||||
actionButtonTitle = environment.strings.BoostGift_Channels_Save
|
||||
//TODO:localize
|
||||
title = "Add Groups or Channels"// environment.strings.BoostGift_Channels_Title
|
||||
subtitle = "select up to \(component.context.userLimits.maxGiveawayChannelsCount) groups or channels" //environment.strings.BoostGift_Channels_Subtitle("\(component.context.userLimits.maxGiveawayChannelsCount)").string
|
||||
actionButtonTitle = "Save Groups and Channels" // environment.strings.BoostGift_Channels_Save
|
||||
}
|
||||
|
||||
let titleComponent: AnyComponent<Empty>
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ public extension ShareWithPeersScreen {
|
|||
}
|
||||
|
||||
for item in searchResults {
|
||||
if let peer = item.peer, case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
if let peer = item.peer, case .channel = peer {
|
||||
selectedPeers.append(peer)
|
||||
existingIds.insert(peer.id)
|
||||
}
|
||||
|
|
@ -672,7 +672,7 @@ public extension ShareWithPeersScreen {
|
|||
if self.initialPeerIds.contains(peer.id) {
|
||||
return false
|
||||
}
|
||||
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
if case .channel = peer {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -292,6 +292,7 @@ public class ImmediateTextNodeWithEntities: TextNode {
|
|||
public var displaySpoilers = false
|
||||
public var displaySpoilerEffect = true
|
||||
public var spoilerColor: UIColor = .black
|
||||
public var balancedTextLayout: Bool = false
|
||||
|
||||
private var enableLooping: Bool = true
|
||||
|
||||
|
|
|
|||
|
|
@ -621,7 +621,7 @@ public class VideoMessageCameraScreen: ViewController {
|
|||
self.previewContainerView = UIView()
|
||||
self.previewContainerView.clipsToBounds = true
|
||||
|
||||
let isDualCameraEnabled = Camera.isDualCameraSupported
|
||||
let isDualCameraEnabled = Camera.isDualCameraSupported(forRoundVideo: true)
|
||||
let isFrontPosition = "".isEmpty
|
||||
|
||||
self.mainPreviewView = CameraSimplePreviewView(frame: .zero, main: true, roundVideo: true)
|
||||
|
|
|
|||
12
submodules/TelegramUI/Images.xcassets/Premium/BoostLarge.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/BoostLarge.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "boosts.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
100
submodules/TelegramUI/Images.xcassets/Premium/BoostLarge.imageset/boosts.pdf
vendored
Normal file
100
submodules/TelegramUI/Images.xcassets/Premium/BoostLarge.imageset/boosts.pdf
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
%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 28.934570 23.770996 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
19.893095 16.420483 m
|
||||
19.893103 16.420439 19.893110 16.420393 19.893118 16.420349 c
|
||||
24.322737 22.894407 l
|
||||
25.011452 23.900990 24.290668 25.267513 23.071022 25.267513 c
|
||||
16.783052 25.267513 l
|
||||
16.020958 25.267513 15.406286 25.824291 15.287010 26.530622 c
|
||||
15.286899 26.530460 l
|
||||
15.260291 26.687939 15.258309 26.852856 15.284810 27.020691 c
|
||||
17.311213 39.854584 l
|
||||
17.563419 41.451893 15.474540 42.282173 14.561391 40.947567 c
|
||||
0.267549 20.056564 l
|
||||
-0.421166 19.049982 0.299617 17.683458 1.519263 17.683458 c
|
||||
7.807235 17.683458 l
|
||||
8.739199 17.683458 9.450692 16.850807 9.305341 15.930248 c
|
||||
7.278937 3.096359 l
|
||||
7.026731 1.499050 9.115610 0.668770 10.028760 2.003372 c
|
||||
19.893095 16.420483 l
|
||||
h
|
||||
19.104115 28.767513 m
|
||||
19.790094 33.112053 l
|
||||
25.151236 40.947567 l
|
||||
26.064384 42.282173 28.153263 41.451893 27.901056 39.854580 c
|
||||
26.002724 27.831802 l
|
||||
25.198483 28.413969 24.199286 28.767513 23.071022 28.767513 c
|
||||
19.104115 28.767513 l
|
||||
h
|
||||
27.211313 20.918013 m
|
||||
28.156090 22.298841 28.298967 23.884453 27.854807 25.267483 c
|
||||
33.660732 25.267483 l
|
||||
34.880375 25.267483 35.601158 23.900959 34.912445 22.894377 c
|
||||
20.618603 2.003372 l
|
||||
19.705454 0.668770 17.616575 1.499050 17.868782 3.096359 c
|
||||
18.724150 8.513695 l
|
||||
27.211313 20.918013 l
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
1339
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 90.000000 90.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
|
||||
0000001429 00000 n
|
||||
0000001452 00000 n
|
||||
0000001625 00000 n
|
||||
0000001699 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
1758
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Premium/Perk/LastSeen.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/Perk/LastSeen.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "lastseen_30.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
169
submodules/TelegramUI/Images.xcassets/Premium/Perk/LastSeen.imageset/lastseen_30.pdf
vendored
Normal file
169
submodules/TelegramUI/Images.xcassets/Premium/Perk/LastSeen.imageset/lastseen_30.pdf
vendored
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 2 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << >>
|
||||
/BBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
>>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 5.320312 4.036133 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
15.718013 7.249816 m
|
||||
15.405374 7.990487 12.549557 9.993635 11.723054 10.108183 c
|
||||
11.210857 10.179170 10.094700 8.757028 9.820968 7.139155 c
|
||||
9.652993 6.146357 9.900538 5.153749 10.575783 4.550840 c
|
||||
12.351411 2.965429 16.030653 6.509145 15.718013 7.249816 c
|
||||
h
|
||||
20.036879 19.735321 m
|
||||
18.253841 20.338758 14.037626 18.223207 12.869061 12.033148 c
|
||||
12.869061 11.732358 15.300022 9.989953 16.974861 9.388252 c
|
||||
17.829952 9.081054 20.971378 12.265821 21.642756 15.454392 c
|
||||
22.042732 17.354000 20.948334 19.426855 20.036879 19.735321 c
|
||||
h
|
||||
5.331334 5.154034 m
|
||||
4.841030 5.573311 1.180003 6.640569 0.478038 6.303137 c
|
||||
-0.223926 5.965705 -0.489510 1.657463 2.111791 1.081186 c
|
||||
4.713092 0.504911 5.821639 4.734756 5.331334 5.154034 c
|
||||
h
|
||||
1.053483 8.698494 m
|
||||
1.543788 8.279216 5.287134 6.983948 5.989099 7.321380 c
|
||||
6.691063 7.658812 11.170075 16.921753 6.587785 17.884901 c
|
||||
5.138152 18.189598 2.305758 16.301899 1.450079 13.825531 c
|
||||
0.615815 11.411140 0.811438 8.905476 1.053483 8.698494 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
1098
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 4 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << >>
|
||||
/BBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
>>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
944
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /XObject << /X1 1 0 R >>
|
||||
/ExtGState << /E1 << /SMask << /Type /Mask
|
||||
/G 3 0 R
|
||||
/S /Alpha
|
||||
>>
|
||||
/Type /ExtGState
|
||||
>> >>
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Length 7 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
/E1 gs
|
||||
/X1 Do
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
7 0 obj
|
||||
46
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 5 0 R
|
||||
/Contents 6 0 R
|
||||
/Parent 9 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
9 0 obj
|
||||
<< /Kids [ 8 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
10 0 obj
|
||||
<< /Pages 9 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 11
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000001356 00000 n
|
||||
0000001379 00000 n
|
||||
0000002571 00000 n
|
||||
0000002593 00000 n
|
||||
0000002891 00000 n
|
||||
0000002993 00000 n
|
||||
0000003014 00000 n
|
||||
0000003187 00000 n
|
||||
0000003261 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 10 0 R
|
||||
/Size 11
|
||||
>>
|
||||
startxref
|
||||
3321
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Premium/Perk/MessagePrivacy.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/Perk/MessagePrivacy.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "messageprivacy_30.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
185
submodules/TelegramUI/Images.xcassets/Premium/Perk/MessagePrivacy.imageset/messageprivacy_30.pdf
vendored
Normal file
185
submodules/TelegramUI/Images.xcassets/Premium/Perk/MessagePrivacy.imageset/messageprivacy_30.pdf
vendored
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 2 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << >>
|
||||
/BBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
>>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 5.000000 4.484375 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
10.000000 20.135742 m
|
||||
15.522848 20.135742 20.000000 16.065603 20.000000 11.044833 c
|
||||
20.000000 6.024063 15.522848 1.953924 10.000000 1.953924 c
|
||||
9.153261 1.953924 8.331102 2.049595 7.545889 2.229696 c
|
||||
7.397357 2.263765 7.228708 2.107983 6.947171 1.847927 c
|
||||
6.606689 1.533424 6.101101 1.066412 5.266314 0.598253 c
|
||||
4.199766 0.000120 2.722059 0.052011 2.471971 0.156912 c
|
||||
2.232201 0.257484 2.416753 0.457399 2.741760 0.809465 c
|
||||
2.966608 1.053034 3.258681 1.369423 3.523984 1.776117 c
|
||||
4.172771 2.770672 3.904685 3.954702 3.613619 4.167799 c
|
||||
1.337573 5.834144 0.000000 8.181331 0.000000 11.044833 c
|
||||
0.000000 16.065603 4.477152 20.135742 10.000000 20.135742 c
|
||||
h
|
||||
6.335000 14.010747 m
|
||||
6.335000 16.034870 7.975876 17.675747 10.000000 17.675747 c
|
||||
12.024124 17.675747 13.665000 16.034870 13.665000 14.010747 c
|
||||
13.665000 12.722709 l
|
||||
14.121655 12.482201 14.492952 12.106080 14.727516 11.645723 c
|
||||
15.000000 11.110944 15.000000 10.410878 15.000000 9.010747 c
|
||||
15.000000 7.610616 15.000000 6.910550 14.727516 6.375771 c
|
||||
14.487833 5.905365 14.105381 5.522914 13.634976 5.283231 c
|
||||
13.100197 5.010747 12.400131 5.010747 11.000000 5.010747 c
|
||||
9.000000 5.010747 l
|
||||
7.599869 5.010747 6.899803 5.010747 6.365024 5.283231 c
|
||||
5.894619 5.522914 5.512167 5.905365 5.272484 6.375771 c
|
||||
5.000000 6.910550 5.000000 7.610616 5.000000 9.010747 c
|
||||
5.000000 10.410878 5.000000 11.110944 5.272484 11.645723 c
|
||||
5.507047 12.106080 5.878345 12.482201 6.335000 12.722709 c
|
||||
6.335000 14.010747 l
|
||||
h
|
||||
12.335000 14.010747 m
|
||||
12.335000 12.995256 l
|
||||
11.973238 13.010747 11.538372 13.010747 11.000000 13.010747 c
|
||||
9.000000 13.010747 l
|
||||
8.461628 13.010747 8.026762 13.010747 7.665000 12.995256 c
|
||||
7.665000 14.010747 l
|
||||
7.665000 15.300332 8.710415 16.345747 10.000000 16.345747 c
|
||||
11.289585 16.345747 12.335000 15.300332 12.335000 14.010747 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
1905
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 4 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << >>
|
||||
/BBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
>>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
944
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /XObject << /X1 1 0 R >>
|
||||
/ExtGState << /E1 << /SMask << /Type /Mask
|
||||
/G 3 0 R
|
||||
/S /Alpha
|
||||
>>
|
||||
/Type /ExtGState
|
||||
>> >>
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Length 7 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
/E1 gs
|
||||
/X1 Do
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
7 0 obj
|
||||
46
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 5 0 R
|
||||
/Contents 6 0 R
|
||||
/Parent 9 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
9 0 obj
|
||||
<< /Kids [ 8 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
10 0 obj
|
||||
<< /Pages 9 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 11
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000002163 00000 n
|
||||
0000002186 00000 n
|
||||
0000003378 00000 n
|
||||
0000003400 00000 n
|
||||
0000003698 00000 n
|
||||
0000003800 00000 n
|
||||
0000003821 00000 n
|
||||
0000003994 00000 n
|
||||
0000004068 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 10 0 R
|
||||
/Size 11
|
||||
>>
|
||||
startxref
|
||||
4128
|
||||
%%EOF
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -3381,6 +3381,8 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
|
||||
let effectiveInputText = effectivePresentationInterfaceState.interfaceState.composeInputState.inputText
|
||||
|
||||
let peerSpecificEmojiPack = (self.controller?.peerView?.cachedData as? CachedChannelData)?.emojiPack
|
||||
|
||||
var inlineStickers: [MediaId: Media] = [:]
|
||||
var firstLockedPremiumEmoji: TelegramMediaFile?
|
||||
var bubbleUpEmojiOrStickersetsById: [Int64: ItemCollectionId] = [:]
|
||||
|
|
@ -3391,7 +3393,15 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
if let packId = value.interactivelySelectedFromPackId {
|
||||
bubbleUpEmojiOrStickersetsById[file.fileId.id] = packId
|
||||
}
|
||||
if file.isPremiumEmoji && !self.chatPresentationInterfaceState.isPremium && self.chatPresentationInterfaceState.chatLocation.peerId != self.context.account.peerId {
|
||||
|
||||
var isPeerSpecific = false
|
||||
for attribute in file.attributes {
|
||||
if case let .CustomEmoji(_, _, _, packReference) = attribute, case let .id(id, _) = packReference {
|
||||
isPeerSpecific = id == peerSpecificEmojiPack?.id.id
|
||||
}
|
||||
}
|
||||
|
||||
if file.isPremiumEmoji && !self.chatPresentationInterfaceState.isPremium && self.chatPresentationInterfaceState.chatLocation.peerId != self.context.account.peerId && !isPeerSpecific {
|
||||
if firstLockedPremiumEmoji == nil {
|
||||
firstLockedPremiumEmoji = file
|
||||
}
|
||||
|
|
|
|||
1634
submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift
Normal file
1634
submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -11,6 +11,7 @@ import TelegramPresentationData
|
|||
import ChatInputPanelNode
|
||||
|
||||
final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
|
||||
private let buttonNode: HighlightTrackingButtonNode
|
||||
private let textNode: ImmediateTextNode
|
||||
private var iconView: UIImageView?
|
||||
|
||||
|
|
@ -21,9 +22,34 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
|
|||
self.textNode.maximumNumberOfLines = 2
|
||||
self.textNode.textAlignment = .center
|
||||
|
||||
self.buttonNode = HighlightTrackingButtonNode()
|
||||
self.buttonNode.isUserInteractionEnabled = false
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.textNode)
|
||||
self.addSubnode(self.buttonNode)
|
||||
|
||||
self.buttonNode.highligthedChanged = { [weak self] highlighted in
|
||||
if let self {
|
||||
if highlighted {
|
||||
self.iconView?.layer.removeAnimation(forKey: "opacity")
|
||||
self.iconView?.alpha = 0.4
|
||||
self.textNode.layer.removeAnimation(forKey: "opacity")
|
||||
self.textNode.alpha = 0.4
|
||||
} else {
|
||||
self.iconView?.alpha = 1.0
|
||||
self.iconView?.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
self.textNode.alpha = 1.0
|
||||
self.textNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
||||
}
|
||||
|
||||
@objc private func buttonPressed() {
|
||||
self.interfaceInteraction?.openBoostToUnrestrict()
|
||||
}
|
||||
|
||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||
|
|
@ -45,6 +71,8 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
|
|||
}
|
||||
|
||||
var iconImage: UIImage?
|
||||
var iconSpacing: CGFloat = 4.0
|
||||
var isUserInteractionEnabled = false
|
||||
|
||||
if case let .replyThread(message) = interfaceState.chatLocation, message.peerId == self.context?.account.peerId {
|
||||
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelStatusAuthorHidden, font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
||||
|
|
@ -63,17 +91,25 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
|
|||
} else if personal {
|
||||
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Conversation_RestrictedText, font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
||||
} else {
|
||||
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Conversation_DefaultRestrictedText, font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
||||
if "".isEmpty {
|
||||
//TODO:localize
|
||||
iconSpacing = 0.0
|
||||
iconImage = PresentationResourcesChat.chatPanelBoostIcon(interfaceState.theme)
|
||||
self.textNode.attributedText = NSAttributedString(string: "Boost this group to send messages", font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.panelControlAccentColor)
|
||||
isUserInteractionEnabled = true
|
||||
} else {
|
||||
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Conversation_DefaultRestrictedText, font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.buttonNode.isUserInteractionEnabled = isUserInteractionEnabled
|
||||
|
||||
let panelHeight = defaultHeight(metrics: metrics)
|
||||
let textSize = self.textNode.updateLayout(CGSize(width: width - leftInset - rightInset - 8.0 * 2.0, height: panelHeight))
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - rightInset - textSize.width) / 2.0), y: floor((panelHeight - textSize.height) / 2.0)), size: textSize)
|
||||
self.textNode.frame = textFrame
|
||||
var originX: CGFloat = leftInset + floor((width - leftInset - rightInset - textSize.width) / 2.0)
|
||||
|
||||
if let iconImage = iconImage {
|
||||
if let iconImage {
|
||||
let iconView: UIImageView
|
||||
if let current = self.iconView {
|
||||
iconView = current
|
||||
|
|
@ -83,12 +119,21 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
|
|||
self.view.addSubview(iconView)
|
||||
}
|
||||
iconView.image = iconImage
|
||||
iconView.frame = CGRect(origin: CGPoint(x: textFrame.minX - 4.0 - iconImage.size.width, y: textFrame.minY + UIScreenPixel + floorToScreenPixels((textFrame.height - iconImage.size.height) / 2.0)), size: iconImage.size)
|
||||
|
||||
let totalWidth = textSize.width + iconImage.size.width + iconSpacing
|
||||
iconView.frame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - rightInset - totalWidth) / 2.0), y: floor((panelHeight - textSize.height) / 2.0) + UIScreenPixel + floorToScreenPixels((textSize.height - iconImage.size.height) / 2.0)), size: iconImage.size)
|
||||
|
||||
originX += iconImage.size.width + iconSpacing
|
||||
} else if let iconView = self.iconView {
|
||||
self.iconView = nil
|
||||
iconView.removeFromSuperview()
|
||||
}
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: originX, y: floor((panelHeight - textSize.height) / 2.0)), size: textSize)
|
||||
self.textNode.frame = textFrame
|
||||
|
||||
self.buttonNode.frame = textFrame.insetBy(dx: -8.0, dy: -12.0)
|
||||
|
||||
return panelHeight
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ swift_library(
|
|||
"//submodules/Markdown",
|
||||
"//submodules/TelegramUI/Components/Stories/AvatarStoryIndicatorComponent",
|
||||
"//submodules/Components/BalancedTextComponent",
|
||||
"//submodules/Components/MultilineTextWithEntitiesComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import AvatarStoryIndicatorComponent
|
|||
import AccountContext
|
||||
import Markdown
|
||||
import BalancedTextComponent
|
||||
import MultilineTextWithEntitiesComponent
|
||||
|
||||
public enum TooltipActiveTextItem {
|
||||
case url(String, Bool)
|
||||
|
|
@ -108,6 +109,8 @@ private class DownArrowsIconNode: ASDisplayNode {
|
|||
}
|
||||
|
||||
private final class TooltipScreenNode: ViewControllerTracingNode {
|
||||
private let context: AccountContext?
|
||||
|
||||
private let text: TooltipScreen.Text
|
||||
private let textAlignment: TooltipScreen.Alignment
|
||||
private let balancedTextLayout: Bool
|
||||
|
|
@ -171,6 +174,7 @@ private final class TooltipScreenNode: ViewControllerTracingNode {
|
|||
cornerRadius: CGFloat? = nil,
|
||||
shouldDismissOnTouch: @escaping (CGPoint, CGRect) -> TooltipScreen.DismissOnTouch, requestDismiss: @escaping () -> Void, openActiveTextItem: ((TooltipActiveTextItem, TooltipActiveTextAction) -> Void)?)
|
||||
{
|
||||
self.context = context
|
||||
self.tooltipStyle = style
|
||||
self.arrowStyle = arrowStyle
|
||||
self.icon = icon
|
||||
|
|
@ -534,6 +538,8 @@ private final class TooltipScreenNode: ViewControllerTracingNode {
|
|||
}
|
||||
)
|
||||
attributedText = parseMarkdownIntoAttributedString(text, attributes: markdownAttributes)
|
||||
case let .attributedString(text):
|
||||
attributedText = text
|
||||
}
|
||||
|
||||
let highlightColor: UIColor? = UIColor.white.withAlphaComponent(0.5)
|
||||
|
|
@ -594,21 +600,44 @@ private final class TooltipScreenNode: ViewControllerTracingNode {
|
|||
}
|
||||
}
|
||||
|
||||
let textSize = self.textView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(BalancedTextComponent(
|
||||
text: .plain(attributedText),
|
||||
balanced: self.balancedTextLayout,
|
||||
horizontalAlignment: self.textAlignment == .center ? .center : .left,
|
||||
maximumNumberOfLines: 0,
|
||||
highlightColor: highlightColor,
|
||||
highlightAction: highlightAction,
|
||||
tapAction: tapAction,
|
||||
longTapAction: longTapAction
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: containerWidth - contentInset * 2.0 - animationSize.width - animationSpacing - buttonInset, height: 1000000.0)
|
||||
)
|
||||
let textSize: CGSize
|
||||
if case .attributedString = self.text, let context = self.context {
|
||||
textSize = self.textView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextWithEntitiesComponent(
|
||||
context: context,
|
||||
animationCache: context.animationCache,
|
||||
animationRenderer: context.animationRenderer,
|
||||
placeholderColor: UIColor(rgb: 0xffffff, alpha: 0.4),
|
||||
text: .plain(attributedText),
|
||||
horizontalAlignment: self.textAlignment == .center ? .center : .left,
|
||||
truncationType: .end,
|
||||
maximumNumberOfLines: 3,
|
||||
lineSpacing: 0.2,
|
||||
highlightAction: nil,
|
||||
tapAction: { _, _ in
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: containerWidth - contentInset * 2.0 - animationSize.width - animationSpacing - buttonInset, height: 1000000.0)
|
||||
)
|
||||
} else {
|
||||
textSize = self.textView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(BalancedTextComponent(
|
||||
text: .plain(attributedText),
|
||||
balanced: self.balancedTextLayout,
|
||||
horizontalAlignment: self.textAlignment == .center ? .center : .left,
|
||||
maximumNumberOfLines: 0,
|
||||
highlightColor: highlightColor,
|
||||
highlightAction: highlightAction,
|
||||
tapAction: tapAction,
|
||||
longTapAction: longTapAction
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: containerWidth - contentInset * 2.0 - animationSize.width - animationSpacing - buttonInset, height: 1000000.0)
|
||||
)
|
||||
}
|
||||
|
||||
var backgroundFrame: CGRect
|
||||
|
||||
|
|
@ -941,6 +970,7 @@ public final class TooltipScreen: ViewController {
|
|||
case plain(text: String)
|
||||
case entities(text: String, entities: [MessageTextEntity])
|
||||
case markdown(text: String)
|
||||
case attributedString(text: NSAttributedString)
|
||||
}
|
||||
|
||||
public class Action {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue